xref: /AOO41X/main/svx/source/form/formcontroller.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "fmcontrolbordermanager.hxx"
32*cdf0e10cSrcweir #include "fmcontrollayout.hxx"
33*cdf0e10cSrcweir #include "formcontroller.hxx"
34*cdf0e10cSrcweir #include "formfeaturedispatcher.hxx"
35*cdf0e10cSrcweir #include "fmdocumentclassification.hxx"
36*cdf0e10cSrcweir #include "formcontrolling.hxx"
37*cdf0e10cSrcweir #include "fmprop.hrc"
38*cdf0e10cSrcweir #include "svx/dialmgr.hxx"
39*cdf0e10cSrcweir #include "svx/fmresids.hrc"
40*cdf0e10cSrcweir #include "fmservs.hxx"
41*cdf0e10cSrcweir #include "svx/fmtools.hxx"
42*cdf0e10cSrcweir #include "fmurl.hxx"
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir /** === begin UNO includes === **/
45*cdf0e10cSrcweir #include <com/sun/star/awt/FocusChangeReason.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/awt/XCheckBox.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/awt/XComboBox.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/awt/XListBox.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/awt/XVclWindowPeer.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/container/XIdentifierReplace.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/form/TabulatorCycle.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/form/XBoundComponent.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/form/XBoundControl.hpp>
57*cdf0e10cSrcweir #include <com/sun/star/form/XGridControl.hpp>
58*cdf0e10cSrcweir #include <com/sun/star/form/XLoadable.hpp>
59*cdf0e10cSrcweir #include <com/sun/star/form/XReset.hpp>
60*cdf0e10cSrcweir #include <com/sun/star/frame/XController.hpp>
61*cdf0e10cSrcweir #include <com/sun/star/sdb/ParametersRequest.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/sdb/RowChangeAction.hpp>
63*cdf0e10cSrcweir #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
64*cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
65*cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp>
66*cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
67*cdf0e10cSrcweir #include <com/sun/star/form/runtime/FormOperations.hpp>
68*cdf0e10cSrcweir #include <com/sun/star/form/runtime/FormFeature.hpp>
69*cdf0e10cSrcweir #include <com/sun/star/container/XContainer.hpp>
70*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
71*cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatter.hpp>
72*cdf0e10cSrcweir #include <com/sun/star/sdb/SQLContext.hpp>
73*cdf0e10cSrcweir #include <com/sun/star/sdb/XColumn.hpp>
74*cdf0e10cSrcweir /** === end UNO includes === **/
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir #include <comphelper/enumhelper.hxx>
77*cdf0e10cSrcweir #include <comphelper/extract.hxx>
78*cdf0e10cSrcweir #include <comphelper/interaction.hxx>
79*cdf0e10cSrcweir #include <comphelper/namedvaluecollection.hxx>
80*cdf0e10cSrcweir #include <comphelper/propagg.hxx>
81*cdf0e10cSrcweir #include <comphelper/property.hxx>
82*cdf0e10cSrcweir #include <comphelper/sequence.hxx>
83*cdf0e10cSrcweir #include <comphelper/uno3.hxx>
84*cdf0e10cSrcweir #include <comphelper/flagguard.hxx>
85*cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx>
86*cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx>
87*cdf0e10cSrcweir #include <toolkit/controls/unocontrol.hxx>
88*cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx>
89*cdf0e10cSrcweir #include <tools/debug.hxx>
90*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
91*cdf0e10cSrcweir #include <tools/shl.hxx>
92*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
93*cdf0e10cSrcweir #include <vcl/svapp.hxx>
94*cdf0e10cSrcweir #include <vos/mutex.hxx>
95*cdf0e10cSrcweir #include <rtl/logfile.hxx>
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir #include <algorithm>
98*cdf0e10cSrcweir #include <functional>
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir using namespace ::com::sun::star;
101*cdf0e10cSrcweir using namespace ::comphelper;
102*cdf0e10cSrcweir using namespace ::connectivity;
103*cdf0e10cSrcweir using namespace ::connectivity::simple;
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir //------------------------------------------------------------------
106*cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
107*cdf0e10cSrcweir     FormController_NewInstance_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & _rxORB )
108*cdf0e10cSrcweir {
109*cdf0e10cSrcweir     return *( new ::svxform::FormController( _rxORB ) );
110*cdf0e10cSrcweir }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir namespace svxform
113*cdf0e10cSrcweir {
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir     /** === begin UNO using === **/
116*cdf0e10cSrcweir     using ::com::sun::star::sdb::XColumn;
117*cdf0e10cSrcweir     using ::com::sun::star::awt::XControl;
118*cdf0e10cSrcweir     using ::com::sun::star::awt::XTabController;
119*cdf0e10cSrcweir     using ::com::sun::star::awt::XToolkit;
120*cdf0e10cSrcweir     using ::com::sun::star::awt::XWindowPeer;
121*cdf0e10cSrcweir     using ::com::sun::star::form::XGrid;
122*cdf0e10cSrcweir     using ::com::sun::star::beans::XPropertySet;
123*cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_SET_THROW;
124*cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_QUERY_THROW;
125*cdf0e10cSrcweir     using ::com::sun::star::container::XIndexAccess;
126*cdf0e10cSrcweir     using ::com::sun::star::uno::Exception;
127*cdf0e10cSrcweir     using ::com::sun::star::uno::XInterface;
128*cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_QUERY;
129*cdf0e10cSrcweir     using ::com::sun::star::uno::Sequence;
130*cdf0e10cSrcweir     using ::com::sun::star::uno::Reference;
131*cdf0e10cSrcweir     using ::com::sun::star::beans::XPropertySetInfo;
132*cdf0e10cSrcweir     using ::com::sun::star::beans::PropertyValue;
133*cdf0e10cSrcweir     using ::com::sun::star::uno::RuntimeException;
134*cdf0e10cSrcweir     using ::com::sun::star::lang::IndexOutOfBoundsException;
135*cdf0e10cSrcweir     using ::com::sun::star::sdb::XInteractionSupplyParameters;
136*cdf0e10cSrcweir     using ::com::sun::star::awt::XTextComponent;
137*cdf0e10cSrcweir     using ::com::sun::star::awt::XTextListener;
138*cdf0e10cSrcweir     using ::com::sun::star::uno::Any;
139*cdf0e10cSrcweir     using ::com::sun::star::frame::XDispatch;
140*cdf0e10cSrcweir     using ::com::sun::star::lang::XMultiServiceFactory;
141*cdf0e10cSrcweir     using ::com::sun::star::uno::XAggregation;
142*cdf0e10cSrcweir     using ::com::sun::star::uno::Type;
143*cdf0e10cSrcweir     using ::com::sun::star::lang::IllegalArgumentException;
144*cdf0e10cSrcweir     using ::com::sun::star::sdbc::XConnection;
145*cdf0e10cSrcweir     using ::com::sun::star::sdbc::XRowSet;
146*cdf0e10cSrcweir     using ::com::sun::star::sdbc::XDatabaseMetaData;
147*cdf0e10cSrcweir     using ::com::sun::star::util::XNumberFormatsSupplier;
148*cdf0e10cSrcweir     using ::com::sun::star::util::XNumberFormatter;
149*cdf0e10cSrcweir     using ::com::sun::star::sdbcx::XColumnsSupplier;
150*cdf0e10cSrcweir     using ::com::sun::star::container::XNameAccess;
151*cdf0e10cSrcweir     using ::com::sun::star::lang::EventObject;
152*cdf0e10cSrcweir     using ::com::sun::star::beans::Property;
153*cdf0e10cSrcweir     using ::com::sun::star::container::XEnumeration;
154*cdf0e10cSrcweir     using ::com::sun::star::form::XFormComponent;
155*cdf0e10cSrcweir     using ::com::sun::star::form::runtime::XFormOperations;
156*cdf0e10cSrcweir     using ::com::sun::star::form::runtime::FilterEvent;
157*cdf0e10cSrcweir     using ::com::sun::star::form::runtime::XFilterControllerListener;
158*cdf0e10cSrcweir     using ::com::sun::star::awt::XControlContainer;
159*cdf0e10cSrcweir     using ::com::sun::star::container::XIdentifierReplace;
160*cdf0e10cSrcweir     using ::com::sun::star::lang::WrappedTargetException;
161*cdf0e10cSrcweir     using ::com::sun::star::form::XFormControllerListener;
162*cdf0e10cSrcweir     using ::com::sun::star::awt::XWindow;
163*cdf0e10cSrcweir     using ::com::sun::star::sdbc::XResultSet;
164*cdf0e10cSrcweir     using ::com::sun::star::awt::XControlModel;
165*cdf0e10cSrcweir     using ::com::sun::star::awt::XTabControllerModel;
166*cdf0e10cSrcweir     using ::com::sun::star::beans::PropertyChangeEvent;
167*cdf0e10cSrcweir     using ::com::sun::star::form::validation::XValidatableFormComponent;
168*cdf0e10cSrcweir     using ::com::sun::star::form::XLoadable;
169*cdf0e10cSrcweir     using ::com::sun::star::script::XEventAttacherManager;
170*cdf0e10cSrcweir     using ::com::sun::star::form::XBoundControl;
171*cdf0e10cSrcweir     using ::com::sun::star::beans::XPropertyChangeListener;
172*cdf0e10cSrcweir     using ::com::sun::star::awt::TextEvent;
173*cdf0e10cSrcweir     using ::com::sun::star::form::XBoundComponent;
174*cdf0e10cSrcweir     using ::com::sun::star::awt::XCheckBox;
175*cdf0e10cSrcweir     using ::com::sun::star::awt::XComboBox;
176*cdf0e10cSrcweir     using ::com::sun::star::awt::XListBox;
177*cdf0e10cSrcweir     using ::com::sun::star::awt::ItemEvent;
178*cdf0e10cSrcweir     using ::com::sun::star::util::XModifyListener;
179*cdf0e10cSrcweir     using ::com::sun::star::form::XReset;
180*cdf0e10cSrcweir     using ::com::sun::star::frame::XDispatchProviderInterception;
181*cdf0e10cSrcweir     using ::com::sun::star::form::XGridControl;
182*cdf0e10cSrcweir     using ::com::sun::star::awt::XVclWindowPeer;
183*cdf0e10cSrcweir     using ::com::sun::star::form::validation::XValidator;
184*cdf0e10cSrcweir     using ::com::sun::star::awt::FocusEvent;
185*cdf0e10cSrcweir     using ::com::sun::star::sdb::SQLContext;
186*cdf0e10cSrcweir     using ::com::sun::star::container::XChild;
187*cdf0e10cSrcweir     using ::com::sun::star::form::TabulatorCycle_RECORDS;
188*cdf0e10cSrcweir     using ::com::sun::star::container::ContainerEvent;
189*cdf0e10cSrcweir     using ::com::sun::star::lang::DisposedException;
190*cdf0e10cSrcweir     using ::com::sun::star::lang::Locale;
191*cdf0e10cSrcweir     using ::com::sun::star::beans::NamedValue;
192*cdf0e10cSrcweir     using ::com::sun::star::lang::NoSupportException;
193*cdf0e10cSrcweir     using ::com::sun::star::sdb::RowChangeEvent;
194*cdf0e10cSrcweir     using ::com::sun::star::frame::XStatusListener;
195*cdf0e10cSrcweir     using ::com::sun::star::frame::XDispatchProviderInterceptor;
196*cdf0e10cSrcweir     using ::com::sun::star::sdb::SQLErrorEvent;
197*cdf0e10cSrcweir     using ::com::sun::star::form::DatabaseParameterEvent;
198*cdf0e10cSrcweir     using ::com::sun::star::sdb::ParametersRequest;
199*cdf0e10cSrcweir     using ::com::sun::star::task::XInteractionRequest;
200*cdf0e10cSrcweir     using ::com::sun::star::util::URL;
201*cdf0e10cSrcweir     using ::com::sun::star::frame::FeatureStateEvent;
202*cdf0e10cSrcweir     using ::com::sun::star::form::runtime::XFormControllerContext;
203*cdf0e10cSrcweir     using ::com::sun::star::task::XInteractionHandler;
204*cdf0e10cSrcweir     using ::com::sun::star::form::runtime::FormOperations;
205*cdf0e10cSrcweir     using ::com::sun::star::container::XContainer;
206*cdf0e10cSrcweir     using ::com::sun::star::sdbc::SQLWarning;
207*cdf0e10cSrcweir     /** === end UNO using === **/
208*cdf0e10cSrcweir     namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
209*cdf0e10cSrcweir     namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
210*cdf0e10cSrcweir     namespace FocusChangeReason = ::com::sun::star::awt::FocusChangeReason;
211*cdf0e10cSrcweir     namespace RowChangeAction = ::com::sun::star::sdb::RowChangeAction;
212*cdf0e10cSrcweir     namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
213*cdf0e10cSrcweir     namespace DataType = ::com::sun::star::sdbc::DataType;
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir //==============================================================================
216*cdf0e10cSrcweir // ColumnInfo
217*cdf0e10cSrcweir //==============================================================================
218*cdf0e10cSrcweir struct ColumnInfo
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir     // information about the column itself
221*cdf0e10cSrcweir     Reference< XColumn >    xColumn;
222*cdf0e10cSrcweir     sal_Int32               nNullable;
223*cdf0e10cSrcweir     sal_Bool                bAutoIncrement;
224*cdf0e10cSrcweir     sal_Bool                bReadOnly;
225*cdf0e10cSrcweir     ::rtl::OUString         sName;
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir     // information about the control(s) bound to this column
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir     /// the first control which is bound to the given column, and which requires input
230*cdf0e10cSrcweir     Reference< XControl >   xFirstControlWithInputRequired;
231*cdf0e10cSrcweir     /** the first grid control which contains a column which is bound to the given database column, and requires
232*cdf0e10cSrcweir         input
233*cdf0e10cSrcweir     */
234*cdf0e10cSrcweir     Reference< XGrid >      xFirstGridWithInputRequiredColumn;
235*cdf0e10cSrcweir     /** if xFirstControlWithInputRequired is a grid control, then nRequiredGridColumn specifies the position
236*cdf0e10cSrcweir         of the grid column which is actually bound
237*cdf0e10cSrcweir     */
238*cdf0e10cSrcweir     sal_Int32               nRequiredGridColumn;
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir     ColumnInfo()
241*cdf0e10cSrcweir         :xColumn()
242*cdf0e10cSrcweir         ,nNullable( ColumnValue::NULLABLE_UNKNOWN )
243*cdf0e10cSrcweir         ,bAutoIncrement( sal_False )
244*cdf0e10cSrcweir         ,bReadOnly( sal_False )
245*cdf0e10cSrcweir         ,sName()
246*cdf0e10cSrcweir         ,xFirstControlWithInputRequired()
247*cdf0e10cSrcweir         ,xFirstGridWithInputRequiredColumn()
248*cdf0e10cSrcweir         ,nRequiredGridColumn( -1 )
249*cdf0e10cSrcweir     {
250*cdf0e10cSrcweir     }
251*cdf0e10cSrcweir };
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir //==============================================================================
254*cdf0e10cSrcweir //= ColumnInfoCache
255*cdf0e10cSrcweir //==============================================================================
256*cdf0e10cSrcweir class ColumnInfoCache
257*cdf0e10cSrcweir {
258*cdf0e10cSrcweir public:
259*cdf0e10cSrcweir     ColumnInfoCache( const Reference< XColumnsSupplier >& _rxColSupplier );
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir     size_t        getColumnCount() const { return m_aColumns.size(); }
262*cdf0e10cSrcweir     const ColumnInfo&   getColumnInfo( size_t _pos );
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir     bool    controlsInitialized() const { return m_bControlsInitialized; }
265*cdf0e10cSrcweir     void    initializeControls( const Sequence< Reference< XControl > >& _rControls );
266*cdf0e10cSrcweir     void    deinitializeControls();
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir private:
269*cdf0e10cSrcweir     typedef ::std::vector< ColumnInfo > ColumnInfos;
270*cdf0e10cSrcweir     ColumnInfos                         m_aColumns;
271*cdf0e10cSrcweir     bool                                m_bControlsInitialized;
272*cdf0e10cSrcweir };
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir //------------------------------------------------------------------------------
275*cdf0e10cSrcweir ColumnInfoCache::ColumnInfoCache( const Reference< XColumnsSupplier >& _rxColSupplier )
276*cdf0e10cSrcweir     :m_aColumns()
277*cdf0e10cSrcweir     ,m_bControlsInitialized( false )
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir     try
280*cdf0e10cSrcweir     {
281*cdf0e10cSrcweir         m_aColumns.clear();
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir         Reference< XColumnsSupplier > xSupplyCols( _rxColSupplier, UNO_SET_THROW );
284*cdf0e10cSrcweir         Reference< XIndexAccess > xColumns( xSupplyCols->getColumns(), UNO_QUERY_THROW );
285*cdf0e10cSrcweir         sal_Int32 nColumnCount = xColumns->getCount();
286*cdf0e10cSrcweir         m_aColumns.reserve( nColumnCount );
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir         Reference< XPropertySet >   xColumnProps;
289*cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < nColumnCount; ++i )
290*cdf0e10cSrcweir         {
291*cdf0e10cSrcweir             ColumnInfo aColInfo;
292*cdf0e10cSrcweir             aColInfo.xColumn.set( xColumns->getByIndex(i), UNO_QUERY_THROW );
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir             xColumnProps.set( aColInfo.xColumn, UNO_QUERY_THROW );
295*cdf0e10cSrcweir             OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_ISNULLABLE ) >>= aColInfo.nNullable );
296*cdf0e10cSrcweir             OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_AUTOINCREMENT ) >>= aColInfo.bAutoIncrement );
297*cdf0e10cSrcweir             OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_NAME ) >>= aColInfo.sName );
298*cdf0e10cSrcweir             OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_ISREADONLY ) >>= aColInfo.bReadOnly );
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir             m_aColumns.push_back( aColInfo );
301*cdf0e10cSrcweir         }
302*cdf0e10cSrcweir     }
303*cdf0e10cSrcweir     catch( const Exception& )
304*cdf0e10cSrcweir     {
305*cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
306*cdf0e10cSrcweir     }
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir //------------------------------------------------------------------------------
310*cdf0e10cSrcweir namespace
311*cdf0e10cSrcweir {
312*cdf0e10cSrcweir     bool lcl_isBoundTo( const Reference< XPropertySet >& _rxControlModel, const Reference< XInterface >& _rxNormDBField )
313*cdf0e10cSrcweir     {
314*cdf0e10cSrcweir         Reference< XInterface > xNormBoundField( _rxControlModel->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY );
315*cdf0e10cSrcweir         return ( xNormBoundField.get() == _rxNormDBField.get() );
316*cdf0e10cSrcweir     }
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir     bool lcl_isInputRequired( const Reference< XPropertySet >& _rxControlModel )
319*cdf0e10cSrcweir     {
320*cdf0e10cSrcweir         sal_Bool bInputRequired = sal_True;
321*cdf0e10cSrcweir         OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_INPUT_REQUIRED ) >>= bInputRequired );
322*cdf0e10cSrcweir         return ( bInputRequired != sal_False );
323*cdf0e10cSrcweir     }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     void lcl_resetColumnControlInfo( ColumnInfo& _rColInfo )
326*cdf0e10cSrcweir     {
327*cdf0e10cSrcweir         _rColInfo.xFirstControlWithInputRequired.clear();
328*cdf0e10cSrcweir         _rColInfo.xFirstGridWithInputRequiredColumn.clear();
329*cdf0e10cSrcweir         _rColInfo.nRequiredGridColumn = -1;
330*cdf0e10cSrcweir     }
331*cdf0e10cSrcweir }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir //------------------------------------------------------------------------------
334*cdf0e10cSrcweir void ColumnInfoCache::deinitializeControls()
335*cdf0e10cSrcweir {
336*cdf0e10cSrcweir     for (   ColumnInfos::iterator col = m_aColumns.begin();
337*cdf0e10cSrcweir             col != m_aColumns.end();
338*cdf0e10cSrcweir             ++col
339*cdf0e10cSrcweir         )
340*cdf0e10cSrcweir     {
341*cdf0e10cSrcweir         lcl_resetColumnControlInfo( *col );
342*cdf0e10cSrcweir     }
343*cdf0e10cSrcweir }
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir //------------------------------------------------------------------------------
346*cdf0e10cSrcweir void ColumnInfoCache::initializeControls( const Sequence< Reference< XControl > >& _rControls )
347*cdf0e10cSrcweir {
348*cdf0e10cSrcweir     try
349*cdf0e10cSrcweir     {
350*cdf0e10cSrcweir         // for every of our known columns, find the controls which are bound to this column
351*cdf0e10cSrcweir         for (   ColumnInfos::iterator col = m_aColumns.begin();
352*cdf0e10cSrcweir                 col != m_aColumns.end();
353*cdf0e10cSrcweir                 ++col
354*cdf0e10cSrcweir             )
355*cdf0e10cSrcweir         {
356*cdf0e10cSrcweir             OSL_ENSURE( !col->xFirstControlWithInputRequired.is() && !col->xFirstGridWithInputRequiredColumn.is()
357*cdf0e10cSrcweir                 && ( col->nRequiredGridColumn == -1 ), "ColumnInfoCache::initializeControls: called me twice?" );
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir             lcl_resetColumnControlInfo( *col );
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir             Reference< XInterface > xNormColumn( col->xColumn, UNO_QUERY_THROW );
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir             const Reference< XControl >* pControl( _rControls.getConstArray() );
364*cdf0e10cSrcweir             const Reference< XControl >* pControlEnd( pControl + _rControls.getLength() );
365*cdf0e10cSrcweir             for ( ; pControl != pControlEnd; ++pControl )
366*cdf0e10cSrcweir             {
367*cdf0e10cSrcweir                 if ( !pControl->is() )
368*cdf0e10cSrcweir                     continue;
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir                 Reference< XPropertySet > xModel( (*pControl)->getModel(), UNO_QUERY_THROW );
371*cdf0e10cSrcweir                 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir                 // special handling for grid controls
374*cdf0e10cSrcweir                 Reference< XGrid > xGrid( *pControl, UNO_QUERY );
375*cdf0e10cSrcweir                 if ( xGrid.is() )
376*cdf0e10cSrcweir                 {
377*cdf0e10cSrcweir                     Reference< XIndexAccess > xGridColAccess( xModel, UNO_QUERY_THROW );
378*cdf0e10cSrcweir                     sal_Int32 gridColCount = xGridColAccess->getCount();
379*cdf0e10cSrcweir                     sal_Int32 gridCol = 0;
380*cdf0e10cSrcweir                     for ( gridCol = 0; gridCol < gridColCount; ++gridCol )
381*cdf0e10cSrcweir                     {
382*cdf0e10cSrcweir                         Reference< XPropertySet > xGridColumnModel( xGridColAccess->getByIndex( gridCol ), UNO_QUERY_THROW );
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir                         if  (   !lcl_isBoundTo( xGridColumnModel, xNormColumn )
385*cdf0e10cSrcweir                             ||  !lcl_isInputRequired( xGridColumnModel )
386*cdf0e10cSrcweir                             )
387*cdf0e10cSrcweir                             continue;   // with next grid column
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir                         break;
390*cdf0e10cSrcweir                     }
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir                     if ( gridCol < gridColCount )
393*cdf0e10cSrcweir                     {
394*cdf0e10cSrcweir                         // found a grid column which is bound to the given
395*cdf0e10cSrcweir                         col->xFirstGridWithInputRequiredColumn = xGrid;
396*cdf0e10cSrcweir                         col->nRequiredGridColumn = gridCol;
397*cdf0e10cSrcweir                         break;
398*cdf0e10cSrcweir                     }
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir                     continue;   // with next control
401*cdf0e10cSrcweir                 }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir                 if  (   !xModelPSI->hasPropertyByName( FM_PROP_BOUNDFIELD )
404*cdf0e10cSrcweir                     ||  !lcl_isBoundTo( xModel, xNormColumn )
405*cdf0e10cSrcweir                     ||  !lcl_isInputRequired( xModel )
406*cdf0e10cSrcweir                     )
407*cdf0e10cSrcweir                     continue;   // with next control
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir                 break;
410*cdf0e10cSrcweir             }
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir             if ( pControl == pControlEnd )
413*cdf0e10cSrcweir                 // did not find a control which is bound to this particular column, and for which the input is required
414*cdf0e10cSrcweir                 continue;   // with next DB column
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir             col->xFirstControlWithInputRequired = *pControl;
417*cdf0e10cSrcweir         }
418*cdf0e10cSrcweir     }
419*cdf0e10cSrcweir     catch( const Exception& )
420*cdf0e10cSrcweir     {
421*cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
422*cdf0e10cSrcweir     }
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir     m_bControlsInitialized = true;
425*cdf0e10cSrcweir }
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir //------------------------------------------------------------------------------
428*cdf0e10cSrcweir const ColumnInfo& ColumnInfoCache::getColumnInfo( size_t _pos )
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir     if ( _pos >= m_aColumns.size() )
431*cdf0e10cSrcweir         throw IndexOutOfBoundsException();
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir     return m_aColumns[ _pos ];
434*cdf0e10cSrcweir }
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir //==================================================================
437*cdf0e10cSrcweir // OParameterContinuation
438*cdf0e10cSrcweir //==================================================================
439*cdf0e10cSrcweir class OParameterContinuation : public OInteraction< XInteractionSupplyParameters >
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir     Sequence< PropertyValue >       m_aValues;
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir public:
444*cdf0e10cSrcweir     OParameterContinuation() { }
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir     Sequence< PropertyValue >   getValues() const { return m_aValues; }
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir // XInteractionSupplyParameters
449*cdf0e10cSrcweir     virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException);
450*cdf0e10cSrcweir };
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir //------------------------------------------------------------------
453*cdf0e10cSrcweir void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException)
454*cdf0e10cSrcweir {
455*cdf0e10cSrcweir     m_aValues = _rValues;
456*cdf0e10cSrcweir }
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir //==================================================================
459*cdf0e10cSrcweir // FmXAutoControl
460*cdf0e10cSrcweir //==================================================================
461*cdf0e10cSrcweir struct FmFieldInfo
462*cdf0e10cSrcweir {
463*cdf0e10cSrcweir     rtl::OUString       aFieldName;
464*cdf0e10cSrcweir     Reference< XPropertySet >   xField;
465*cdf0e10cSrcweir     Reference< XTextComponent >  xText;
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir     FmFieldInfo(const Reference< XPropertySet >& _xField, const Reference< XTextComponent >& _xText)
468*cdf0e10cSrcweir         :xField(_xField)
469*cdf0e10cSrcweir         ,xText(_xText)
470*cdf0e10cSrcweir     {xField->getPropertyValue(FM_PROP_NAME) >>= aFieldName;}
471*cdf0e10cSrcweir };
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir //==================================================================
474*cdf0e10cSrcweir // FmXAutoControl
475*cdf0e10cSrcweir //==================================================================
476*cdf0e10cSrcweir class FmXAutoControl: public UnoControl
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir {
479*cdf0e10cSrcweir     friend Reference< XInterface > SAL_CALL FmXAutoControl_NewInstance_Impl();
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir public:
482*cdf0e10cSrcweir     FmXAutoControl( const ::comphelper::ComponentContext& i_context )
483*cdf0e10cSrcweir         :UnoControl( i_context.getLegacyServiceFactory() )
484*cdf0e10cSrcweir     {
485*cdf0e10cSrcweir     }
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir     virtual ::rtl::OUString GetComponentServiceName() {return ::rtl::OUString::createFromAscii("Edit");}
488*cdf0e10cSrcweir     virtual void SAL_CALL createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer >  & rParentPeer ) throw( RuntimeException );
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir protected:
491*cdf0e10cSrcweir     virtual void ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal );
492*cdf0e10cSrcweir };
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir //------------------------------------------------------------------------------
495*cdf0e10cSrcweir void FmXAutoControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer >  & rParentPeer ) throw( RuntimeException )
496*cdf0e10cSrcweir {
497*cdf0e10cSrcweir     UnoControl::createPeer( rxToolkit, rParentPeer );
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir     Reference< XTextComponent >  xText(getPeer() , UNO_QUERY);
500*cdf0e10cSrcweir     if (xText.is())
501*cdf0e10cSrcweir     {
502*cdf0e10cSrcweir         xText->setText(::rtl::OUString(String(SVX_RES(RID_STR_AUTOFIELD))));
503*cdf0e10cSrcweir         xText->setEditable(sal_False);
504*cdf0e10cSrcweir     }
505*cdf0e10cSrcweir }
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir //------------------------------------------------------------------------------
508*cdf0e10cSrcweir void FmXAutoControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal )
509*cdf0e10cSrcweir {
510*cdf0e10cSrcweir     // these properties are ignored
511*cdf0e10cSrcweir     if (rPropName == FM_PROP_TEXT)
512*cdf0e10cSrcweir         return;
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir     UnoControl::ImplSetPeerProperty( rPropName, rVal );
515*cdf0e10cSrcweir }
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir //------------------------------------------------------------------------------
518*cdf0e10cSrcweir IMPL_LINK( FormController, OnActivateTabOrder, void*, /*EMPTYTAG*/ )
519*cdf0e10cSrcweir {
520*cdf0e10cSrcweir     activateTabOrder();
521*cdf0e10cSrcweir     return 1;
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir //------------------------------------------------------------------------------
525*cdf0e10cSrcweir struct UpdateAllListeners : public ::std::unary_function< Reference< XDispatch >, bool >
526*cdf0e10cSrcweir {
527*cdf0e10cSrcweir     bool operator()( const Reference< XDispatch >& _rxDispatcher ) const
528*cdf0e10cSrcweir     {
529*cdf0e10cSrcweir         static_cast< ::svx::OSingleFeatureDispatcher* >( _rxDispatcher.get() )->updateAllListeners();
530*cdf0e10cSrcweir         // the return is a dummy only so we can use this struct in a std::compose1 call
531*cdf0e10cSrcweir         return true;
532*cdf0e10cSrcweir     }
533*cdf0e10cSrcweir };
534*cdf0e10cSrcweir //..............................................................................
535*cdf0e10cSrcweir IMPL_LINK( FormController, OnInvalidateFeatures, void*, /*_pNotInterestedInThisParam*/ )
536*cdf0e10cSrcweir {
537*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
538*cdf0e10cSrcweir     for ( ::std::set< sal_Int16 >::const_iterator aLoop = m_aInvalidFeatures.begin();
539*cdf0e10cSrcweir           aLoop != m_aInvalidFeatures.end();
540*cdf0e10cSrcweir           ++aLoop
541*cdf0e10cSrcweir         )
542*cdf0e10cSrcweir     {
543*cdf0e10cSrcweir         DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( *aLoop );
544*cdf0e10cSrcweir         if ( aDispatcherPos != m_aFeatureDispatchers.end() )
545*cdf0e10cSrcweir         {
546*cdf0e10cSrcweir             // TODO: for the real and actual listener notifications, we should release
547*cdf0e10cSrcweir             // our mutex
548*cdf0e10cSrcweir             UpdateAllListeners( )( aDispatcherPos->second );
549*cdf0e10cSrcweir         }
550*cdf0e10cSrcweir     }
551*cdf0e10cSrcweir     return 1;
552*cdf0e10cSrcweir }
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir /*************************************************************************/
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir DBG_NAME( FormController )
557*cdf0e10cSrcweir //------------------------------------------------------------------
558*cdf0e10cSrcweir FormController::FormController(const Reference< XMultiServiceFactory > & _rxORB )
559*cdf0e10cSrcweir 				  :FormController_BASE( m_aMutex )
560*cdf0e10cSrcweir 				  ,OPropertySetHelper( FormController_BASE::rBHelper )
561*cdf0e10cSrcweir                   ,OSQLParserClient( _rxORB )
562*cdf0e10cSrcweir 				  ,m_aContext( _rxORB )
563*cdf0e10cSrcweir 				  ,m_aActivateListeners(m_aMutex)
564*cdf0e10cSrcweir 				  ,m_aModifyListeners(m_aMutex)
565*cdf0e10cSrcweir 				  ,m_aErrorListeners(m_aMutex)
566*cdf0e10cSrcweir 				  ,m_aDeleteListeners(m_aMutex)
567*cdf0e10cSrcweir 				  ,m_aRowSetApproveListeners(m_aMutex)
568*cdf0e10cSrcweir 				  ,m_aParameterListeners(m_aMutex)
569*cdf0e10cSrcweir                   ,m_aFilterListeners(m_aMutex)
570*cdf0e10cSrcweir                   ,m_pControlBorderManager( new ::svxform::ControlBorderManager )
571*cdf0e10cSrcweir                   ,m_xFormOperations()
572*cdf0e10cSrcweir 				  ,m_aMode( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ) )
573*cdf0e10cSrcweir 				  ,m_aLoadEvent( LINK( this, FormController, OnLoad ) )
574*cdf0e10cSrcweir 				  ,m_aToggleEvent( LINK( this, FormController, OnToggleAutoFields ) )
575*cdf0e10cSrcweir                   ,m_aActivationEvent( LINK( this, FormController, OnActivated ) )
576*cdf0e10cSrcweir                   ,m_aDeactivationEvent( LINK( this, FormController, OnDeactivated ) )
577*cdf0e10cSrcweir 				  ,m_nCurrentFilterPosition(-1)
578*cdf0e10cSrcweir 				  ,m_bCurrentRecordModified(sal_False)
579*cdf0e10cSrcweir 				  ,m_bCurrentRecordNew(sal_False)
580*cdf0e10cSrcweir 				  ,m_bLocked(sal_False)
581*cdf0e10cSrcweir 				  ,m_bDBConnection(sal_False)
582*cdf0e10cSrcweir 				  ,m_bCycle(sal_False)
583*cdf0e10cSrcweir 				  ,m_bCanInsert(sal_False)
584*cdf0e10cSrcweir 				  ,m_bCanUpdate(sal_False)
585*cdf0e10cSrcweir 				  ,m_bCommitLock(sal_False)
586*cdf0e10cSrcweir 				  ,m_bModified(sal_False)
587*cdf0e10cSrcweir                   ,m_bControlsSorted(sal_False)
588*cdf0e10cSrcweir                   ,m_bFiltering(sal_False)
589*cdf0e10cSrcweir 				  ,m_bAttachEvents(sal_True)
590*cdf0e10cSrcweir 				  ,m_bDetachEvents(sal_True)
591*cdf0e10cSrcweir                   ,m_bAttemptedHandlerCreation( false )
592*cdf0e10cSrcweir                   ,m_bSuspendFilterTextListening( false )
593*cdf0e10cSrcweir {
594*cdf0e10cSrcweir 	DBG_CTOR( FormController, NULL );
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir 	::comphelper::increment(m_refCount);
597*cdf0e10cSrcweir 	{
598*cdf0e10cSrcweir         {
599*cdf0e10cSrcweir 		    m_xAggregate = Reference< XAggregation >(
600*cdf0e10cSrcweir                 m_aContext.createComponent( "com.sun.star.awt.TabController" ),
601*cdf0e10cSrcweir                 UNO_QUERY
602*cdf0e10cSrcweir             );
603*cdf0e10cSrcweir 		    DBG_ASSERT( m_xAggregate.is(), "FormController::FormController : could not create my aggregate !" );
604*cdf0e10cSrcweir 		    m_xTabController = Reference< XTabController >( m_xAggregate, UNO_QUERY );
605*cdf0e10cSrcweir         }
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir     	if ( m_xAggregate.is() )
608*cdf0e10cSrcweir 	        m_xAggregate->setDelegator( *this );
609*cdf0e10cSrcweir     }
610*cdf0e10cSrcweir     ::comphelper::decrement(m_refCount);
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir     m_aTabActivationTimer.SetTimeout( 500 );
613*cdf0e10cSrcweir     m_aTabActivationTimer.SetTimeoutHdl( LINK( this, FormController, OnActivateTabOrder ) );
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir     m_aFeatureInvalidationTimer.SetTimeout( 200 );
616*cdf0e10cSrcweir     m_aFeatureInvalidationTimer.SetTimeoutHdl( LINK( this, FormController, OnInvalidateFeatures ) );
617*cdf0e10cSrcweir }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir //------------------------------------------------------------------
620*cdf0e10cSrcweir FormController::~FormController()
621*cdf0e10cSrcweir {
622*cdf0e10cSrcweir     {
623*cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( m_aMutex );
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir         m_aLoadEvent.CancelPendingCall();
626*cdf0e10cSrcweir         m_aToggleEvent.CancelPendingCall();
627*cdf0e10cSrcweir         m_aActivationEvent.CancelPendingCall();
628*cdf0e10cSrcweir         m_aDeactivationEvent.CancelPendingCall();
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir         if ( m_aTabActivationTimer.IsActive() )
631*cdf0e10cSrcweir             m_aTabActivationTimer.Stop();
632*cdf0e10cSrcweir     }
633*cdf0e10cSrcweir 
634*cdf0e10cSrcweir     if ( m_aFeatureInvalidationTimer.IsActive() )
635*cdf0e10cSrcweir         m_aFeatureInvalidationTimer.Stop();
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir     disposeAllFeaturesAndDispatchers();
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir     if ( m_xFormOperations.is() )
640*cdf0e10cSrcweir         m_xFormOperations->dispose();
641*cdf0e10cSrcweir     m_xFormOperations.clear();
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir     // Freigeben der Aggregation
644*cdf0e10cSrcweir     if ( m_xAggregate.is() )
645*cdf0e10cSrcweir     {
646*cdf0e10cSrcweir         m_xAggregate->setDelegator( NULL );
647*cdf0e10cSrcweir         m_xAggregate.clear();
648*cdf0e10cSrcweir     }
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir     DELETEZ( m_pControlBorderManager );
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir 	DBG_DTOR( FormController, NULL );
653*cdf0e10cSrcweir }
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir // -----------------------------------------------------------------------------
656*cdf0e10cSrcweir void SAL_CALL FormController::acquire() throw ()
657*cdf0e10cSrcweir {
658*cdf0e10cSrcweir     FormController_BASE::acquire();
659*cdf0e10cSrcweir }
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir // -----------------------------------------------------------------------------
662*cdf0e10cSrcweir void SAL_CALL FormController::release() throw ()
663*cdf0e10cSrcweir {
664*cdf0e10cSrcweir     FormController_BASE::release();
665*cdf0e10cSrcweir }
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir //------------------------------------------------------------------
668*cdf0e10cSrcweir Any SAL_CALL FormController::queryInterface( const Type& _rType ) throw(RuntimeException)
669*cdf0e10cSrcweir {
670*cdf0e10cSrcweir     Any aRet = FormController_BASE::queryInterface( _rType );
671*cdf0e10cSrcweir     if ( !aRet.hasValue() )
672*cdf0e10cSrcweir         aRet = OPropertySetHelper::queryInterface( _rType );
673*cdf0e10cSrcweir     if ( !aRet.hasValue() )
674*cdf0e10cSrcweir         aRet = m_xAggregate->queryAggregation( _rType );
675*cdf0e10cSrcweir     return aRet;
676*cdf0e10cSrcweir }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir //------------------------------------------------------------------------------
679*cdf0e10cSrcweir Sequence< sal_Int8 > SAL_CALL FormController::getImplementationId() throw( RuntimeException )
680*cdf0e10cSrcweir {
681*cdf0e10cSrcweir     static ::cppu::OImplementationId* pId = NULL;
682*cdf0e10cSrcweir 	if  ( !pId )
683*cdf0e10cSrcweir 	{
684*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
685*cdf0e10cSrcweir 		if ( !pId )
686*cdf0e10cSrcweir 		{
687*cdf0e10cSrcweir 			static ::cppu::OImplementationId aId;
688*cdf0e10cSrcweir 			pId = &aId;
689*cdf0e10cSrcweir 		}
690*cdf0e10cSrcweir 	}
691*cdf0e10cSrcweir 	return pId->getImplementationId();
692*cdf0e10cSrcweir }
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir //------------------------------------------------------------------------------
695*cdf0e10cSrcweir Sequence< Type > SAL_CALL FormController::getTypes(  ) throw(RuntimeException)
696*cdf0e10cSrcweir {
697*cdf0e10cSrcweir     return comphelper::concatSequences(
698*cdf0e10cSrcweir         FormController_BASE::getTypes(),
699*cdf0e10cSrcweir         ::cppu::OPropertySetHelper::getTypes()
700*cdf0e10cSrcweir     );
701*cdf0e10cSrcweir }
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir // XServiceInfo
704*cdf0e10cSrcweir //------------------------------------------------------------------------------
705*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::supportsService(const ::rtl::OUString& ServiceName) throw( RuntimeException )
706*cdf0e10cSrcweir {
707*cdf0e10cSrcweir     Sequence< ::rtl::OUString> aSNL(getSupportedServiceNames());
708*cdf0e10cSrcweir     const ::rtl::OUString * pArray = aSNL.getConstArray();
709*cdf0e10cSrcweir     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
710*cdf0e10cSrcweir         if( pArray[i] == ServiceName )
711*cdf0e10cSrcweir             return sal_True;
712*cdf0e10cSrcweir     return sal_False;
713*cdf0e10cSrcweir }
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir //------------------------------------------------------------------------------
716*cdf0e10cSrcweir ::rtl::OUString SAL_CALL FormController::getImplementationName() throw( RuntimeException )
717*cdf0e10cSrcweir {
718*cdf0e10cSrcweir     return ::rtl::OUString::createFromAscii( "org.openoffice.comp.svx.FormController" );
719*cdf0e10cSrcweir }
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir //------------------------------------------------------------------------------
722*cdf0e10cSrcweir Sequence< ::rtl::OUString> SAL_CALL FormController::getSupportedServiceNames(void) throw( RuntimeException )
723*cdf0e10cSrcweir {
724*cdf0e10cSrcweir     // service names which are supported only, but cannot be used to created an
725*cdf0e10cSrcweir     // instance at a service factory
726*cdf0e10cSrcweir     Sequence< ::rtl::OUString > aNonCreatableServiceNames( 1 );
727*cdf0e10cSrcweir     aNonCreatableServiceNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.FormControllerDispatcher" ) );
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir     // services which can be used to created an instance at a service factory
730*cdf0e10cSrcweir     Sequence< ::rtl::OUString > aCreatableServiceNames( getSupportedServiceNames_Static() );
731*cdf0e10cSrcweir     return ::comphelper::concatSequences( aCreatableServiceNames, aNonCreatableServiceNames );
732*cdf0e10cSrcweir }
733*cdf0e10cSrcweir 
734*cdf0e10cSrcweir //------------------------------------------------------------------------------
735*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::approveReset(const EventObject& /*rEvent*/) throw( RuntimeException )
736*cdf0e10cSrcweir {
737*cdf0e10cSrcweir     return sal_True;
738*cdf0e10cSrcweir }
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir //------------------------------------------------------------------------------
741*cdf0e10cSrcweir void SAL_CALL FormController::resetted(const EventObject& rEvent) throw( RuntimeException )
742*cdf0e10cSrcweir {
743*cdf0e10cSrcweir     ::osl::MutexGuard aGuard(m_aMutex);
744*cdf0e10cSrcweir     if (getCurrentControl().is() &&  (getCurrentControl()->getModel() == rEvent.Source))
745*cdf0e10cSrcweir         m_bModified = sal_False;
746*cdf0e10cSrcweir }
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir //------------------------------------------------------------------------------
749*cdf0e10cSrcweir Sequence< ::rtl::OUString> FormController::getSupportedServiceNames_Static(void)
750*cdf0e10cSrcweir {
751*cdf0e10cSrcweir     static Sequence< ::rtl::OUString> aServices;
752*cdf0e10cSrcweir     if (!aServices.getLength())
753*cdf0e10cSrcweir     {
754*cdf0e10cSrcweir         aServices.realloc(2);
755*cdf0e10cSrcweir         aServices.getArray()[0] = FM_FORM_CONTROLLER;
756*cdf0e10cSrcweir         aServices.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.awt.control.TabController");
757*cdf0e10cSrcweir     }
758*cdf0e10cSrcweir     return aServices;
759*cdf0e10cSrcweir }
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir // -----------------------------------------------------------------------------
762*cdf0e10cSrcweir namespace
763*cdf0e10cSrcweir {
764*cdf0e10cSrcweir     struct ResetComponentText : public ::std::unary_function< Reference< XTextComponent >, void >
765*cdf0e10cSrcweir     {
766*cdf0e10cSrcweir         void operator()( const Reference< XTextComponent >& _rxText )
767*cdf0e10cSrcweir         {
768*cdf0e10cSrcweir             _rxText->setText( ::rtl::OUString() );
769*cdf0e10cSrcweir         }
770*cdf0e10cSrcweir     };
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir     struct RemoveComponentTextListener : public ::std::unary_function< Reference< XTextComponent >, void >
773*cdf0e10cSrcweir     {
774*cdf0e10cSrcweir         RemoveComponentTextListener( const Reference< XTextListener >& _rxListener )
775*cdf0e10cSrcweir             :m_xListener( _rxListener )
776*cdf0e10cSrcweir         {
777*cdf0e10cSrcweir         }
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir         void operator()( const Reference< XTextComponent >& _rxText )
780*cdf0e10cSrcweir         {
781*cdf0e10cSrcweir             _rxText->removeTextListener( m_xListener );
782*cdf0e10cSrcweir         }
783*cdf0e10cSrcweir 
784*cdf0e10cSrcweir     private:
785*cdf0e10cSrcweir         Reference< XTextListener >  m_xListener;
786*cdf0e10cSrcweir     };
787*cdf0e10cSrcweir }
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir // -----------------------------------------------------------------------------
790*cdf0e10cSrcweir void FormController::impl_setTextOnAllFilter_throw()
791*cdf0e10cSrcweir {
792*cdf0e10cSrcweir     m_bSuspendFilterTextListening = true;
793*cdf0e10cSrcweir     ::comphelper::FlagGuard aResetFlag( m_bSuspendFilterTextListening );
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir     // reset the text for all controls
796*cdf0e10cSrcweir     ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), ResetComponentText() );
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir     if ( m_aFilterRows.empty() )
799*cdf0e10cSrcweir         // nothing to do anymore
800*cdf0e10cSrcweir         return;
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir     if ( m_nCurrentFilterPosition < 0 )
803*cdf0e10cSrcweir         return;
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir     // set the text for all filters
806*cdf0e10cSrcweir     OSL_ENSURE( m_aFilterRows.size() > (size_t)m_nCurrentFilterPosition,
807*cdf0e10cSrcweir         "FormController::impl_setTextOnAllFilter_throw: m_nCurrentFilterPosition too big" );
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 	if ( (size_t)m_nCurrentFilterPosition < m_aFilterRows.size() )
810*cdf0e10cSrcweir 	{
811*cdf0e10cSrcweir         FmFilterRow& rRow = m_aFilterRows[ m_nCurrentFilterPosition ];
812*cdf0e10cSrcweir         for (   FmFilterRow::const_iterator iter2 = rRow.begin();
813*cdf0e10cSrcweir                 iter2 != rRow.end();
814*cdf0e10cSrcweir                 ++iter2
815*cdf0e10cSrcweir             )
816*cdf0e10cSrcweir         {
817*cdf0e10cSrcweir             iter2->first->setText( iter2->second );
818*cdf0e10cSrcweir         }
819*cdf0e10cSrcweir     }
820*cdf0e10cSrcweir }
821*cdf0e10cSrcweir // OPropertySetHelper
822*cdf0e10cSrcweir //------------------------------------------------------------------------------
823*cdf0e10cSrcweir sal_Bool FormController::convertFastPropertyValue( Any & /*rConvertedValue*/, Any & /*rOldValue*/,
824*cdf0e10cSrcweir                                             sal_Int32 /*nHandle*/, const Any& /*rValue*/ )
825*cdf0e10cSrcweir                 throw( IllegalArgumentException )
826*cdf0e10cSrcweir {
827*cdf0e10cSrcweir     return sal_False;
828*cdf0e10cSrcweir }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir //------------------------------------------------------------------------------
831*cdf0e10cSrcweir void FormController::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/, const Any& /*rValue*/ )
832*cdf0e10cSrcweir                          throw( Exception )
833*cdf0e10cSrcweir {
834*cdf0e10cSrcweir }
835*cdf0e10cSrcweir 
836*cdf0e10cSrcweir //------------------------------------------------------------------------------
837*cdf0e10cSrcweir void FormController::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
838*cdf0e10cSrcweir {
839*cdf0e10cSrcweir     switch (nHandle)
840*cdf0e10cSrcweir     {
841*cdf0e10cSrcweir         case FM_ATTR_FILTER:
842*cdf0e10cSrcweir         {
843*cdf0e10cSrcweir             ::rtl::OUStringBuffer aFilter;
844*cdf0e10cSrcweir 			OStaticDataAccessTools aStaticTools;
845*cdf0e10cSrcweir             Reference<XConnection> xConnection(aStaticTools.getRowSetConnection(Reference< XRowSet>(m_xModelAsIndex, UNO_QUERY)));
846*cdf0e10cSrcweir             if (xConnection.is())
847*cdf0e10cSrcweir             {
848*cdf0e10cSrcweir                 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
849*cdf0e10cSrcweir                 Reference< XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats( xConnection, sal_True ) );
850*cdf0e10cSrcweir                 Reference< XNumberFormatter> xFormatter( m_aContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW );
851*cdf0e10cSrcweir                 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir                 Reference< XColumnsSupplier> xSupplyCols(m_xModelAsIndex, UNO_QUERY);
854*cdf0e10cSrcweir                 Reference< XNameAccess> xFields(xSupplyCols->getColumns(), UNO_QUERY);
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir                 ::rtl::OUString aQuote( xMetaData->getIdentifierQuoteString() );
857*cdf0e10cSrcweir 
858*cdf0e10cSrcweir                 // now add the filter rows
859*cdf0e10cSrcweir                 try
860*cdf0e10cSrcweir                 {
861*cdf0e10cSrcweir                     for ( FmFilterRows::const_iterator row = m_aFilterRows.begin(); row != m_aFilterRows.end(); ++row )
862*cdf0e10cSrcweir                     {
863*cdf0e10cSrcweir                         const FmFilterRow& rRow = *row;
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir                         if ( rRow.empty() )
866*cdf0e10cSrcweir                             continue;
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir                         ::rtl::OUStringBuffer aRowFilter;
869*cdf0e10cSrcweir                         for ( FmFilterRow::const_iterator condition = rRow.begin(); condition != rRow.end(); ++condition )
870*cdf0e10cSrcweir                         {
871*cdf0e10cSrcweir                             // get the field of the controls map
872*cdf0e10cSrcweir                             Reference< XControl > xControl( condition->first, UNO_QUERY_THROW );
873*cdf0e10cSrcweir                             Reference< XPropertySet > xModelProps( xControl->getModel(), UNO_QUERY_THROW );
874*cdf0e10cSrcweir                             Reference< XPropertySet > xField( xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY_THROW );
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir                             ::rtl::OUString sFilterValue( condition->second );
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir                             ::rtl::OUString sErrorMsg, sCriteria;
879*cdf0e10cSrcweir                             const ::rtl::Reference< ISQLParseNode > xParseNode =
880*cdf0e10cSrcweir                                 predicateTree( sErrorMsg, sFilterValue, xFormatter, xField );
881*cdf0e10cSrcweir                             OSL_ENSURE( xParseNode.is(), "FormController::getFastPropertyValue: could not parse the field value predicate!" );
882*cdf0e10cSrcweir                             if ( xParseNode.is() )
883*cdf0e10cSrcweir                             {
884*cdf0e10cSrcweir                                 // don't use a parse context here, we need it unlocalized
885*cdf0e10cSrcweir                                 xParseNode->parseNodeToStr( sCriteria, xConnection, NULL );
886*cdf0e10cSrcweir                                 if ( condition != rRow.begin() )
887*cdf0e10cSrcweir                                     aRowFilter.appendAscii( " AND " );
888*cdf0e10cSrcweir                                 aRowFilter.append( sCriteria );
889*cdf0e10cSrcweir                             }
890*cdf0e10cSrcweir                         }
891*cdf0e10cSrcweir                         if ( aRowFilter.getLength() > 0 )
892*cdf0e10cSrcweir                         {
893*cdf0e10cSrcweir                             if ( aFilter.getLength() )
894*cdf0e10cSrcweir                                 aFilter.appendAscii( " OR " );
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir                             aFilter.appendAscii( "( " );
897*cdf0e10cSrcweir                             aFilter.append( aRowFilter.makeStringAndClear() );
898*cdf0e10cSrcweir                             aFilter.appendAscii( " )" );
899*cdf0e10cSrcweir                         }
900*cdf0e10cSrcweir                     }
901*cdf0e10cSrcweir                 }
902*cdf0e10cSrcweir                 catch( const Exception& )
903*cdf0e10cSrcweir                 {
904*cdf0e10cSrcweir                     DBG_UNHANDLED_EXCEPTION();
905*cdf0e10cSrcweir                     aFilter.setLength(0);
906*cdf0e10cSrcweir                 }
907*cdf0e10cSrcweir             }
908*cdf0e10cSrcweir             rValue <<= aFilter.makeStringAndClear();
909*cdf0e10cSrcweir         }
910*cdf0e10cSrcweir         break;
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir         case FM_ATTR_FORM_OPERATIONS:
913*cdf0e10cSrcweir             rValue <<= m_xFormOperations;
914*cdf0e10cSrcweir             break;
915*cdf0e10cSrcweir     }
916*cdf0e10cSrcweir }
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir //------------------------------------------------------------------------------
919*cdf0e10cSrcweir Reference< XPropertySetInfo >  FormController::getPropertySetInfo() throw( RuntimeException )
920*cdf0e10cSrcweir {
921*cdf0e10cSrcweir     static Reference< XPropertySetInfo >  xInfo( createPropertySetInfo( getInfoHelper() ) );
922*cdf0e10cSrcweir     return xInfo;
923*cdf0e10cSrcweir }
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir //------------------------------------------------------------------------------
926*cdf0e10cSrcweir #define DECL_PROP_CORE(varname, type) \
927*cdf0e10cSrcweir pDesc[nPos++] = Property(FM_PROP_##varname, FM_ATTR_##varname, ::getCppuType((const type*)0),
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir #define DECL_PROP1(varname, type, attrib1)  \
931*cdf0e10cSrcweir     DECL_PROP_CORE(varname, type) PropertyAttribute::attrib1)
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir //------------------------------------------------------------------------------
934*cdf0e10cSrcweir void FormController::fillProperties(
935*cdf0e10cSrcweir         Sequence< Property >& /* [out] */ _rProps,
936*cdf0e10cSrcweir         Sequence< Property >& /* [out] */ /*_rAggregateProps*/
937*cdf0e10cSrcweir         ) const
938*cdf0e10cSrcweir {
939*cdf0e10cSrcweir     _rProps.realloc(2);
940*cdf0e10cSrcweir     sal_Int32 nPos = 0;
941*cdf0e10cSrcweir     Property* pDesc = _rProps.getArray();
942*cdf0e10cSrcweir     DECL_PROP1(FILTER, rtl::OUString, READONLY);
943*cdf0e10cSrcweir     DECL_PROP1(FORM_OPERATIONS, Reference< XFormOperations >, READONLY);
944*cdf0e10cSrcweir }
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir //------------------------------------------------------------------------------
947*cdf0e10cSrcweir ::cppu::IPropertyArrayHelper& FormController::getInfoHelper()
948*cdf0e10cSrcweir {
949*cdf0e10cSrcweir     return *getArrayHelper();
950*cdf0e10cSrcweir }
951*cdf0e10cSrcweir 
952*cdf0e10cSrcweir // XFilterController
953*cdf0e10cSrcweir //------------------------------------------------------------------------------
954*cdf0e10cSrcweir void SAL_CALL FormController::addFilterControllerListener( const Reference< XFilterControllerListener >& _Listener ) throw( RuntimeException )
955*cdf0e10cSrcweir {
956*cdf0e10cSrcweir     m_aFilterListeners.addInterface( _Listener );
957*cdf0e10cSrcweir }
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir //------------------------------------------------------------------------------
960*cdf0e10cSrcweir void SAL_CALL FormController::removeFilterControllerListener( const Reference< XFilterControllerListener >& _Listener ) throw( RuntimeException )
961*cdf0e10cSrcweir {
962*cdf0e10cSrcweir     m_aFilterListeners.removeInterface( _Listener );
963*cdf0e10cSrcweir }
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir //------------------------------------------------------------------------------
966*cdf0e10cSrcweir ::sal_Int32 SAL_CALL FormController::getFilterComponents() throw( ::com::sun::star::uno::RuntimeException )
967*cdf0e10cSrcweir {
968*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
969*cdf0e10cSrcweir     impl_checkDisposed_throw();
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir     return m_aFilterComponents.size();
972*cdf0e10cSrcweir }
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir //------------------------------------------------------------------------------
975*cdf0e10cSrcweir ::sal_Int32 SAL_CALL FormController::getDisjunctiveTerms() throw( ::com::sun::star::uno::RuntimeException )
976*cdf0e10cSrcweir {
977*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
978*cdf0e10cSrcweir     impl_checkDisposed_throw();
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir     return m_aFilterRows.size();
981*cdf0e10cSrcweir }
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir //------------------------------------------------------------------------------
984*cdf0e10cSrcweir void SAL_CALL FormController::setPredicateExpression( ::sal_Int32 _Component, ::sal_Int32 _Term, const ::rtl::OUString& _PredicateExpression ) throw( RuntimeException, IndexOutOfBoundsException )
985*cdf0e10cSrcweir {
986*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
987*cdf0e10cSrcweir     impl_checkDisposed_throw();
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir     if ( ( _Component < 0 ) || ( _Component >= getFilterComponents() ) || ( _Term < 0 ) || ( _Term >= getDisjunctiveTerms() ) )
990*cdf0e10cSrcweir         throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir     Reference< XTextComponent > xText( m_aFilterComponents[ _Component ] );
993*cdf0e10cSrcweir     xText->setText( _PredicateExpression );
994*cdf0e10cSrcweir 
995*cdf0e10cSrcweir     FmFilterRow& rFilterRow = m_aFilterRows[ _Term ];
996*cdf0e10cSrcweir     if ( _PredicateExpression.getLength() )
997*cdf0e10cSrcweir         rFilterRow[ xText ] = _PredicateExpression;
998*cdf0e10cSrcweir     else
999*cdf0e10cSrcweir         rFilterRow.erase( xText );
1000*cdf0e10cSrcweir }
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir //------------------------------------------------------------------------------
1003*cdf0e10cSrcweir Reference< XControl > FormController::getFilterComponent( ::sal_Int32 _Component ) throw( RuntimeException, IndexOutOfBoundsException )
1004*cdf0e10cSrcweir {
1005*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1006*cdf0e10cSrcweir     impl_checkDisposed_throw();
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir     if ( ( _Component < 0 ) || ( _Component >= getFilterComponents() ) )
1009*cdf0e10cSrcweir         throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
1010*cdf0e10cSrcweir 
1011*cdf0e10cSrcweir     return Reference< XControl >( m_aFilterComponents[ _Component ], UNO_QUERY );
1012*cdf0e10cSrcweir }
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir //------------------------------------------------------------------------------
1015*cdf0e10cSrcweir Sequence< Sequence< ::rtl::OUString > > FormController::getPredicateExpressions() throw( RuntimeException )
1016*cdf0e10cSrcweir {
1017*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1018*cdf0e10cSrcweir     impl_checkDisposed_throw();
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir     Sequence< Sequence< ::rtl::OUString > > aExpressions( m_aFilterRows.size() );
1021*cdf0e10cSrcweir     sal_Int32 termIndex = 0;
1022*cdf0e10cSrcweir     for (   FmFilterRows::const_iterator row = m_aFilterRows.begin();
1023*cdf0e10cSrcweir             row != m_aFilterRows.end();
1024*cdf0e10cSrcweir             ++row, ++termIndex
1025*cdf0e10cSrcweir         )
1026*cdf0e10cSrcweir     {
1027*cdf0e10cSrcweir         const FmFilterRow& rRow( *row );
1028*cdf0e10cSrcweir 
1029*cdf0e10cSrcweir         Sequence< ::rtl::OUString > aConjunction( m_aFilterComponents.size() );
1030*cdf0e10cSrcweir         sal_Int32 componentIndex = 0;
1031*cdf0e10cSrcweir         for (   FilterComponents::const_iterator comp = m_aFilterComponents.begin();
1032*cdf0e10cSrcweir                 comp != m_aFilterComponents.end();
1033*cdf0e10cSrcweir                 ++comp, ++componentIndex
1034*cdf0e10cSrcweir             )
1035*cdf0e10cSrcweir         {
1036*cdf0e10cSrcweir             FmFilterRow::const_iterator predicate = rRow.find( *comp );
1037*cdf0e10cSrcweir             if ( predicate != rRow.end() )
1038*cdf0e10cSrcweir                 aConjunction[ componentIndex ] = predicate->second;
1039*cdf0e10cSrcweir         }
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir         aExpressions[ termIndex ] = aConjunction;
1042*cdf0e10cSrcweir     }
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir     return aExpressions;
1045*cdf0e10cSrcweir }
1046*cdf0e10cSrcweir 
1047*cdf0e10cSrcweir //------------------------------------------------------------------------------
1048*cdf0e10cSrcweir void SAL_CALL FormController::removeDisjunctiveTerm( ::sal_Int32 _Term ) throw (IndexOutOfBoundsException, RuntimeException)
1049*cdf0e10cSrcweir {
1050*cdf0e10cSrcweir     // SYNCHRONIZED -->
1051*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
1052*cdf0e10cSrcweir     impl_checkDisposed_throw();
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir     if ( ( _Term < 0 ) || ( _Term >= getDisjunctiveTerms() ) )
1055*cdf0e10cSrcweir         throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir     // if the to-be-deleted row is our current row, we need to shift
1058*cdf0e10cSrcweir     if ( _Term == m_nCurrentFilterPosition )
1059*cdf0e10cSrcweir     {
1060*cdf0e10cSrcweir         if ( m_nCurrentFilterPosition < sal_Int32( m_aFilterRows.size() - 1 ) )
1061*cdf0e10cSrcweir             ++m_nCurrentFilterPosition;
1062*cdf0e10cSrcweir         else
1063*cdf0e10cSrcweir             --m_nCurrentFilterPosition;
1064*cdf0e10cSrcweir     }
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir     FmFilterRows::iterator pos = m_aFilterRows.begin() + _Term;
1067*cdf0e10cSrcweir     m_aFilterRows.erase( pos );
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir     // adjust m_nCurrentFilterPosition if the removed row preceeded it
1070*cdf0e10cSrcweir     if ( _Term < m_nCurrentFilterPosition )
1071*cdf0e10cSrcweir         --m_nCurrentFilterPosition;
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir     OSL_POSTCOND( ( m_nCurrentFilterPosition < 0 ) == ( m_aFilterRows.empty() ),
1074*cdf0e10cSrcweir         "FormController::removeDisjunctiveTerm: inconsistency!" );
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir     // update the texts in the filter controls
1077*cdf0e10cSrcweir     impl_setTextOnAllFilter_throw();
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir     FilterEvent aEvent;
1080*cdf0e10cSrcweir     aEvent.Source = *this;
1081*cdf0e10cSrcweir     aEvent.DisjunctiveTerm = _Term;
1082*cdf0e10cSrcweir     aGuard.clear();
1083*cdf0e10cSrcweir     // <-- SYNCHRONIZED
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir     m_aFilterListeners.notifyEach( &XFilterControllerListener::disjunctiveTermRemoved, aEvent );
1086*cdf0e10cSrcweir }
1087*cdf0e10cSrcweir 
1088*cdf0e10cSrcweir //------------------------------------------------------------------------------
1089*cdf0e10cSrcweir void SAL_CALL FormController::appendEmptyDisjunctiveTerm() throw (RuntimeException)
1090*cdf0e10cSrcweir {
1091*cdf0e10cSrcweir     // SYNCHRONIZED -->
1092*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
1093*cdf0e10cSrcweir     impl_checkDisposed_throw();
1094*cdf0e10cSrcweir 
1095*cdf0e10cSrcweir     impl_appendEmptyFilterRow( aGuard );
1096*cdf0e10cSrcweir     // <-- SYNCHRONIZED
1097*cdf0e10cSrcweir }
1098*cdf0e10cSrcweir 
1099*cdf0e10cSrcweir //------------------------------------------------------------------------------
1100*cdf0e10cSrcweir ::sal_Int32 SAL_CALL FormController::getActiveTerm() throw (RuntimeException)
1101*cdf0e10cSrcweir {
1102*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1103*cdf0e10cSrcweir     impl_checkDisposed_throw();
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir     return m_nCurrentFilterPosition;
1106*cdf0e10cSrcweir }
1107*cdf0e10cSrcweir 
1108*cdf0e10cSrcweir //------------------------------------------------------------------------------
1109*cdf0e10cSrcweir void SAL_CALL FormController::setActiveTerm( ::sal_Int32 _ActiveTerm ) throw (IndexOutOfBoundsException, RuntimeException)
1110*cdf0e10cSrcweir {
1111*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1112*cdf0e10cSrcweir     impl_checkDisposed_throw();
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir     if ( ( _ActiveTerm < 0 ) || ( _ActiveTerm >= getDisjunctiveTerms() ) )
1115*cdf0e10cSrcweir         throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir     if ( _ActiveTerm == getActiveTerm() )
1118*cdf0e10cSrcweir         return;
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir     m_nCurrentFilterPosition = _ActiveTerm;
1121*cdf0e10cSrcweir     impl_setTextOnAllFilter_throw();
1122*cdf0e10cSrcweir }
1123*cdf0e10cSrcweir 
1124*cdf0e10cSrcweir // XElementAccess
1125*cdf0e10cSrcweir //------------------------------------------------------------------------------
1126*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::hasElements(void) throw( RuntimeException )
1127*cdf0e10cSrcweir {
1128*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1129*cdf0e10cSrcweir     return !m_aChilds.empty();
1130*cdf0e10cSrcweir }
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir //------------------------------------------------------------------------------
1133*cdf0e10cSrcweir Type SAL_CALL  FormController::getElementType(void) throw( RuntimeException )
1134*cdf0e10cSrcweir {
1135*cdf0e10cSrcweir     return ::getCppuType((const Reference< XFormController>*)0);
1136*cdf0e10cSrcweir 
1137*cdf0e10cSrcweir }
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir // XEnumerationAccess
1140*cdf0e10cSrcweir //------------------------------------------------------------------------------
1141*cdf0e10cSrcweir Reference< XEnumeration > SAL_CALL  FormController::createEnumeration(void) throw( RuntimeException )
1142*cdf0e10cSrcweir {
1143*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1144*cdf0e10cSrcweir     return new ::comphelper::OEnumerationByIndex(this);
1145*cdf0e10cSrcweir }
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir // XIndexAccess
1148*cdf0e10cSrcweir //------------------------------------------------------------------------------
1149*cdf0e10cSrcweir sal_Int32 SAL_CALL FormController::getCount(void) throw( RuntimeException )
1150*cdf0e10cSrcweir {
1151*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1152*cdf0e10cSrcweir     return m_aChilds.size();
1153*cdf0e10cSrcweir }
1154*cdf0e10cSrcweir 
1155*cdf0e10cSrcweir //------------------------------------------------------------------------------
1156*cdf0e10cSrcweir Any SAL_CALL FormController::getByIndex(sal_Int32 Index) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1157*cdf0e10cSrcweir {
1158*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1159*cdf0e10cSrcweir 	if (Index < 0 ||
1160*cdf0e10cSrcweir 		Index >= (sal_Int32)m_aChilds.size())
1161*cdf0e10cSrcweir 		throw IndexOutOfBoundsException();
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir     return makeAny( m_aChilds[ Index ] );
1164*cdf0e10cSrcweir }
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir //  EventListener
1167*cdf0e10cSrcweir //------------------------------------------------------------------------------
1168*cdf0e10cSrcweir void SAL_CALL FormController::disposing(const EventObject& e) throw( RuntimeException )
1169*cdf0e10cSrcweir {
1170*cdf0e10cSrcweir     // Ist der Container disposed worden
1171*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1172*cdf0e10cSrcweir     Reference< XControlContainer >  xContainer(e.Source, UNO_QUERY);
1173*cdf0e10cSrcweir     if (xContainer.is())
1174*cdf0e10cSrcweir     {
1175*cdf0e10cSrcweir         setContainer(Reference< XControlContainer > ());
1176*cdf0e10cSrcweir     }
1177*cdf0e10cSrcweir     else
1178*cdf0e10cSrcweir     {
1179*cdf0e10cSrcweir         // ist ein Control disposed worden
1180*cdf0e10cSrcweir         Reference< XControl >  xControl(e.Source, UNO_QUERY);
1181*cdf0e10cSrcweir         if (xControl.is())
1182*cdf0e10cSrcweir         {
1183*cdf0e10cSrcweir             if (getContainer().is())
1184*cdf0e10cSrcweir                 removeControl(xControl);
1185*cdf0e10cSrcweir         }
1186*cdf0e10cSrcweir     }
1187*cdf0e10cSrcweir }
1188*cdf0e10cSrcweir 
1189*cdf0e10cSrcweir // OComponentHelper
1190*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1191*cdf0e10cSrcweir void FormController::disposeAllFeaturesAndDispatchers() SAL_THROW(())
1192*cdf0e10cSrcweir {
1193*cdf0e10cSrcweir     for ( DispatcherContainer::iterator aDispatcher = m_aFeatureDispatchers.begin();
1194*cdf0e10cSrcweir           aDispatcher != m_aFeatureDispatchers.end();
1195*cdf0e10cSrcweir           ++aDispatcher
1196*cdf0e10cSrcweir         )
1197*cdf0e10cSrcweir     {
1198*cdf0e10cSrcweir         try
1199*cdf0e10cSrcweir         {
1200*cdf0e10cSrcweir             ::comphelper::disposeComponent( aDispatcher->second );
1201*cdf0e10cSrcweir         }
1202*cdf0e10cSrcweir         catch( const Exception& )
1203*cdf0e10cSrcweir         {
1204*cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
1205*cdf0e10cSrcweir         }
1206*cdf0e10cSrcweir     }
1207*cdf0e10cSrcweir     m_aFeatureDispatchers.clear();
1208*cdf0e10cSrcweir }
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1211*cdf0e10cSrcweir void FormController::disposing(void)
1212*cdf0e10cSrcweir {
1213*cdf0e10cSrcweir     EventObject aEvt( *this );
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir     // if we're still active, simulate a "deactivated" event
1216*cdf0e10cSrcweir     if ( m_xActiveControl.is() )
1217*cdf0e10cSrcweir         m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvt );
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir     // notify all our listeners
1220*cdf0e10cSrcweir     m_aActivateListeners.disposeAndClear(aEvt);
1221*cdf0e10cSrcweir     m_aModifyListeners.disposeAndClear(aEvt);
1222*cdf0e10cSrcweir     m_aErrorListeners.disposeAndClear(aEvt);
1223*cdf0e10cSrcweir     m_aDeleteListeners.disposeAndClear(aEvt);
1224*cdf0e10cSrcweir     m_aRowSetApproveListeners.disposeAndClear(aEvt);
1225*cdf0e10cSrcweir     m_aParameterListeners.disposeAndClear(aEvt);
1226*cdf0e10cSrcweir     m_aFilterListeners.disposeAndClear(aEvt);
1227*cdf0e10cSrcweir 
1228*cdf0e10cSrcweir 	removeBoundFieldListener();
1229*cdf0e10cSrcweir 	stopFiltering();
1230*cdf0e10cSrcweir 
1231*cdf0e10cSrcweir     m_pControlBorderManager->restoreAll();
1232*cdf0e10cSrcweir 
1233*cdf0e10cSrcweir     m_aFilterRows.clear();
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1236*cdf0e10cSrcweir     m_xActiveControl = NULL;
1237*cdf0e10cSrcweir     implSetCurrentControl( NULL );
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir     // clean up our children
1240*cdf0e10cSrcweir     for (FmFormControllers::const_iterator i = m_aChilds.begin();
1241*cdf0e10cSrcweir         i != m_aChilds.end(); i++)
1242*cdf0e10cSrcweir     {
1243*cdf0e10cSrcweir         // search the position of the model within the form
1244*cdf0e10cSrcweir         Reference< XFormComponent >  xForm((*i)->getModel(), UNO_QUERY);
1245*cdf0e10cSrcweir         sal_uInt32 nPos = m_xModelAsIndex->getCount();
1246*cdf0e10cSrcweir         Reference< XFormComponent > xTemp;
1247*cdf0e10cSrcweir         for( ; nPos; )
1248*cdf0e10cSrcweir         {
1249*cdf0e10cSrcweir 
1250*cdf0e10cSrcweir             m_xModelAsIndex->getByIndex( --nPos ) >>= xTemp;
1251*cdf0e10cSrcweir             if ( xForm.get() == xTemp.get() )
1252*cdf0e10cSrcweir             {
1253*cdf0e10cSrcweir                 Reference< XInterface > xIfc( *i, UNO_QUERY );
1254*cdf0e10cSrcweir                 m_xModelAsManager->detach( nPos, xIfc );
1255*cdf0e10cSrcweir                 break;
1256*cdf0e10cSrcweir             }
1257*cdf0e10cSrcweir         }
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir         Reference< XComponent > (*i, UNO_QUERY)->dispose();
1260*cdf0e10cSrcweir     }
1261*cdf0e10cSrcweir     m_aChilds.clear();
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir     disposeAllFeaturesAndDispatchers();
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir     if ( m_xFormOperations.is() )
1266*cdf0e10cSrcweir         m_xFormOperations->dispose();
1267*cdf0e10cSrcweir     m_xFormOperations.clear();
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir     if (m_bDBConnection)
1270*cdf0e10cSrcweir         unload();
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir     setContainer( NULL );
1273*cdf0e10cSrcweir     setModel( NULL );
1274*cdf0e10cSrcweir     setParent( NULL );
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir     ::comphelper::disposeComponent( m_xComposer );
1277*cdf0e10cSrcweir 
1278*cdf0e10cSrcweir     m_bDBConnection = sal_False;
1279*cdf0e10cSrcweir }
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir //------------------------------------------------------------------------------
1282*cdf0e10cSrcweir namespace
1283*cdf0e10cSrcweir {
1284*cdf0e10cSrcweir     static bool lcl_shouldUseDynamicControlBorder( const Reference< XInterface >& _rxForm, const Any& _rDynamicColorProp )
1285*cdf0e10cSrcweir     {
1286*cdf0e10cSrcweir         bool bDoUse = false;
1287*cdf0e10cSrcweir         if ( !( _rDynamicColorProp >>= bDoUse ) )
1288*cdf0e10cSrcweir         {
1289*cdf0e10cSrcweir             DocumentType eDocType = DocumentClassification::classifyHostDocument( _rxForm );
1290*cdf0e10cSrcweir             return ControlLayouter::useDynamicBorderColor( eDocType );
1291*cdf0e10cSrcweir         }
1292*cdf0e10cSrcweir         return bDoUse;
1293*cdf0e10cSrcweir     }
1294*cdf0e10cSrcweir }
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir //------------------------------------------------------------------------------
1297*cdf0e10cSrcweir void SAL_CALL FormController::propertyChange(const PropertyChangeEvent& evt) throw( RuntimeException )
1298*cdf0e10cSrcweir {
1299*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1300*cdf0e10cSrcweir     if ( evt.PropertyName == FM_PROP_BOUNDFIELD )
1301*cdf0e10cSrcweir     {
1302*cdf0e10cSrcweir 		Reference<XPropertySet> xOldBound;
1303*cdf0e10cSrcweir 		evt.OldValue >>= xOldBound;
1304*cdf0e10cSrcweir 		if ( !xOldBound.is() && evt.NewValue.hasValue() )
1305*cdf0e10cSrcweir 		{
1306*cdf0e10cSrcweir 			Reference< XControlModel > xControlModel(evt.Source,UNO_QUERY);
1307*cdf0e10cSrcweir 			Reference< XControl > xControl = findControl(m_aControls,xControlModel,sal_False,sal_False);
1308*cdf0e10cSrcweir 			if ( xControl.is() )
1309*cdf0e10cSrcweir 			{
1310*cdf0e10cSrcweir 				startControlModifyListening( xControl );
1311*cdf0e10cSrcweir 				Reference<XPropertySet> xProp(xControlModel,UNO_QUERY);
1312*cdf0e10cSrcweir 				if ( xProp.is() )
1313*cdf0e10cSrcweir 					xProp->removePropertyChangeListener(FM_PROP_BOUNDFIELD, this);
1314*cdf0e10cSrcweir 			}
1315*cdf0e10cSrcweir 		}
1316*cdf0e10cSrcweir     }
1317*cdf0e10cSrcweir     else
1318*cdf0e10cSrcweir     {
1319*cdf0e10cSrcweir 		sal_Bool bModifiedChanged = (evt.PropertyName == FM_PROP_ISMODIFIED);
1320*cdf0e10cSrcweir 		sal_Bool bNewChanged = (evt.PropertyName == FM_PROP_ISNEW);
1321*cdf0e10cSrcweir 		if (bModifiedChanged || bNewChanged)
1322*cdf0e10cSrcweir 		{
1323*cdf0e10cSrcweir 			::osl::MutexGuard aGuard( m_aMutex );
1324*cdf0e10cSrcweir 			if (bModifiedChanged)
1325*cdf0e10cSrcweir 				m_bCurrentRecordModified = ::comphelper::getBOOL(evt.NewValue);
1326*cdf0e10cSrcweir 			else
1327*cdf0e10cSrcweir 				m_bCurrentRecordNew = ::comphelper::getBOOL(evt.NewValue);
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir 			// toggle the locking
1330*cdf0e10cSrcweir 			if (m_bLocked != determineLockState())
1331*cdf0e10cSrcweir 			{
1332*cdf0e10cSrcweir 				m_bLocked = !m_bLocked;
1333*cdf0e10cSrcweir 				setLocks();
1334*cdf0e10cSrcweir 				if (isListeningForChanges())
1335*cdf0e10cSrcweir 					startListening();
1336*cdf0e10cSrcweir 				else
1337*cdf0e10cSrcweir 					stopListening();
1338*cdf0e10cSrcweir 			}
1339*cdf0e10cSrcweir 
1340*cdf0e10cSrcweir 			if ( bNewChanged )
1341*cdf0e10cSrcweir 				m_aToggleEvent.Call();
1342*cdf0e10cSrcweir 
1343*cdf0e10cSrcweir 			if (!m_bCurrentRecordModified)
1344*cdf0e10cSrcweir 				m_bModified = sal_False;
1345*cdf0e10cSrcweir 		}
1346*cdf0e10cSrcweir         else if ( evt.PropertyName == FM_PROP_DYNAMIC_CONTROL_BORDER )
1347*cdf0e10cSrcweir         {
1348*cdf0e10cSrcweir             bool bEnable = lcl_shouldUseDynamicControlBorder( evt.Source, evt.NewValue );
1349*cdf0e10cSrcweir             if ( bEnable )
1350*cdf0e10cSrcweir             {
1351*cdf0e10cSrcweir                 m_pControlBorderManager->enableDynamicBorderColor();
1352*cdf0e10cSrcweir                 if ( m_xActiveControl.is() )
1353*cdf0e10cSrcweir                     m_pControlBorderManager->focusGained( m_xActiveControl.get() );
1354*cdf0e10cSrcweir             }
1355*cdf0e10cSrcweir             else
1356*cdf0e10cSrcweir             {
1357*cdf0e10cSrcweir                 m_pControlBorderManager->disableDynamicBorderColor();
1358*cdf0e10cSrcweir             }
1359*cdf0e10cSrcweir         }
1360*cdf0e10cSrcweir 	}
1361*cdf0e10cSrcweir }
1362*cdf0e10cSrcweir 
1363*cdf0e10cSrcweir //------------------------------------------------------------------------------
1364*cdf0e10cSrcweir bool FormController::replaceControl( const Reference< XControl >& _rxExistentControl, const Reference< XControl >& _rxNewControl )
1365*cdf0e10cSrcweir {
1366*cdf0e10cSrcweir     bool bSuccess = false;
1367*cdf0e10cSrcweir     try
1368*cdf0e10cSrcweir     {
1369*cdf0e10cSrcweir         Reference< XIdentifierReplace > xContainer( getContainer(), UNO_QUERY );
1370*cdf0e10cSrcweir         DBG_ASSERT( xContainer.is(), "FormController::replaceControl: yes, it's not required by the service description, but XItentifierReplaces would be nice!" );
1371*cdf0e10cSrcweir         if ( xContainer.is() )
1372*cdf0e10cSrcweir         {
1373*cdf0e10cSrcweir             // look up the ID of _rxExistentControl
1374*cdf0e10cSrcweir             Sequence< sal_Int32 > aIdentifiers( xContainer->getIdentifiers() );
1375*cdf0e10cSrcweir             const sal_Int32* pIdentifiers = aIdentifiers.getConstArray();
1376*cdf0e10cSrcweir             const sal_Int32* pIdentifiersEnd = aIdentifiers.getConstArray() + aIdentifiers.getLength();
1377*cdf0e10cSrcweir             for ( ; pIdentifiers != pIdentifiersEnd; ++pIdentifiers )
1378*cdf0e10cSrcweir             {
1379*cdf0e10cSrcweir                 Reference< XControl > xCheck( xContainer->getByIdentifier( *pIdentifiers ), UNO_QUERY );
1380*cdf0e10cSrcweir                 if ( xCheck == _rxExistentControl )
1381*cdf0e10cSrcweir                     break;
1382*cdf0e10cSrcweir             }
1383*cdf0e10cSrcweir             DBG_ASSERT( pIdentifiers != pIdentifiersEnd, "FormController::replaceControl: did not find the control in the container!" );
1384*cdf0e10cSrcweir             if ( pIdentifiers != pIdentifiersEnd )
1385*cdf0e10cSrcweir             {
1386*cdf0e10cSrcweir                 bool bReplacedWasActive = ( m_xActiveControl.get() == _rxExistentControl.get() );
1387*cdf0e10cSrcweir                 bool bReplacedWasCurrent = ( m_xCurrentControl.get() == _rxExistentControl.get() );
1388*cdf0e10cSrcweir 
1389*cdf0e10cSrcweir                 if ( bReplacedWasActive )
1390*cdf0e10cSrcweir                 {
1391*cdf0e10cSrcweir                     m_xActiveControl = NULL;
1392*cdf0e10cSrcweir                     implSetCurrentControl( NULL );
1393*cdf0e10cSrcweir                 }
1394*cdf0e10cSrcweir                 else if ( bReplacedWasCurrent )
1395*cdf0e10cSrcweir                 {
1396*cdf0e10cSrcweir                     implSetCurrentControl( _rxNewControl );
1397*cdf0e10cSrcweir                 }
1398*cdf0e10cSrcweir 
1399*cdf0e10cSrcweir                 // carry over the model
1400*cdf0e10cSrcweir                 _rxNewControl->setModel( _rxExistentControl->getModel() );
1401*cdf0e10cSrcweir 
1402*cdf0e10cSrcweir                 xContainer->replaceByIdentifer( *pIdentifiers, makeAny( _rxNewControl ) );
1403*cdf0e10cSrcweir                 bSuccess = true;
1404*cdf0e10cSrcweir 
1405*cdf0e10cSrcweir                 if ( bReplacedWasActive )
1406*cdf0e10cSrcweir                 {
1407*cdf0e10cSrcweir                     Reference< XWindow > xControlWindow( _rxNewControl, UNO_QUERY );
1408*cdf0e10cSrcweir                     if ( xControlWindow.is() )
1409*cdf0e10cSrcweir                         xControlWindow->setFocus();
1410*cdf0e10cSrcweir                 }
1411*cdf0e10cSrcweir             }
1412*cdf0e10cSrcweir         }
1413*cdf0e10cSrcweir     }
1414*cdf0e10cSrcweir     catch( const Exception& )
1415*cdf0e10cSrcweir     {
1416*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
1417*cdf0e10cSrcweir     }
1418*cdf0e10cSrcweir 
1419*cdf0e10cSrcweir     Reference< XControl > xDisposeIt( bSuccess ? _rxExistentControl : _rxNewControl );
1420*cdf0e10cSrcweir     ::comphelper::disposeComponent( xDisposeIt );
1421*cdf0e10cSrcweir     return bSuccess;
1422*cdf0e10cSrcweir }
1423*cdf0e10cSrcweir 
1424*cdf0e10cSrcweir //------------------------------------------------------------------------------
1425*cdf0e10cSrcweir void FormController::toggleAutoFields(sal_Bool bAutoFields)
1426*cdf0e10cSrcweir {
1427*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir     Sequence< Reference< XControl > > aControlsCopy( m_aControls );
1431*cdf0e10cSrcweir     const Reference< XControl >* pControls = aControlsCopy.getConstArray();
1432*cdf0e10cSrcweir     sal_Int32 nControls = aControlsCopy.getLength();
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir     if (bAutoFields)
1435*cdf0e10cSrcweir     {
1436*cdf0e10cSrcweir         // as we don't want new controls to be attached to the scripting environment
1437*cdf0e10cSrcweir         // we change attach flags
1438*cdf0e10cSrcweir         m_bAttachEvents = sal_False;
1439*cdf0e10cSrcweir         for (sal_Int32 i = nControls; i > 0;)
1440*cdf0e10cSrcweir         {
1441*cdf0e10cSrcweir             Reference< XControl > xControl = pControls[--i];
1442*cdf0e10cSrcweir             if (xControl.is())
1443*cdf0e10cSrcweir             {
1444*cdf0e10cSrcweir                 Reference< XPropertySet >  xSet(xControl->getModel(), UNO_QUERY);
1445*cdf0e10cSrcweir                 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1446*cdf0e10cSrcweir                 {
1447*cdf0e10cSrcweir                     // does the model use a bound field ?
1448*cdf0e10cSrcweir                     Reference< XPropertySet >  xField;
1449*cdf0e10cSrcweir                     xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1450*cdf0e10cSrcweir 
1451*cdf0e10cSrcweir                     // is it a autofield?
1452*cdf0e10cSrcweir                     if  (   xField.is()
1453*cdf0e10cSrcweir                         &&  ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT, xField )
1454*cdf0e10cSrcweir                         &&  ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_AUTOINCREMENT ) )
1455*cdf0e10cSrcweir                         )
1456*cdf0e10cSrcweir                     {
1457*cdf0e10cSrcweir                         replaceControl( xControl, new FmXAutoControl( m_aContext ) );
1458*cdf0e10cSrcweir                     }
1459*cdf0e10cSrcweir                 }
1460*cdf0e10cSrcweir             }
1461*cdf0e10cSrcweir         }
1462*cdf0e10cSrcweir         m_bAttachEvents = sal_True;
1463*cdf0e10cSrcweir     }
1464*cdf0e10cSrcweir     else
1465*cdf0e10cSrcweir     {
1466*cdf0e10cSrcweir         m_bDetachEvents = sal_False;
1467*cdf0e10cSrcweir         for (sal_Int32 i = nControls; i > 0;)
1468*cdf0e10cSrcweir         {
1469*cdf0e10cSrcweir             Reference< XControl > xControl = pControls[--i];
1470*cdf0e10cSrcweir             if (xControl.is())
1471*cdf0e10cSrcweir             {
1472*cdf0e10cSrcweir                 Reference< XPropertySet >  xSet(xControl->getModel(), UNO_QUERY);
1473*cdf0e10cSrcweir                 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1474*cdf0e10cSrcweir                 {
1475*cdf0e10cSrcweir                     // does the model use a bound field ?
1476*cdf0e10cSrcweir                     Reference< XPropertySet >  xField;
1477*cdf0e10cSrcweir                     xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1478*cdf0e10cSrcweir 
1479*cdf0e10cSrcweir                     // is it a autofield?
1480*cdf0e10cSrcweir                     if  (   xField.is()
1481*cdf0e10cSrcweir                         &&  ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT, xField )
1482*cdf0e10cSrcweir                         &&  ::comphelper::getBOOL( xField->getPropertyValue(FM_PROP_AUTOINCREMENT ) )
1483*cdf0e10cSrcweir                         )
1484*cdf0e10cSrcweir                     {
1485*cdf0e10cSrcweir                         ::rtl::OUString sServiceName;
1486*cdf0e10cSrcweir                         OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DEFAULTCONTROL ) >>= sServiceName );
1487*cdf0e10cSrcweir                         Reference< XControl > xNewControl( m_aContext.createComponent( sServiceName ), UNO_QUERY );
1488*cdf0e10cSrcweir                         replaceControl( xControl, xNewControl );
1489*cdf0e10cSrcweir                     }
1490*cdf0e10cSrcweir                 }
1491*cdf0e10cSrcweir             }
1492*cdf0e10cSrcweir         }
1493*cdf0e10cSrcweir         m_bDetachEvents = sal_True;
1494*cdf0e10cSrcweir     }
1495*cdf0e10cSrcweir }
1496*cdf0e10cSrcweir 
1497*cdf0e10cSrcweir //------------------------------------------------------------------------------
1498*cdf0e10cSrcweir IMPL_LINK(FormController, OnToggleAutoFields, void*, EMPTYARG)
1499*cdf0e10cSrcweir {
1500*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1501*cdf0e10cSrcweir 
1502*cdf0e10cSrcweir     toggleAutoFields(m_bCurrentRecordNew);
1503*cdf0e10cSrcweir     return 1L;
1504*cdf0e10cSrcweir }
1505*cdf0e10cSrcweir 
1506*cdf0e10cSrcweir // XTextListener
1507*cdf0e10cSrcweir //------------------------------------------------------------------------------
1508*cdf0e10cSrcweir void SAL_CALL FormController::textChanged(const TextEvent& e) throw( RuntimeException )
1509*cdf0e10cSrcweir {
1510*cdf0e10cSrcweir     // SYNCHRONIZED -->
1511*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
1512*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1513*cdf0e10cSrcweir     if ( !m_bFiltering )
1514*cdf0e10cSrcweir     {
1515*cdf0e10cSrcweir         impl_onModify();
1516*cdf0e10cSrcweir         return;
1517*cdf0e10cSrcweir     }
1518*cdf0e10cSrcweir 
1519*cdf0e10cSrcweir     if ( m_bSuspendFilterTextListening )
1520*cdf0e10cSrcweir         return;
1521*cdf0e10cSrcweir 
1522*cdf0e10cSrcweir     Reference< XTextComponent >  xText(e.Source,UNO_QUERY);
1523*cdf0e10cSrcweir     ::rtl::OUString aText = xText->getText();
1524*cdf0e10cSrcweir 
1525*cdf0e10cSrcweir     if ( m_aFilterRows.empty() )
1526*cdf0e10cSrcweir         appendEmptyDisjunctiveTerm();
1527*cdf0e10cSrcweir 
1528*cdf0e10cSrcweir     // Suchen der aktuellen Row
1529*cdf0e10cSrcweir     if ( ( (size_t)m_nCurrentFilterPosition >= m_aFilterRows.size() ) || ( m_nCurrentFilterPosition < 0 ) )
1530*cdf0e10cSrcweir     {
1531*cdf0e10cSrcweir 	    OSL_ENSURE( false, "FormController::textChanged: m_nCurrentFilterPosition is wrong!" );
1532*cdf0e10cSrcweir         return;
1533*cdf0e10cSrcweir     }
1534*cdf0e10cSrcweir 
1535*cdf0e10cSrcweir 	FmFilterRow& rRow = m_aFilterRows[ m_nCurrentFilterPosition ];
1536*cdf0e10cSrcweir 
1537*cdf0e10cSrcweir 	// do we have a new filter
1538*cdf0e10cSrcweir 	if (aText.getLength())
1539*cdf0e10cSrcweir 		rRow[xText] = aText;
1540*cdf0e10cSrcweir 	else
1541*cdf0e10cSrcweir 	{
1542*cdf0e10cSrcweir 		// do we have the control in the row
1543*cdf0e10cSrcweir 		FmFilterRow::iterator iter = rRow.find(xText);
1544*cdf0e10cSrcweir 		// erase the entry out of the row
1545*cdf0e10cSrcweir 		if (iter != rRow.end())
1546*cdf0e10cSrcweir 			rRow.erase(iter);
1547*cdf0e10cSrcweir 	}
1548*cdf0e10cSrcweir 
1549*cdf0e10cSrcweir     // multiplex the event to our FilterControllerListeners
1550*cdf0e10cSrcweir     FilterEvent aEvent;
1551*cdf0e10cSrcweir     aEvent.Source = *this;
1552*cdf0e10cSrcweir     aEvent.FilterComponent = ::std::find( m_aFilterComponents.begin(), m_aFilterComponents.end(), xText ) - m_aFilterComponents.begin();
1553*cdf0e10cSrcweir     aEvent.DisjunctiveTerm = getActiveTerm();
1554*cdf0e10cSrcweir     aEvent.PredicateExpression = aText;
1555*cdf0e10cSrcweir 
1556*cdf0e10cSrcweir     aGuard.clear();
1557*cdf0e10cSrcweir     // <-- SYNCHRONIZED
1558*cdf0e10cSrcweir 
1559*cdf0e10cSrcweir     // notify the changed filter expression
1560*cdf0e10cSrcweir     m_aFilterListeners.notifyEach( &XFilterControllerListener::predicateExpressionChanged, aEvent );
1561*cdf0e10cSrcweir }
1562*cdf0e10cSrcweir 
1563*cdf0e10cSrcweir // XItemListener
1564*cdf0e10cSrcweir //------------------------------------------------------------------------------
1565*cdf0e10cSrcweir void SAL_CALL FormController::itemStateChanged(const ItemEvent& /*rEvent*/) throw( RuntimeException )
1566*cdf0e10cSrcweir {
1567*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1568*cdf0e10cSrcweir     impl_onModify();
1569*cdf0e10cSrcweir }
1570*cdf0e10cSrcweir 
1571*cdf0e10cSrcweir // XModificationBroadcaster
1572*cdf0e10cSrcweir //------------------------------------------------------------------------------
1573*cdf0e10cSrcweir void SAL_CALL FormController::addModifyListener(const Reference< XModifyListener > & l) throw( RuntimeException )
1574*cdf0e10cSrcweir {
1575*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1576*cdf0e10cSrcweir     impl_checkDisposed_throw();
1577*cdf0e10cSrcweir     m_aModifyListeners.addInterface( l );
1578*cdf0e10cSrcweir }
1579*cdf0e10cSrcweir 
1580*cdf0e10cSrcweir //------------------------------------------------------------------------------
1581*cdf0e10cSrcweir void FormController::removeModifyListener(const Reference< XModifyListener > & l) throw( RuntimeException )
1582*cdf0e10cSrcweir {
1583*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1584*cdf0e10cSrcweir     impl_checkDisposed_throw();
1585*cdf0e10cSrcweir     m_aModifyListeners.removeInterface( l );
1586*cdf0e10cSrcweir }
1587*cdf0e10cSrcweir 
1588*cdf0e10cSrcweir // XModificationListener
1589*cdf0e10cSrcweir //------------------------------------------------------------------------------
1590*cdf0e10cSrcweir void FormController::modified( const EventObject& _rEvent ) throw( RuntimeException )
1591*cdf0e10cSrcweir {
1592*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1593*cdf0e10cSrcweir 
1594*cdf0e10cSrcweir     try
1595*cdf0e10cSrcweir     {
1596*cdf0e10cSrcweir         if ( _rEvent.Source != m_xActiveControl )
1597*cdf0e10cSrcweir         {	// let this control grab the focus
1598*cdf0e10cSrcweir             // (this case may happen if somebody moves the scroll wheel of the mouse over a control
1599*cdf0e10cSrcweir             // which does not have the focus)
1600*cdf0e10cSrcweir             // 85511 - 29.05.2001 - frank.schoenheit@germany.sun.com
1601*cdf0e10cSrcweir             //
1602*cdf0e10cSrcweir             // also, it happens when an image control gets a new image by double-clicking it
1603*cdf0e10cSrcweir             // #i88458# / 2009-01-12 / frank.schoenheit@sun.com
1604*cdf0e10cSrcweir             Reference< XWindow > xControlWindow( _rEvent.Source, UNO_QUERY_THROW );
1605*cdf0e10cSrcweir             xControlWindow->setFocus();
1606*cdf0e10cSrcweir         }
1607*cdf0e10cSrcweir     }
1608*cdf0e10cSrcweir     catch( const Exception& )
1609*cdf0e10cSrcweir     {
1610*cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
1611*cdf0e10cSrcweir     }
1612*cdf0e10cSrcweir 
1613*cdf0e10cSrcweir     impl_onModify();
1614*cdf0e10cSrcweir }
1615*cdf0e10cSrcweir 
1616*cdf0e10cSrcweir //------------------------------------------------------------------------------
1617*cdf0e10cSrcweir void FormController::impl_checkDisposed_throw() const
1618*cdf0e10cSrcweir {
1619*cdf0e10cSrcweir     if ( impl_isDisposed_nofail() )
1620*cdf0e10cSrcweir         throw DisposedException( ::rtl::OUString(), *const_cast< FormController* >( this ) );
1621*cdf0e10cSrcweir }
1622*cdf0e10cSrcweir 
1623*cdf0e10cSrcweir //------------------------------------------------------------------------------
1624*cdf0e10cSrcweir void FormController::impl_onModify()
1625*cdf0e10cSrcweir {
1626*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1627*cdf0e10cSrcweir 
1628*cdf0e10cSrcweir     {
1629*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
1630*cdf0e10cSrcweir         if ( !m_bModified )
1631*cdf0e10cSrcweir             m_bModified = sal_True;
1632*cdf0e10cSrcweir     }
1633*cdf0e10cSrcweir 
1634*cdf0e10cSrcweir 	EventObject aEvt(static_cast<cppu::OWeakObject*>(this));
1635*cdf0e10cSrcweir     m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
1636*cdf0e10cSrcweir }
1637*cdf0e10cSrcweir 
1638*cdf0e10cSrcweir //------------------------------------------------------------------------------
1639*cdf0e10cSrcweir void FormController::impl_addFilterRow( const FmFilterRow& _row )
1640*cdf0e10cSrcweir {
1641*cdf0e10cSrcweir     m_aFilterRows.push_back( _row );
1642*cdf0e10cSrcweir 
1643*cdf0e10cSrcweir     if ( m_aFilterRows.size() == 1 )
1644*cdf0e10cSrcweir     {   // that's the first row ever
1645*cdf0e10cSrcweir         OSL_ENSURE( m_nCurrentFilterPosition == -1, "FormController::impl_addFilterRow: inconsistency!" );
1646*cdf0e10cSrcweir         m_nCurrentFilterPosition = 0;
1647*cdf0e10cSrcweir     }
1648*cdf0e10cSrcweir }
1649*cdf0e10cSrcweir 
1650*cdf0e10cSrcweir //------------------------------------------------------------------------------
1651*cdf0e10cSrcweir void FormController::impl_appendEmptyFilterRow( ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1652*cdf0e10cSrcweir {
1653*cdf0e10cSrcweir     // SYNCHRONIZED -->
1654*cdf0e10cSrcweir     impl_addFilterRow( FmFilterRow() );
1655*cdf0e10cSrcweir 
1656*cdf0e10cSrcweir     // notify the listeners
1657*cdf0e10cSrcweir     FilterEvent aEvent;
1658*cdf0e10cSrcweir     aEvent.Source = *this;
1659*cdf0e10cSrcweir     aEvent.DisjunctiveTerm = (sal_Int32)m_aFilterRows.size() - 1;
1660*cdf0e10cSrcweir     _rClearBeforeNotify.clear();
1661*cdf0e10cSrcweir     // <-- SYNCHRONIZED
1662*cdf0e10cSrcweir     m_aFilterListeners.notifyEach( &XFilterControllerListener::disjunctiveTermAdded, aEvent );
1663*cdf0e10cSrcweir }
1664*cdf0e10cSrcweir 
1665*cdf0e10cSrcweir //------------------------------------------------------------------------------
1666*cdf0e10cSrcweir sal_Bool FormController::determineLockState() const
1667*cdf0e10cSrcweir {
1668*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1669*cdf0e10cSrcweir     // a.) in filter mode we are always locked
1670*cdf0e10cSrcweir     // b.) if we have no valid model or our model (a result set) is not alive -> we're locked
1671*cdf0e10cSrcweir     // c.) if we are inserting everything is OK and we are not locked
1672*cdf0e10cSrcweir     // d.) if are not updatable or on invalid position
1673*cdf0e10cSrcweir     Reference< XResultSet >  xResultSet(m_xModelAsIndex, UNO_QUERY);
1674*cdf0e10cSrcweir     if (m_bFiltering || !xResultSet.is() || !isRowSetAlive(xResultSet))
1675*cdf0e10cSrcweir         return sal_True;
1676*cdf0e10cSrcweir     else
1677*cdf0e10cSrcweir         return (m_bCanInsert && m_bCurrentRecordNew) ? sal_False
1678*cdf0e10cSrcweir         :  xResultSet->isBeforeFirst() || xResultSet->isAfterLast() || xResultSet->rowDeleted() || !m_bCanUpdate;
1679*cdf0e10cSrcweir }
1680*cdf0e10cSrcweir 
1681*cdf0e10cSrcweir //  FocusListener
1682*cdf0e10cSrcweir //------------------------------------------------------------------------------
1683*cdf0e10cSrcweir void FormController::focusGained(const FocusEvent& e) throw( RuntimeException )
1684*cdf0e10cSrcweir {
1685*cdf0e10cSrcweir     // SYNCHRONIZED -->
1686*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
1687*cdf0e10cSrcweir     impl_checkDisposed_throw();
1688*cdf0e10cSrcweir 
1689*cdf0e10cSrcweir     m_pControlBorderManager->focusGained( e.Source );
1690*cdf0e10cSrcweir 
1691*cdf0e10cSrcweir     Reference< XControl >  xControl(e.Source, UNO_QUERY);
1692*cdf0e10cSrcweir     if (m_bDBConnection)
1693*cdf0e10cSrcweir     {
1694*cdf0e10cSrcweir         // do we need to keep the locking of the commit
1695*cdf0e10cSrcweir         // we hold the lock as long as the control differs from the current
1696*cdf0e10cSrcweir         // otherwhise we disabled the lock
1697*cdf0e10cSrcweir         m_bCommitLock = m_bCommitLock && (XControl*)xControl.get() != (XControl*)m_xCurrentControl.get();
1698*cdf0e10cSrcweir         if (m_bCommitLock)
1699*cdf0e10cSrcweir             return;
1700*cdf0e10cSrcweir 
1701*cdf0e10cSrcweir         // when do we have to commit a value to form or a filter
1702*cdf0e10cSrcweir         // a.) if the current value is modified
1703*cdf0e10cSrcweir         // b.) there must be a current control
1704*cdf0e10cSrcweir         // c.) and it must be different from the new focus owning control or
1705*cdf0e10cSrcweir         // d.) the focus is moving around (so we have only one control)
1706*cdf0e10cSrcweir 
1707*cdf0e10cSrcweir         if  (   ( m_bModified || m_bFiltering )
1708*cdf0e10cSrcweir             &&  m_xCurrentControl.is()
1709*cdf0e10cSrcweir             &&  (   ( xControl.get() != m_xCurrentControl.get() )
1710*cdf0e10cSrcweir                 ||  (   ( e.FocusFlags & FocusChangeReason::AROUND )
1711*cdf0e10cSrcweir                     &&  ( m_bCycle || m_bFiltering )
1712*cdf0e10cSrcweir                     )
1713*cdf0e10cSrcweir                 )
1714*cdf0e10cSrcweir             )
1715*cdf0e10cSrcweir         {
1716*cdf0e10cSrcweir             // check the old control if the content is ok
1717*cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
1718*cdf0e10cSrcweir 			Reference< XBoundControl >  xLockingTest(m_xCurrentControl, UNO_QUERY);
1719*cdf0e10cSrcweir 			sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
1720*cdf0e10cSrcweir 			OSL_ENSURE(!bControlIsLocked, "FormController::Gained: I'm modified and the current control is locked ? How this ?");
1721*cdf0e10cSrcweir 			// normalerweise sollte ein gelocktes Control nicht modified sein, also muss wohl mein bModified aus einem anderen Kontext
1722*cdf0e10cSrcweir 			// gesetzt worden sein, was ich nicht verstehen wuerde ...
1723*cdf0e10cSrcweir #endif
1724*cdf0e10cSrcweir 			DBG_ASSERT(m_xCurrentControl.is(), "kein CurrentControl gesetzt");
1725*cdf0e10cSrcweir 			// zunaechst das Control fragen ob es das IFace unterstuetzt
1726*cdf0e10cSrcweir 			Reference< XBoundComponent >  xBound(m_xCurrentControl, UNO_QUERY);
1727*cdf0e10cSrcweir 			if (!xBound.is() && m_xCurrentControl.is())
1728*cdf0e10cSrcweir 				xBound  = Reference< XBoundComponent > (m_xCurrentControl->getModel(), UNO_QUERY);
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir 			// lock if we lose the focus during commit
1731*cdf0e10cSrcweir 			m_bCommitLock = sal_True;
1732*cdf0e10cSrcweir 
1733*cdf0e10cSrcweir 			// Commit nicht erfolgreich, Focus zuruecksetzen
1734*cdf0e10cSrcweir 			if (xBound.is() && !xBound->commit())
1735*cdf0e10cSrcweir 			{
1736*cdf0e10cSrcweir 				// the commit failed and we don't commit again until the current control
1737*cdf0e10cSrcweir 				// which couldn't be commit gains the focus again
1738*cdf0e10cSrcweir 				Reference< XWindow >  xWindow(m_xCurrentControl, UNO_QUERY);
1739*cdf0e10cSrcweir 				if (xWindow.is())
1740*cdf0e10cSrcweir 					xWindow->setFocus();
1741*cdf0e10cSrcweir 				return;
1742*cdf0e10cSrcweir 			}
1743*cdf0e10cSrcweir 			else
1744*cdf0e10cSrcweir 			{
1745*cdf0e10cSrcweir 				m_bModified = sal_False;
1746*cdf0e10cSrcweir 				m_bCommitLock = sal_False;
1747*cdf0e10cSrcweir 			}
1748*cdf0e10cSrcweir 		}
1749*cdf0e10cSrcweir 
1750*cdf0e10cSrcweir 		if (!m_bFiltering && m_bCycle && (e.FocusFlags & FocusChangeReason::AROUND) && m_xCurrentControl.is())
1751*cdf0e10cSrcweir 		{
1752*cdf0e10cSrcweir             SQLErrorEvent aErrorEvent;
1753*cdf0e10cSrcweir             OSL_ENSURE( m_xFormOperations.is(), "FormController::focusGained: hmm?" );
1754*cdf0e10cSrcweir                 // should have been created in setModel
1755*cdf0e10cSrcweir             try
1756*cdf0e10cSrcweir             {
1757*cdf0e10cSrcweir 			    if ( e.FocusFlags & FocusChangeReason::FORWARD )
1758*cdf0e10cSrcweir 		        {
1759*cdf0e10cSrcweir                     if ( m_xFormOperations.is() && m_xFormOperations->isEnabled( FormFeature::MoveToNext ) )
1760*cdf0e10cSrcweir                         m_xFormOperations->execute( FormFeature::MoveToNext );
1761*cdf0e10cSrcweir                 }
1762*cdf0e10cSrcweir 			    else // backward
1763*cdf0e10cSrcweir                 {
1764*cdf0e10cSrcweir                     if ( m_xFormOperations.is() && m_xFormOperations->isEnabled( FormFeature::MoveToPrevious ) )
1765*cdf0e10cSrcweir                         m_xFormOperations->execute( FormFeature::MoveToPrevious );
1766*cdf0e10cSrcweir                 }
1767*cdf0e10cSrcweir             }
1768*cdf0e10cSrcweir             catch ( const Exception& )
1769*cdf0e10cSrcweir             {
1770*cdf0e10cSrcweir                 // don't handle this any further. That's an ... admissible error.
1771*cdf0e10cSrcweir                 DBG_UNHANDLED_EXCEPTION();
1772*cdf0e10cSrcweir             }
1773*cdf0e10cSrcweir 		}
1774*cdf0e10cSrcweir 	}
1775*cdf0e10cSrcweir 
1776*cdf0e10cSrcweir 	// Immer noch ein und dasselbe Control
1777*cdf0e10cSrcweir 	if	(	( m_xActiveControl == xControl )
1778*cdf0e10cSrcweir 		&&	( xControl == m_xCurrentControl )
1779*cdf0e10cSrcweir 		)
1780*cdf0e10cSrcweir 	{
1781*cdf0e10cSrcweir 		DBG_ASSERT(m_xCurrentControl.is(), "Kein CurrentControl selektiert");
1782*cdf0e10cSrcweir 		return;
1783*cdf0e10cSrcweir 	}
1784*cdf0e10cSrcweir 
1785*cdf0e10cSrcweir 	sal_Bool bActivated = !m_xActiveControl.is() && xControl.is();
1786*cdf0e10cSrcweir 
1787*cdf0e10cSrcweir 	m_xActiveControl  = xControl;
1788*cdf0e10cSrcweir 
1789*cdf0e10cSrcweir     implSetCurrentControl( xControl );
1790*cdf0e10cSrcweir 	OSL_POSTCOND( m_xCurrentControl.is(), "implSetCurrentControl did nonsense!" );
1791*cdf0e10cSrcweir 
1792*cdf0e10cSrcweir 	if ( bActivated )
1793*cdf0e10cSrcweir     {
1794*cdf0e10cSrcweir         // (asynchronously) call activation handlers
1795*cdf0e10cSrcweir         m_aActivationEvent.Call();
1796*cdf0e10cSrcweir 
1797*cdf0e10cSrcweir         // call modify listeners
1798*cdf0e10cSrcweir         if ( m_bModified )
1799*cdf0e10cSrcweir             m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *this ) );
1800*cdf0e10cSrcweir     }
1801*cdf0e10cSrcweir 
1802*cdf0e10cSrcweir     // invalidate all features which depend on the currently focused control
1803*cdf0e10cSrcweir 	if ( m_bDBConnection && !m_bFiltering )
1804*cdf0e10cSrcweir         implInvalidateCurrentControlDependentFeatures();
1805*cdf0e10cSrcweir 
1806*cdf0e10cSrcweir 	if ( !m_xCurrentControl.is() )
1807*cdf0e10cSrcweir         return;
1808*cdf0e10cSrcweir 
1809*cdf0e10cSrcweir 	// Control erhaelt Focus, dann eventuell in den sichtbaren Bereich
1810*cdf0e10cSrcweir     Reference< XFormControllerContext > xContext( m_xContext );
1811*cdf0e10cSrcweir     Reference< XControl > xCurrentControl( m_xCurrentControl );
1812*cdf0e10cSrcweir     aGuard.clear();
1813*cdf0e10cSrcweir     // <-- SYNCHRONIZED
1814*cdf0e10cSrcweir 
1815*cdf0e10cSrcweir     if ( xContext.is() )
1816*cdf0e10cSrcweir         xContext->makeVisible( xCurrentControl );
1817*cdf0e10cSrcweir }
1818*cdf0e10cSrcweir 
1819*cdf0e10cSrcweir //------------------------------------------------------------------------------
1820*cdf0e10cSrcweir IMPL_LINK( FormController, OnActivated, void*, /**/ )
1821*cdf0e10cSrcweir {
1822*cdf0e10cSrcweir     EventObject aEvent;
1823*cdf0e10cSrcweir     aEvent.Source = *this;
1824*cdf0e10cSrcweir     m_aActivateListeners.notifyEach( &XFormControllerListener::formActivated, aEvent );
1825*cdf0e10cSrcweir 
1826*cdf0e10cSrcweir     return 0L;
1827*cdf0e10cSrcweir }
1828*cdf0e10cSrcweir 
1829*cdf0e10cSrcweir //------------------------------------------------------------------------------
1830*cdf0e10cSrcweir IMPL_LINK( FormController, OnDeactivated, void*, /**/ )
1831*cdf0e10cSrcweir {
1832*cdf0e10cSrcweir     EventObject aEvent;
1833*cdf0e10cSrcweir     aEvent.Source = *this;
1834*cdf0e10cSrcweir     m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvent );
1835*cdf0e10cSrcweir 
1836*cdf0e10cSrcweir     return 0L;
1837*cdf0e10cSrcweir }
1838*cdf0e10cSrcweir 
1839*cdf0e10cSrcweir //------------------------------------------------------------------------------
1840*cdf0e10cSrcweir void FormController::focusLost(const FocusEvent& e) throw( RuntimeException )
1841*cdf0e10cSrcweir {
1842*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1843*cdf0e10cSrcweir 
1844*cdf0e10cSrcweir     m_pControlBorderManager->focusLost( e.Source );
1845*cdf0e10cSrcweir 
1846*cdf0e10cSrcweir     Reference< XControl >  xControl(e.Source, UNO_QUERY);
1847*cdf0e10cSrcweir     Reference< XWindowPeer >  xNext(e.NextFocus, UNO_QUERY);
1848*cdf0e10cSrcweir     Reference< XControl >  xNextControl = isInList(xNext);
1849*cdf0e10cSrcweir     if (!xNextControl.is())
1850*cdf0e10cSrcweir     {
1851*cdf0e10cSrcweir         m_xActiveControl = NULL;
1852*cdf0e10cSrcweir         m_aDeactivationEvent.Call();
1853*cdf0e10cSrcweir     }
1854*cdf0e10cSrcweir }
1855*cdf0e10cSrcweir 
1856*cdf0e10cSrcweir //--------------------------------------------------------------------
1857*cdf0e10cSrcweir void SAL_CALL FormController::mousePressed( const awt::MouseEvent& /*_rEvent*/ ) throw (RuntimeException)
1858*cdf0e10cSrcweir {
1859*cdf0e10cSrcweir     // not interested in
1860*cdf0e10cSrcweir }
1861*cdf0e10cSrcweir 
1862*cdf0e10cSrcweir //--------------------------------------------------------------------
1863*cdf0e10cSrcweir void SAL_CALL FormController::mouseReleased( const awt::MouseEvent& /*_rEvent*/ ) throw (RuntimeException)
1864*cdf0e10cSrcweir {
1865*cdf0e10cSrcweir     // not interested in
1866*cdf0e10cSrcweir }
1867*cdf0e10cSrcweir 
1868*cdf0e10cSrcweir //--------------------------------------------------------------------
1869*cdf0e10cSrcweir void SAL_CALL FormController::mouseEntered( const awt::MouseEvent& _rEvent ) throw (RuntimeException)
1870*cdf0e10cSrcweir {
1871*cdf0e10cSrcweir     m_pControlBorderManager->mouseEntered( _rEvent.Source );
1872*cdf0e10cSrcweir }
1873*cdf0e10cSrcweir 
1874*cdf0e10cSrcweir //--------------------------------------------------------------------
1875*cdf0e10cSrcweir void SAL_CALL FormController::mouseExited( const awt::MouseEvent& _rEvent ) throw (RuntimeException)
1876*cdf0e10cSrcweir {
1877*cdf0e10cSrcweir     m_pControlBorderManager->mouseExited( _rEvent.Source );
1878*cdf0e10cSrcweir }
1879*cdf0e10cSrcweir 
1880*cdf0e10cSrcweir //--------------------------------------------------------------------
1881*cdf0e10cSrcweir void SAL_CALL FormController::componentValidityChanged( const EventObject& _rSource ) throw (RuntimeException)
1882*cdf0e10cSrcweir {
1883*cdf0e10cSrcweir     Reference< XControl > xControl( findControl( m_aControls, Reference< XControlModel >( _rSource.Source, UNO_QUERY ), sal_False, sal_False ) );
1884*cdf0e10cSrcweir     Reference< XValidatableFormComponent > xValidatable( _rSource.Source, UNO_QUERY );
1885*cdf0e10cSrcweir 
1886*cdf0e10cSrcweir     OSL_ENSURE( xControl.is() && xValidatable.is(), "FormController::componentValidityChanged: huh?" );
1887*cdf0e10cSrcweir 
1888*cdf0e10cSrcweir     if ( xControl.is() && xValidatable.is() )
1889*cdf0e10cSrcweir         m_pControlBorderManager->validityChanged( xControl, xValidatable );
1890*cdf0e10cSrcweir }
1891*cdf0e10cSrcweir 
1892*cdf0e10cSrcweir //--------------------------------------------------------------------
1893*cdf0e10cSrcweir void FormController::setModel(const Reference< XTabControllerModel > & Model) throw( RuntimeException )
1894*cdf0e10cSrcweir {
1895*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
1896*cdf0e10cSrcweir     impl_checkDisposed_throw();
1897*cdf0e10cSrcweir 
1898*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::setModel : invalid aggregate !");
1899*cdf0e10cSrcweir 
1900*cdf0e10cSrcweir     try
1901*cdf0e10cSrcweir     {
1902*cdf0e10cSrcweir         // disconnect from the old model
1903*cdf0e10cSrcweir         if (m_xModelAsIndex.is())
1904*cdf0e10cSrcweir         {
1905*cdf0e10cSrcweir             if (m_bDBConnection)
1906*cdf0e10cSrcweir             {
1907*cdf0e10cSrcweir                 // we are currently working on the model
1908*cdf0e10cSrcweir                 EventObject aEvt(m_xModelAsIndex);
1909*cdf0e10cSrcweir                 unloaded(aEvt);
1910*cdf0e10cSrcweir             }
1911*cdf0e10cSrcweir 
1912*cdf0e10cSrcweir             Reference< XLoadable >  xForm(m_xModelAsIndex, UNO_QUERY);
1913*cdf0e10cSrcweir             if (xForm.is())
1914*cdf0e10cSrcweir                 xForm->removeLoadListener(this);
1915*cdf0e10cSrcweir 
1916*cdf0e10cSrcweir             Reference< XSQLErrorBroadcaster >  xBroadcaster(m_xModelAsIndex, UNO_QUERY);
1917*cdf0e10cSrcweir             if (xBroadcaster.is())
1918*cdf0e10cSrcweir                 xBroadcaster->removeSQLErrorListener(this);
1919*cdf0e10cSrcweir 
1920*cdf0e10cSrcweir             Reference< XDatabaseParameterBroadcaster >  xParamBroadcaster(m_xModelAsIndex, UNO_QUERY);
1921*cdf0e10cSrcweir             if (xParamBroadcaster.is())
1922*cdf0e10cSrcweir                 xParamBroadcaster->removeParameterListener(this);
1923*cdf0e10cSrcweir 
1924*cdf0e10cSrcweir         }
1925*cdf0e10cSrcweir 
1926*cdf0e10cSrcweir         disposeAllFeaturesAndDispatchers();
1927*cdf0e10cSrcweir 
1928*cdf0e10cSrcweir         if ( m_xFormOperations.is() )
1929*cdf0e10cSrcweir             m_xFormOperations->dispose();
1930*cdf0e10cSrcweir         m_xFormOperations.clear();
1931*cdf0e10cSrcweir 
1932*cdf0e10cSrcweir         // set the new model wait for the load event
1933*cdf0e10cSrcweir         if (m_xTabController.is())
1934*cdf0e10cSrcweir             m_xTabController->setModel(Model);
1935*cdf0e10cSrcweir         m_xModelAsIndex = Reference< XIndexAccess > (Model, UNO_QUERY);
1936*cdf0e10cSrcweir         m_xModelAsManager = Reference< XEventAttacherManager > (Model, UNO_QUERY);
1937*cdf0e10cSrcweir 
1938*cdf0e10cSrcweir         // only if both ifaces exit, the controller will work successful
1939*cdf0e10cSrcweir         if (!m_xModelAsIndex.is() || !m_xModelAsManager.is())
1940*cdf0e10cSrcweir         {
1941*cdf0e10cSrcweir             m_xModelAsManager = NULL;
1942*cdf0e10cSrcweir             m_xModelAsIndex = NULL;
1943*cdf0e10cSrcweir         }
1944*cdf0e10cSrcweir 
1945*cdf0e10cSrcweir         if (m_xModelAsIndex.is())
1946*cdf0e10cSrcweir         {
1947*cdf0e10cSrcweir             // re-create m_xFormOperations
1948*cdf0e10cSrcweir             m_xFormOperations.set( FormOperations::createWithFormController( m_aContext.getUNOContext(), this ), UNO_SET_THROW );
1949*cdf0e10cSrcweir             m_xFormOperations->setFeatureInvalidation( this );
1950*cdf0e10cSrcweir 
1951*cdf0e10cSrcweir             // adding load and ui interaction listeners
1952*cdf0e10cSrcweir             Reference< XLoadable >  xForm(Model, UNO_QUERY);
1953*cdf0e10cSrcweir             if (xForm.is())
1954*cdf0e10cSrcweir                 xForm->addLoadListener(this);
1955*cdf0e10cSrcweir 
1956*cdf0e10cSrcweir             Reference< XSQLErrorBroadcaster >  xBroadcaster(Model, UNO_QUERY);
1957*cdf0e10cSrcweir             if (xBroadcaster.is())
1958*cdf0e10cSrcweir                 xBroadcaster->addSQLErrorListener(this);
1959*cdf0e10cSrcweir 
1960*cdf0e10cSrcweir             Reference< XDatabaseParameterBroadcaster >  xParamBroadcaster(Model, UNO_QUERY);
1961*cdf0e10cSrcweir             if (xParamBroadcaster.is())
1962*cdf0e10cSrcweir                 xParamBroadcaster->addParameterListener(this);
1963*cdf0e10cSrcweir 
1964*cdf0e10cSrcweir             // well, is the database already loaded?
1965*cdf0e10cSrcweir             // then we have to simulate a load event
1966*cdf0e10cSrcweir             Reference< XLoadable >  xCursor(m_xModelAsIndex, UNO_QUERY);
1967*cdf0e10cSrcweir             if (xCursor.is() && xCursor->isLoaded())
1968*cdf0e10cSrcweir             {
1969*cdf0e10cSrcweir                 EventObject aEvt(xCursor);
1970*cdf0e10cSrcweir                 loaded(aEvt);
1971*cdf0e10cSrcweir             }
1972*cdf0e10cSrcweir 
1973*cdf0e10cSrcweir             Reference< XPropertySet > xModelProps( m_xModelAsIndex, UNO_QUERY );
1974*cdf0e10cSrcweir             Reference< XPropertySetInfo > xPropInfo( xModelProps->getPropertySetInfo() );
1975*cdf0e10cSrcweir             if (  xPropInfo.is()
1976*cdf0e10cSrcweir                && xPropInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER )
1977*cdf0e10cSrcweir                && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_FOCUS )
1978*cdf0e10cSrcweir                && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_MOUSE )
1979*cdf0e10cSrcweir                && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_INVALID )
1980*cdf0e10cSrcweir                )
1981*cdf0e10cSrcweir             {
1982*cdf0e10cSrcweir                 bool bEnableDynamicControlBorder = lcl_shouldUseDynamicControlBorder(
1983*cdf0e10cSrcweir                     xModelProps.get(), xModelProps->getPropertyValue( FM_PROP_DYNAMIC_CONTROL_BORDER ) );
1984*cdf0e10cSrcweir                 if ( bEnableDynamicControlBorder )
1985*cdf0e10cSrcweir                     m_pControlBorderManager->enableDynamicBorderColor();
1986*cdf0e10cSrcweir                 else
1987*cdf0e10cSrcweir                     m_pControlBorderManager->disableDynamicBorderColor();
1988*cdf0e10cSrcweir 
1989*cdf0e10cSrcweir                 sal_Int32 nColor = 0;
1990*cdf0e10cSrcweir                 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_FOCUS ) >>= nColor )
1991*cdf0e10cSrcweir                     m_pControlBorderManager->setStatusColor( CONTROL_STATUS_FOCUSED, nColor );
1992*cdf0e10cSrcweir                 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_MOUSE ) >>= nColor )
1993*cdf0e10cSrcweir                     m_pControlBorderManager->setStatusColor( CONTROL_STATUS_MOUSE_HOVER, nColor );
1994*cdf0e10cSrcweir                 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_INVALID ) >>= nColor )
1995*cdf0e10cSrcweir                     m_pControlBorderManager->setStatusColor( CONTROL_STATUS_INVALID, nColor );
1996*cdf0e10cSrcweir             }
1997*cdf0e10cSrcweir         }
1998*cdf0e10cSrcweir     }
1999*cdf0e10cSrcweir     catch( const Exception& )
2000*cdf0e10cSrcweir     {
2001*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
2002*cdf0e10cSrcweir     }
2003*cdf0e10cSrcweir }
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir //------------------------------------------------------------------------------
2006*cdf0e10cSrcweir Reference< XTabControllerModel >  FormController::getModel() throw( RuntimeException )
2007*cdf0e10cSrcweir {
2008*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2009*cdf0e10cSrcweir     impl_checkDisposed_throw();
2010*cdf0e10cSrcweir 
2011*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::getModel : invalid aggregate !");
2012*cdf0e10cSrcweir     if (!m_xTabController.is())
2013*cdf0e10cSrcweir         return Reference< XTabControllerModel > ();
2014*cdf0e10cSrcweir     return m_xTabController->getModel();
2015*cdf0e10cSrcweir }
2016*cdf0e10cSrcweir 
2017*cdf0e10cSrcweir //------------------------------------------------------------------------------
2018*cdf0e10cSrcweir void FormController::addToEventAttacher(const Reference< XControl > & xControl)
2019*cdf0e10cSrcweir {
2020*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2021*cdf0e10cSrcweir     OSL_ENSURE( xControl.is(), "FormController::addToEventAttacher: invalid control - how did you reach this?" );
2022*cdf0e10cSrcweir     if ( !xControl.is() )
2023*cdf0e10cSrcweir         return; /* throw IllegalArgumentException(); */
2024*cdf0e10cSrcweir 
2025*cdf0e10cSrcweir     // anmelden beim Eventattacher
2026*cdf0e10cSrcweir     Reference< XFormComponent >  xComp(xControl->getModel(), UNO_QUERY);
2027*cdf0e10cSrcweir     if (xComp.is() && m_xModelAsIndex.is())
2028*cdf0e10cSrcweir     {
2029*cdf0e10cSrcweir         // Und die Position des ControlModel darin suchen
2030*cdf0e10cSrcweir         sal_uInt32 nPos = m_xModelAsIndex->getCount();
2031*cdf0e10cSrcweir         Reference< XFormComponent > xTemp;
2032*cdf0e10cSrcweir         for( ; nPos; )
2033*cdf0e10cSrcweir         {
2034*cdf0e10cSrcweir             m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
2035*cdf0e10cSrcweir             if ((XFormComponent*)xComp.get() == (XFormComponent*)xTemp.get())
2036*cdf0e10cSrcweir             {
2037*cdf0e10cSrcweir                 Reference< XInterface >  xIfc(xControl, UNO_QUERY);
2038*cdf0e10cSrcweir                 m_xModelAsManager->attach( nPos, xIfc, makeAny(xControl) );
2039*cdf0e10cSrcweir                 break;
2040*cdf0e10cSrcweir             }
2041*cdf0e10cSrcweir         }
2042*cdf0e10cSrcweir     }
2043*cdf0e10cSrcweir }
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir //------------------------------------------------------------------------------
2046*cdf0e10cSrcweir void FormController::removeFromEventAttacher(const Reference< XControl > & xControl)
2047*cdf0e10cSrcweir {
2048*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2049*cdf0e10cSrcweir     OSL_ENSURE( xControl.is(), "FormController::removeFromEventAttacher: invalid control - how did you reach this?" );
2050*cdf0e10cSrcweir     if ( !xControl.is() )
2051*cdf0e10cSrcweir         return; /* throw IllegalArgumentException(); */
2052*cdf0e10cSrcweir 
2053*cdf0e10cSrcweir     // abmelden beim Eventattacher
2054*cdf0e10cSrcweir     Reference< XFormComponent >  xComp(xControl->getModel(), UNO_QUERY);
2055*cdf0e10cSrcweir     if ( xComp.is() && m_xModelAsIndex.is() )
2056*cdf0e10cSrcweir     {
2057*cdf0e10cSrcweir         // Und die Position des ControlModel darin suchen
2058*cdf0e10cSrcweir         sal_uInt32 nPos = m_xModelAsIndex->getCount();
2059*cdf0e10cSrcweir         Reference< XFormComponent > xTemp;
2060*cdf0e10cSrcweir         for( ; nPos; )
2061*cdf0e10cSrcweir         {
2062*cdf0e10cSrcweir             m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
2063*cdf0e10cSrcweir             if ((XFormComponent*)xComp.get() == (XFormComponent*)xTemp.get())
2064*cdf0e10cSrcweir             {
2065*cdf0e10cSrcweir                 Reference< XInterface >  xIfc(xControl, UNO_QUERY);
2066*cdf0e10cSrcweir                 m_xModelAsManager->detach( nPos, xIfc );
2067*cdf0e10cSrcweir                 break;
2068*cdf0e10cSrcweir             }
2069*cdf0e10cSrcweir         }
2070*cdf0e10cSrcweir     }
2071*cdf0e10cSrcweir }
2072*cdf0e10cSrcweir 
2073*cdf0e10cSrcweir //------------------------------------------------------------------------------
2074*cdf0e10cSrcweir void FormController::setContainer(const Reference< XControlContainer > & xContainer) throw( RuntimeException )
2075*cdf0e10cSrcweir {
2076*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2077*cdf0e10cSrcweir     Reference< XTabControllerModel >  xTabModel(getModel());
2078*cdf0e10cSrcweir     DBG_ASSERT(xTabModel.is() || !xContainer.is(), "No Model defined");
2079*cdf0e10cSrcweir         // if we have a new container we need a model
2080*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::setContainer : invalid aggregate !");
2081*cdf0e10cSrcweir 
2082*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2083*cdf0e10cSrcweir     Reference< XContainer >  xCurrentContainer;
2084*cdf0e10cSrcweir     if (m_xTabController.is())
2085*cdf0e10cSrcweir         xCurrentContainer = Reference< XContainer > (m_xTabController->getContainer(), UNO_QUERY);
2086*cdf0e10cSrcweir     if (xCurrentContainer.is())
2087*cdf0e10cSrcweir     {
2088*cdf0e10cSrcweir         xCurrentContainer->removeContainerListener(this);
2089*cdf0e10cSrcweir 
2090*cdf0e10cSrcweir         if ( m_aTabActivationTimer.IsActive() )
2091*cdf0e10cSrcweir             m_aTabActivationTimer.Stop();
2092*cdf0e10cSrcweir 
2093*cdf0e10cSrcweir         // clear the filter map
2094*cdf0e10cSrcweir         ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), RemoveComponentTextListener( this ) );
2095*cdf0e10cSrcweir         m_aFilterComponents.clear();
2096*cdf0e10cSrcweir 
2097*cdf0e10cSrcweir         // einsammeln der Controls
2098*cdf0e10cSrcweir         const Reference< XControl >* pControls = m_aControls.getConstArray();
2099*cdf0e10cSrcweir         const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2100*cdf0e10cSrcweir         while ( pControls != pControlsEnd )
2101*cdf0e10cSrcweir             implControlRemoved( *pControls++, true );
2102*cdf0e10cSrcweir 
2103*cdf0e10cSrcweir         // Datenbank spezifische Dinge vornehmen
2104*cdf0e10cSrcweir         if (m_bDBConnection && isListeningForChanges())
2105*cdf0e10cSrcweir             stopListening();
2106*cdf0e10cSrcweir 
2107*cdf0e10cSrcweir         m_aControls.realloc( 0 );
2108*cdf0e10cSrcweir     }
2109*cdf0e10cSrcweir 
2110*cdf0e10cSrcweir     if (m_xTabController.is())
2111*cdf0e10cSrcweir         m_xTabController->setContainer(xContainer);
2112*cdf0e10cSrcweir 
2113*cdf0e10cSrcweir     // Welche Controls gehoeren zum Container ?
2114*cdf0e10cSrcweir     if (xContainer.is() && xTabModel.is())
2115*cdf0e10cSrcweir     {
2116*cdf0e10cSrcweir         Sequence< Reference< XControlModel > > aModels = xTabModel->getControlModels();
2117*cdf0e10cSrcweir         const Reference< XControlModel > * pModels = aModels.getConstArray();
2118*cdf0e10cSrcweir         Sequence< Reference< XControl > > aAllControls = xContainer->getControls();
2119*cdf0e10cSrcweir 
2120*cdf0e10cSrcweir         sal_Int32 nCount = aModels.getLength();
2121*cdf0e10cSrcweir         m_aControls = Sequence< Reference< XControl > >( nCount );
2122*cdf0e10cSrcweir         Reference< XControl > * pControls = m_aControls.getArray();
2123*cdf0e10cSrcweir 
2124*cdf0e10cSrcweir         // einsammeln der Controls
2125*cdf0e10cSrcweir         sal_Int32 i, j;
2126*cdf0e10cSrcweir         for (i = 0, j = 0; i < nCount; ++i, ++pModels )
2127*cdf0e10cSrcweir         {
2128*cdf0e10cSrcweir             Reference< XControl > xControl = findControl( aAllControls, *pModels, sal_False, sal_True );
2129*cdf0e10cSrcweir             if ( xControl.is() )
2130*cdf0e10cSrcweir             {
2131*cdf0e10cSrcweir                 pControls[j++] = xControl;
2132*cdf0e10cSrcweir                 implControlInserted( xControl, true );
2133*cdf0e10cSrcweir             }
2134*cdf0e10cSrcweir         }
2135*cdf0e10cSrcweir 
2136*cdf0e10cSrcweir         // not every model had an associated control
2137*cdf0e10cSrcweir         if (j != i)
2138*cdf0e10cSrcweir             m_aControls.realloc(j);
2139*cdf0e10cSrcweir 
2140*cdf0e10cSrcweir         // am Container horchen
2141*cdf0e10cSrcweir         Reference< XContainer >  xNewContainer(xContainer, UNO_QUERY);
2142*cdf0e10cSrcweir         if (xNewContainer.is())
2143*cdf0e10cSrcweir             xNewContainer->addContainerListener(this);
2144*cdf0e10cSrcweir 
2145*cdf0e10cSrcweir         // Datenbank spezifische Dinge vornehmen
2146*cdf0e10cSrcweir         if (m_bDBConnection)
2147*cdf0e10cSrcweir         {
2148*cdf0e10cSrcweir             m_bLocked = determineLockState();
2149*cdf0e10cSrcweir             setLocks();
2150*cdf0e10cSrcweir             if (!isLocked())
2151*cdf0e10cSrcweir                 startListening();
2152*cdf0e10cSrcweir         }
2153*cdf0e10cSrcweir     }
2154*cdf0e10cSrcweir     // befinden sich die Controls in der richtigen Reihenfolge
2155*cdf0e10cSrcweir     m_bControlsSorted = sal_True;
2156*cdf0e10cSrcweir }
2157*cdf0e10cSrcweir 
2158*cdf0e10cSrcweir //------------------------------------------------------------------------------
2159*cdf0e10cSrcweir Reference< XControlContainer >  FormController::getContainer() throw( RuntimeException )
2160*cdf0e10cSrcweir {
2161*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
2162*cdf0e10cSrcweir     impl_checkDisposed_throw();
2163*cdf0e10cSrcweir 
2164*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::getContainer : invalid aggregate !");
2165*cdf0e10cSrcweir     if (!m_xTabController.is())
2166*cdf0e10cSrcweir         return Reference< XControlContainer > ();
2167*cdf0e10cSrcweir     return m_xTabController->getContainer();
2168*cdf0e10cSrcweir }
2169*cdf0e10cSrcweir 
2170*cdf0e10cSrcweir //------------------------------------------------------------------------------
2171*cdf0e10cSrcweir Sequence< Reference< XControl > > FormController::getControls(void) throw( RuntimeException )
2172*cdf0e10cSrcweir {
2173*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2174*cdf0e10cSrcweir     impl_checkDisposed_throw();
2175*cdf0e10cSrcweir 
2176*cdf0e10cSrcweir     if (!m_bControlsSorted)
2177*cdf0e10cSrcweir     {
2178*cdf0e10cSrcweir         Reference< XTabControllerModel >  xModel = getModel();
2179*cdf0e10cSrcweir         if (!xModel.is())
2180*cdf0e10cSrcweir             return m_aControls;
2181*cdf0e10cSrcweir 
2182*cdf0e10cSrcweir         Sequence< Reference< XControlModel > > aControlModels = xModel->getControlModels();
2183*cdf0e10cSrcweir         const Reference< XControlModel > * pModels = aControlModels.getConstArray();
2184*cdf0e10cSrcweir         sal_Int32 nModels = aControlModels.getLength();
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir         Sequence< Reference< XControl > > aNewControls(nModels);
2187*cdf0e10cSrcweir 
2188*cdf0e10cSrcweir         Reference< XControl > * pControls = aNewControls.getArray();
2189*cdf0e10cSrcweir         Reference< XControl >  xControl;
2190*cdf0e10cSrcweir 
2191*cdf0e10cSrcweir         // Umsortieren der Controls entsprechend der TabReihenfolge
2192*cdf0e10cSrcweir 	    sal_Int32 j = 0;
2193*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < nModels; ++i, ++pModels )
2194*cdf0e10cSrcweir         {
2195*cdf0e10cSrcweir             xControl = findControl( m_aControls, *pModels, sal_True, sal_True );
2196*cdf0e10cSrcweir             if ( xControl.is() )
2197*cdf0e10cSrcweir                 pControls[j++] = xControl;
2198*cdf0e10cSrcweir         }
2199*cdf0e10cSrcweir 
2200*cdf0e10cSrcweir         // not every model had an associated control
2201*cdf0e10cSrcweir         if ( j != nModels )
2202*cdf0e10cSrcweir             aNewControls.realloc( j );
2203*cdf0e10cSrcweir 
2204*cdf0e10cSrcweir         m_aControls = aNewControls;
2205*cdf0e10cSrcweir         m_bControlsSorted = sal_True;
2206*cdf0e10cSrcweir     }
2207*cdf0e10cSrcweir     return m_aControls;
2208*cdf0e10cSrcweir }
2209*cdf0e10cSrcweir 
2210*cdf0e10cSrcweir //------------------------------------------------------------------------------
2211*cdf0e10cSrcweir void FormController::autoTabOrder() throw( RuntimeException )
2212*cdf0e10cSrcweir {
2213*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2214*cdf0e10cSrcweir     impl_checkDisposed_throw();
2215*cdf0e10cSrcweir 
2216*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::autoTabOrder : invalid aggregate !");
2217*cdf0e10cSrcweir     if (m_xTabController.is())
2218*cdf0e10cSrcweir         m_xTabController->autoTabOrder();
2219*cdf0e10cSrcweir }
2220*cdf0e10cSrcweir 
2221*cdf0e10cSrcweir //------------------------------------------------------------------------------
2222*cdf0e10cSrcweir void FormController::activateTabOrder() throw( RuntimeException )
2223*cdf0e10cSrcweir {
2224*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2225*cdf0e10cSrcweir     impl_checkDisposed_throw();
2226*cdf0e10cSrcweir 
2227*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::activateTabOrder : invalid aggregate !");
2228*cdf0e10cSrcweir     if (m_xTabController.is())
2229*cdf0e10cSrcweir         m_xTabController->activateTabOrder();
2230*cdf0e10cSrcweir }
2231*cdf0e10cSrcweir 
2232*cdf0e10cSrcweir //------------------------------------------------------------------------------
2233*cdf0e10cSrcweir void FormController::setControlLock(const Reference< XControl > & xControl)
2234*cdf0e10cSrcweir {
2235*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2236*cdf0e10cSrcweir     sal_Bool bLocked = isLocked();
2237*cdf0e10cSrcweir 
2238*cdf0e10cSrcweir     // es wird gelockt
2239*cdf0e10cSrcweir     // a.) wenn der ganze Datensatz gesperrt ist
2240*cdf0e10cSrcweir     // b.) wenn das zugehoerige Feld gespeert ist
2241*cdf0e10cSrcweir     Reference< XBoundControl >  xBound(xControl, UNO_QUERY);
2242*cdf0e10cSrcweir     if (xBound.is() && (( (bLocked && bLocked != xBound->getLock()) ||
2243*cdf0e10cSrcweir                          !bLocked)))    // beim entlocken immer einzelne Felder ueberpr�fen
2244*cdf0e10cSrcweir     {
2245*cdf0e10cSrcweir         // gibt es eine Datenquelle
2246*cdf0e10cSrcweir         Reference< XPropertySet >  xSet(xControl->getModel(), UNO_QUERY);
2247*cdf0e10cSrcweir         if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2248*cdf0e10cSrcweir         {
2249*cdf0e10cSrcweir             // wie sieht mit den Properties ReadOnly und Enable aus
2250*cdf0e10cSrcweir             sal_Bool bTouch = sal_True;
2251*cdf0e10cSrcweir             if (::comphelper::hasProperty(FM_PROP_ENABLED, xSet))
2252*cdf0e10cSrcweir                 bTouch = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ENABLED));
2253*cdf0e10cSrcweir             if (::comphelper::hasProperty(FM_PROP_READONLY, xSet))
2254*cdf0e10cSrcweir                 bTouch = !::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_READONLY));
2255*cdf0e10cSrcweir 
2256*cdf0e10cSrcweir             if (bTouch)
2257*cdf0e10cSrcweir             {
2258*cdf0e10cSrcweir                 Reference< XPropertySet >  xField;
2259*cdf0e10cSrcweir                 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2260*cdf0e10cSrcweir                 if (xField.is())
2261*cdf0e10cSrcweir                 {
2262*cdf0e10cSrcweir                     if (bLocked)
2263*cdf0e10cSrcweir                         xBound->setLock(bLocked);
2264*cdf0e10cSrcweir                     else
2265*cdf0e10cSrcweir                     {
2266*cdf0e10cSrcweir                         try
2267*cdf0e10cSrcweir                         {
2268*cdf0e10cSrcweir                             Any aVal = xField->getPropertyValue(FM_PROP_ISREADONLY);
2269*cdf0e10cSrcweir                             if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2270*cdf0e10cSrcweir                                 xBound->setLock(sal_True);
2271*cdf0e10cSrcweir                             else
2272*cdf0e10cSrcweir                                 xBound->setLock(bLocked);
2273*cdf0e10cSrcweir                         }
2274*cdf0e10cSrcweir                         catch( const Exception& )
2275*cdf0e10cSrcweir                         {
2276*cdf0e10cSrcweir                             DBG_UNHANDLED_EXCEPTION();
2277*cdf0e10cSrcweir                         }
2278*cdf0e10cSrcweir 
2279*cdf0e10cSrcweir                     }
2280*cdf0e10cSrcweir                 }
2281*cdf0e10cSrcweir             }
2282*cdf0e10cSrcweir         }
2283*cdf0e10cSrcweir     }
2284*cdf0e10cSrcweir }
2285*cdf0e10cSrcweir 
2286*cdf0e10cSrcweir //------------------------------------------------------------------------------
2287*cdf0e10cSrcweir void FormController::setLocks()
2288*cdf0e10cSrcweir {
2289*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2290*cdf0e10cSrcweir     // alle Controls, die mit einer Datenquelle verbunden sind locken/unlocken
2291*cdf0e10cSrcweir     const Reference< XControl >* pControls = m_aControls.getConstArray();
2292*cdf0e10cSrcweir     const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2293*cdf0e10cSrcweir     while ( pControls != pControlsEnd )
2294*cdf0e10cSrcweir         setControlLock( *pControls++ );
2295*cdf0e10cSrcweir }
2296*cdf0e10cSrcweir 
2297*cdf0e10cSrcweir //------------------------------------------------------------------------------
2298*cdf0e10cSrcweir namespace
2299*cdf0e10cSrcweir {
2300*cdf0e10cSrcweir     bool lcl_shouldListenForModifications( const Reference< XControl >& _rxControl, const Reference< XPropertyChangeListener >& _rxBoundFieldListener )
2301*cdf0e10cSrcweir     {
2302*cdf0e10cSrcweir         bool bShould = false;
2303*cdf0e10cSrcweir 
2304*cdf0e10cSrcweir         Reference< XBoundComponent > xBound( _rxControl, UNO_QUERY );
2305*cdf0e10cSrcweir         if ( xBound.is() )
2306*cdf0e10cSrcweir         {
2307*cdf0e10cSrcweir             bShould = true;
2308*cdf0e10cSrcweir         }
2309*cdf0e10cSrcweir         else if ( _rxControl.is() )
2310*cdf0e10cSrcweir         {
2311*cdf0e10cSrcweir             Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
2312*cdf0e10cSrcweir             if ( xModelProps.is() && ::comphelper::hasProperty( FM_PROP_BOUNDFIELD, xModelProps ) )
2313*cdf0e10cSrcweir             {
2314*cdf0e10cSrcweir                 Reference< XPropertySet > xField;
2315*cdf0e10cSrcweir                 xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
2316*cdf0e10cSrcweir                 bShould = xField.is();
2317*cdf0e10cSrcweir 
2318*cdf0e10cSrcweir                 if ( !bShould && _rxBoundFieldListener.is() )
2319*cdf0e10cSrcweir 				    xModelProps->addPropertyChangeListener( FM_PROP_BOUNDFIELD, _rxBoundFieldListener );
2320*cdf0e10cSrcweir             }
2321*cdf0e10cSrcweir         }
2322*cdf0e10cSrcweir 
2323*cdf0e10cSrcweir         return bShould;
2324*cdf0e10cSrcweir     }
2325*cdf0e10cSrcweir }
2326*cdf0e10cSrcweir 
2327*cdf0e10cSrcweir //------------------------------------------------------------------------------
2328*cdf0e10cSrcweir void FormController::startControlModifyListening(const Reference< XControl > & xControl)
2329*cdf0e10cSrcweir {
2330*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2331*cdf0e10cSrcweir 
2332*cdf0e10cSrcweir     bool bModifyListening = lcl_shouldListenForModifications( xControl, this );
2333*cdf0e10cSrcweir 
2334*cdf0e10cSrcweir     // artificial while
2335*cdf0e10cSrcweir     while ( bModifyListening )
2336*cdf0e10cSrcweir     {
2337*cdf0e10cSrcweir         Reference< XModifyBroadcaster >  xMod(xControl, UNO_QUERY);
2338*cdf0e10cSrcweir         if (xMod.is())
2339*cdf0e10cSrcweir         {
2340*cdf0e10cSrcweir             xMod->addModifyListener(this);
2341*cdf0e10cSrcweir             break;
2342*cdf0e10cSrcweir         }
2343*cdf0e10cSrcweir 
2344*cdf0e10cSrcweir         // alle die Text um vorzeitig ein modified zu erkennen
2345*cdf0e10cSrcweir         Reference< XTextComponent >  xText(xControl, UNO_QUERY);
2346*cdf0e10cSrcweir         if (xText.is())
2347*cdf0e10cSrcweir         {
2348*cdf0e10cSrcweir             xText->addTextListener(this);
2349*cdf0e10cSrcweir             break;
2350*cdf0e10cSrcweir         }
2351*cdf0e10cSrcweir 
2352*cdf0e10cSrcweir         Reference< XCheckBox >  xBox(xControl, UNO_QUERY);
2353*cdf0e10cSrcweir         if (xBox.is())
2354*cdf0e10cSrcweir         {
2355*cdf0e10cSrcweir             xBox->addItemListener(this);
2356*cdf0e10cSrcweir             break;
2357*cdf0e10cSrcweir         }
2358*cdf0e10cSrcweir 
2359*cdf0e10cSrcweir         Reference< XComboBox >  xCbBox(xControl, UNO_QUERY);
2360*cdf0e10cSrcweir         if (xCbBox.is())
2361*cdf0e10cSrcweir         {
2362*cdf0e10cSrcweir             xCbBox->addItemListener(this);
2363*cdf0e10cSrcweir             break;
2364*cdf0e10cSrcweir         }
2365*cdf0e10cSrcweir 
2366*cdf0e10cSrcweir         Reference< XListBox >  xListBox(xControl, UNO_QUERY);
2367*cdf0e10cSrcweir         if (xListBox.is())
2368*cdf0e10cSrcweir         {
2369*cdf0e10cSrcweir             xListBox->addItemListener(this);
2370*cdf0e10cSrcweir             break;
2371*cdf0e10cSrcweir         }
2372*cdf0e10cSrcweir         break;
2373*cdf0e10cSrcweir     }
2374*cdf0e10cSrcweir }
2375*cdf0e10cSrcweir 
2376*cdf0e10cSrcweir //------------------------------------------------------------------------------
2377*cdf0e10cSrcweir void FormController::stopControlModifyListening(const Reference< XControl > & xControl)
2378*cdf0e10cSrcweir {
2379*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2380*cdf0e10cSrcweir 
2381*cdf0e10cSrcweir     bool bModifyListening = lcl_shouldListenForModifications( xControl, NULL );
2382*cdf0e10cSrcweir 
2383*cdf0e10cSrcweir     // kuenstliches while
2384*cdf0e10cSrcweir     while (bModifyListening)
2385*cdf0e10cSrcweir     {
2386*cdf0e10cSrcweir         Reference< XModifyBroadcaster >  xMod(xControl, UNO_QUERY);
2387*cdf0e10cSrcweir         if (xMod.is())
2388*cdf0e10cSrcweir         {
2389*cdf0e10cSrcweir             xMod->removeModifyListener(this);
2390*cdf0e10cSrcweir             break;
2391*cdf0e10cSrcweir         }
2392*cdf0e10cSrcweir         // alle die Text um vorzeitig ein modified zu erkennen
2393*cdf0e10cSrcweir         Reference< XTextComponent >  xText(xControl, UNO_QUERY);
2394*cdf0e10cSrcweir         if (xText.is())
2395*cdf0e10cSrcweir         {
2396*cdf0e10cSrcweir             xText->removeTextListener(this);
2397*cdf0e10cSrcweir             break;
2398*cdf0e10cSrcweir         }
2399*cdf0e10cSrcweir 
2400*cdf0e10cSrcweir         Reference< XCheckBox >  xBox(xControl, UNO_QUERY);
2401*cdf0e10cSrcweir         if (xBox.is())
2402*cdf0e10cSrcweir         {
2403*cdf0e10cSrcweir             xBox->removeItemListener(this);
2404*cdf0e10cSrcweir             break;
2405*cdf0e10cSrcweir         }
2406*cdf0e10cSrcweir 
2407*cdf0e10cSrcweir         Reference< XComboBox >  xCbBox(xControl, UNO_QUERY);
2408*cdf0e10cSrcweir         if (xCbBox.is())
2409*cdf0e10cSrcweir         {
2410*cdf0e10cSrcweir             xCbBox->removeItemListener(this);
2411*cdf0e10cSrcweir             break;
2412*cdf0e10cSrcweir         }
2413*cdf0e10cSrcweir 
2414*cdf0e10cSrcweir         Reference< XListBox >  xListBox(xControl, UNO_QUERY);
2415*cdf0e10cSrcweir         if (xListBox.is())
2416*cdf0e10cSrcweir         {
2417*cdf0e10cSrcweir             xListBox->removeItemListener(this);
2418*cdf0e10cSrcweir             break;
2419*cdf0e10cSrcweir         }
2420*cdf0e10cSrcweir         break;
2421*cdf0e10cSrcweir     }
2422*cdf0e10cSrcweir }
2423*cdf0e10cSrcweir 
2424*cdf0e10cSrcweir //------------------------------------------------------------------------------
2425*cdf0e10cSrcweir void FormController::startListening()
2426*cdf0e10cSrcweir {
2427*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2428*cdf0e10cSrcweir     m_bModified  = sal_False;
2429*cdf0e10cSrcweir 
2430*cdf0e10cSrcweir     // jetzt anmelden bei gebundenen feldern
2431*cdf0e10cSrcweir     const Reference< XControl >* pControls = m_aControls.getConstArray();
2432*cdf0e10cSrcweir     const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2433*cdf0e10cSrcweir     while ( pControls != pControlsEnd )
2434*cdf0e10cSrcweir         startControlModifyListening( *pControls++ );
2435*cdf0e10cSrcweir }
2436*cdf0e10cSrcweir 
2437*cdf0e10cSrcweir //------------------------------------------------------------------------------
2438*cdf0e10cSrcweir void FormController::stopListening()
2439*cdf0e10cSrcweir {
2440*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2441*cdf0e10cSrcweir     m_bModified  = sal_False;
2442*cdf0e10cSrcweir 
2443*cdf0e10cSrcweir     // jetzt anmelden bei gebundenen feldern
2444*cdf0e10cSrcweir     const Reference< XControl >* pControls = m_aControls.getConstArray();
2445*cdf0e10cSrcweir     const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2446*cdf0e10cSrcweir     while ( pControls != pControlsEnd )
2447*cdf0e10cSrcweir         stopControlModifyListening( *pControls++ );
2448*cdf0e10cSrcweir }
2449*cdf0e10cSrcweir 
2450*cdf0e10cSrcweir 
2451*cdf0e10cSrcweir //------------------------------------------------------------------------------
2452*cdf0e10cSrcweir Reference< XControl >  FormController::findControl(Sequence< Reference< XControl > >& _rControls, const Reference< XControlModel > & xCtrlModel ,sal_Bool _bRemove,sal_Bool _bOverWrite) const
2453*cdf0e10cSrcweir {
2454*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2455*cdf0e10cSrcweir     DBG_ASSERT( xCtrlModel.is(), "findControl - welches ?!" );
2456*cdf0e10cSrcweir 
2457*cdf0e10cSrcweir     Reference< XControl >* pControls = _rControls.getArray();
2458*cdf0e10cSrcweir     Reference< XControlModel >  xModel;
2459*cdf0e10cSrcweir     for ( sal_Int32 i = 0, nCount = _rControls.getLength(); i < nCount; ++i, ++pControls )
2460*cdf0e10cSrcweir     {
2461*cdf0e10cSrcweir         if ( pControls->is() )
2462*cdf0e10cSrcweir         {
2463*cdf0e10cSrcweir             xModel = (*pControls)->getModel();
2464*cdf0e10cSrcweir             if ( xModel.get() == xCtrlModel.get() )
2465*cdf0e10cSrcweir             {
2466*cdf0e10cSrcweir                 Reference< XControl > xControl( *pControls );
2467*cdf0e10cSrcweir 				if ( _bRemove )
2468*cdf0e10cSrcweir 					::comphelper::removeElementAt( _rControls, i );
2469*cdf0e10cSrcweir 				else if ( _bOverWrite )
2470*cdf0e10cSrcweir 					*pControls = Reference< XControl >();
2471*cdf0e10cSrcweir                 return xControl;
2472*cdf0e10cSrcweir             }
2473*cdf0e10cSrcweir         }
2474*cdf0e10cSrcweir     }
2475*cdf0e10cSrcweir     return Reference< XControl > ();
2476*cdf0e10cSrcweir }
2477*cdf0e10cSrcweir 
2478*cdf0e10cSrcweir //------------------------------------------------------------------------------
2479*cdf0e10cSrcweir void FormController::implControlInserted( const Reference< XControl>& _rxControl, bool _bAddToEventAttacher )
2480*cdf0e10cSrcweir {
2481*cdf0e10cSrcweir     Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2482*cdf0e10cSrcweir     if ( xWindow.is() )
2483*cdf0e10cSrcweir     {
2484*cdf0e10cSrcweir         xWindow->addFocusListener( this );
2485*cdf0e10cSrcweir         xWindow->addMouseListener( this );
2486*cdf0e10cSrcweir 
2487*cdf0e10cSrcweir         if ( _bAddToEventAttacher )
2488*cdf0e10cSrcweir             addToEventAttacher( _rxControl );
2489*cdf0e10cSrcweir     }
2490*cdf0e10cSrcweir 
2491*cdf0e10cSrcweir     // add a dispatch interceptor to the control (if supported)
2492*cdf0e10cSrcweir     Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY );
2493*cdf0e10cSrcweir     if ( xInterception.is() )
2494*cdf0e10cSrcweir         createInterceptor( xInterception );
2495*cdf0e10cSrcweir 
2496*cdf0e10cSrcweir     if ( _rxControl.is() )
2497*cdf0e10cSrcweir     {
2498*cdf0e10cSrcweir         Reference< XControlModel > xModel( _rxControl->getModel() );
2499*cdf0e10cSrcweir 
2500*cdf0e10cSrcweir         // we want to know about the reset of the the model of our controls
2501*cdf0e10cSrcweir         // (for correctly resetting m_bModified)
2502*cdf0e10cSrcweir         Reference< XReset >  xReset( xModel, UNO_QUERY );
2503*cdf0e10cSrcweir 		if ( xReset.is() )
2504*cdf0e10cSrcweir 			xReset->addResetListener( this );
2505*cdf0e10cSrcweir 
2506*cdf0e10cSrcweir         // and we want to know about the validity, to visually indicate it
2507*cdf0e10cSrcweir         Reference< XValidatableFormComponent > xValidatable( xModel, UNO_QUERY );
2508*cdf0e10cSrcweir         if ( xValidatable.is() )
2509*cdf0e10cSrcweir         {
2510*cdf0e10cSrcweir             xValidatable->addFormComponentValidityListener( this );
2511*cdf0e10cSrcweir             m_pControlBorderManager->validityChanged( _rxControl, xValidatable );
2512*cdf0e10cSrcweir         }
2513*cdf0e10cSrcweir     }
2514*cdf0e10cSrcweir 
2515*cdf0e10cSrcweir }
2516*cdf0e10cSrcweir 
2517*cdf0e10cSrcweir //------------------------------------------------------------------------------
2518*cdf0e10cSrcweir void FormController::implControlRemoved( const Reference< XControl>& _rxControl, bool _bRemoveFromEventAttacher )
2519*cdf0e10cSrcweir {
2520*cdf0e10cSrcweir 	Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2521*cdf0e10cSrcweir 	if ( xWindow.is() )
2522*cdf0e10cSrcweir 	{
2523*cdf0e10cSrcweir         xWindow->removeFocusListener( this );
2524*cdf0e10cSrcweir         xWindow->removeMouseListener( this );
2525*cdf0e10cSrcweir 
2526*cdf0e10cSrcweir         if ( _bRemoveFromEventAttacher )
2527*cdf0e10cSrcweir 			removeFromEventAttacher( _rxControl );
2528*cdf0e10cSrcweir 	}
2529*cdf0e10cSrcweir 
2530*cdf0e10cSrcweir 	Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY);
2531*cdf0e10cSrcweir 	if ( xInterception.is() )
2532*cdf0e10cSrcweir 		deleteInterceptor( xInterception );
2533*cdf0e10cSrcweir 
2534*cdf0e10cSrcweir 	if ( _rxControl.is() )
2535*cdf0e10cSrcweir 	{
2536*cdf0e10cSrcweir         Reference< XControlModel > xModel( _rxControl->getModel() );
2537*cdf0e10cSrcweir 
2538*cdf0e10cSrcweir         Reference< XReset >  xReset( xModel, UNO_QUERY );
2539*cdf0e10cSrcweir 		if ( xReset.is() )
2540*cdf0e10cSrcweir 			xReset->removeResetListener( this );
2541*cdf0e10cSrcweir 
2542*cdf0e10cSrcweir         Reference< XValidatableFormComponent > xValidatable( xModel, UNO_QUERY );
2543*cdf0e10cSrcweir         if ( xValidatable.is() )
2544*cdf0e10cSrcweir             xValidatable->removeFormComponentValidityListener( this );
2545*cdf0e10cSrcweir 	}
2546*cdf0e10cSrcweir }
2547*cdf0e10cSrcweir 
2548*cdf0e10cSrcweir //------------------------------------------------------------------------------
2549*cdf0e10cSrcweir void FormController::implSetCurrentControl( const Reference< XControl >& _rxControl )
2550*cdf0e10cSrcweir {
2551*cdf0e10cSrcweir     if ( m_xCurrentControl.get() == _rxControl.get() )
2552*cdf0e10cSrcweir         return;
2553*cdf0e10cSrcweir 
2554*cdf0e10cSrcweir     Reference< XGridControl > xGridControl( m_xCurrentControl, UNO_QUERY );
2555*cdf0e10cSrcweir     if ( xGridControl.is() )
2556*cdf0e10cSrcweir         xGridControl->removeGridControlListener( this );
2557*cdf0e10cSrcweir 
2558*cdf0e10cSrcweir     m_xCurrentControl = _rxControl;
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir     xGridControl.set( m_xCurrentControl, UNO_QUERY );
2561*cdf0e10cSrcweir     if ( xGridControl.is() )
2562*cdf0e10cSrcweir         xGridControl->addGridControlListener( this );
2563*cdf0e10cSrcweir }
2564*cdf0e10cSrcweir 
2565*cdf0e10cSrcweir //------------------------------------------------------------------------------
2566*cdf0e10cSrcweir void FormController::insertControl(const Reference< XControl > & xControl)
2567*cdf0e10cSrcweir {
2568*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2569*cdf0e10cSrcweir     m_bControlsSorted = sal_False;
2570*cdf0e10cSrcweir     m_aControls.realloc(m_aControls.getLength() + 1);
2571*cdf0e10cSrcweir     m_aControls.getArray()[m_aControls.getLength() - 1] = xControl;
2572*cdf0e10cSrcweir 
2573*cdf0e10cSrcweir     if ( m_pColumnInfoCache.get() )
2574*cdf0e10cSrcweir         m_pColumnInfoCache->deinitializeControls();
2575*cdf0e10cSrcweir 
2576*cdf0e10cSrcweir     implControlInserted( xControl, m_bAttachEvents );
2577*cdf0e10cSrcweir 
2578*cdf0e10cSrcweir     if (m_bDBConnection && !m_bFiltering)
2579*cdf0e10cSrcweir         setControlLock(xControl);
2580*cdf0e10cSrcweir 
2581*cdf0e10cSrcweir     if (isListeningForChanges() && m_bAttachEvents)
2582*cdf0e10cSrcweir         startControlModifyListening( xControl );
2583*cdf0e10cSrcweir }
2584*cdf0e10cSrcweir 
2585*cdf0e10cSrcweir //------------------------------------------------------------------------------
2586*cdf0e10cSrcweir void FormController::removeControl(const Reference< XControl > & xControl)
2587*cdf0e10cSrcweir {
2588*cdf0e10cSrcweir 	OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2589*cdf0e10cSrcweir 	const Reference< XControl >* pControls = m_aControls.getConstArray();
2590*cdf0e10cSrcweir 	const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2591*cdf0e10cSrcweir     while ( pControls != pControlsEnd )
2592*cdf0e10cSrcweir 	{
2593*cdf0e10cSrcweir 		if ( xControl.get() == (*pControls++).get() )
2594*cdf0e10cSrcweir 		{
2595*cdf0e10cSrcweir 			::comphelper::removeElementAt( m_aControls, pControls - m_aControls.getConstArray() - 1 );
2596*cdf0e10cSrcweir 			break;
2597*cdf0e10cSrcweir 		}
2598*cdf0e10cSrcweir 	}
2599*cdf0e10cSrcweir 
2600*cdf0e10cSrcweir     FilterComponents::iterator componentPos = ::std::find( m_aFilterComponents.begin(), m_aFilterComponents.end(), xControl );
2601*cdf0e10cSrcweir     if ( componentPos != m_aFilterComponents.end() )
2602*cdf0e10cSrcweir         m_aFilterComponents.erase( componentPos );
2603*cdf0e10cSrcweir 
2604*cdf0e10cSrcweir     implControlRemoved( xControl, m_bDetachEvents );
2605*cdf0e10cSrcweir 
2606*cdf0e10cSrcweir     if ( isListeningForChanges() && m_bDetachEvents )
2607*cdf0e10cSrcweir         stopControlModifyListening( xControl );
2608*cdf0e10cSrcweir }
2609*cdf0e10cSrcweir 
2610*cdf0e10cSrcweir // XLoadListener
2611*cdf0e10cSrcweir //------------------------------------------------------------------------------
2612*cdf0e10cSrcweir void FormController::loaded(const EventObject& rEvent) throw( RuntimeException )
2613*cdf0e10cSrcweir {
2614*cdf0e10cSrcweir 	OSL_ENSURE( rEvent.Source == m_xModelAsIndex, "FormController::loaded: where did this come from?" );
2615*cdf0e10cSrcweir 
2616*cdf0e10cSrcweir 	OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2617*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2618*cdf0e10cSrcweir     Reference< XRowSet >  xForm(rEvent.Source, UNO_QUERY);
2619*cdf0e10cSrcweir     // do we have a connected data source
2620*cdf0e10cSrcweir 	OStaticDataAccessTools aStaticTools;
2621*cdf0e10cSrcweir     if (xForm.is() && aStaticTools.getRowSetConnection(xForm).is())
2622*cdf0e10cSrcweir     {
2623*cdf0e10cSrcweir         Reference< XPropertySet >  xSet(xForm, UNO_QUERY);
2624*cdf0e10cSrcweir         if (xSet.is())
2625*cdf0e10cSrcweir         {
2626*cdf0e10cSrcweir             Any aVal        = xSet->getPropertyValue(FM_PROP_CYCLE);
2627*cdf0e10cSrcweir             sal_Int32 aVal2 = 0;
2628*cdf0e10cSrcweir             ::cppu::enum2int(aVal2,aVal);
2629*cdf0e10cSrcweir             m_bCycle        = !aVal.hasValue() || aVal2 == TabulatorCycle_RECORDS;
2630*cdf0e10cSrcweir             m_bCanUpdate    = aStaticTools.canUpdate(xSet);
2631*cdf0e10cSrcweir             m_bCanInsert    = aStaticTools.canInsert(xSet);
2632*cdf0e10cSrcweir             m_bCurrentRecordModified = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED));
2633*cdf0e10cSrcweir             m_bCurrentRecordNew      = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
2634*cdf0e10cSrcweir 
2635*cdf0e10cSrcweir 			startFormListening( xSet, sal_False );
2636*cdf0e10cSrcweir 
2637*cdf0e10cSrcweir             // set the locks for the current controls
2638*cdf0e10cSrcweir             if (getContainer().is())
2639*cdf0e10cSrcweir             {
2640*cdf0e10cSrcweir                 m_aLoadEvent.Call();
2641*cdf0e10cSrcweir             }
2642*cdf0e10cSrcweir         }
2643*cdf0e10cSrcweir         else
2644*cdf0e10cSrcweir         {
2645*cdf0e10cSrcweir             m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2646*cdf0e10cSrcweir             m_bCurrentRecordModified = sal_False;
2647*cdf0e10cSrcweir             m_bCurrentRecordNew = sal_False;
2648*cdf0e10cSrcweir             m_bLocked = sal_False;
2649*cdf0e10cSrcweir         }
2650*cdf0e10cSrcweir         m_bDBConnection = sal_True;
2651*cdf0e10cSrcweir     }
2652*cdf0e10cSrcweir     else
2653*cdf0e10cSrcweir     {
2654*cdf0e10cSrcweir         m_bDBConnection = sal_False;
2655*cdf0e10cSrcweir         m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2656*cdf0e10cSrcweir         m_bCurrentRecordModified = sal_False;
2657*cdf0e10cSrcweir         m_bCurrentRecordNew = sal_False;
2658*cdf0e10cSrcweir         m_bLocked = sal_False;
2659*cdf0e10cSrcweir     }
2660*cdf0e10cSrcweir 
2661*cdf0e10cSrcweir     Reference< XColumnsSupplier > xFormColumns( xForm, UNO_QUERY );
2662*cdf0e10cSrcweir     m_pColumnInfoCache.reset( xFormColumns.is() ? new ColumnInfoCache( xFormColumns ) : NULL );
2663*cdf0e10cSrcweir 
2664*cdf0e10cSrcweir     updateAllDispatchers();
2665*cdf0e10cSrcweir }
2666*cdf0e10cSrcweir 
2667*cdf0e10cSrcweir //------------------------------------------------------------------------------
2668*cdf0e10cSrcweir void FormController::updateAllDispatchers() const
2669*cdf0e10cSrcweir {
2670*cdf0e10cSrcweir     ::std::for_each(
2671*cdf0e10cSrcweir         m_aFeatureDispatchers.begin(),
2672*cdf0e10cSrcweir         m_aFeatureDispatchers.end(),
2673*cdf0e10cSrcweir         ::std::compose1(
2674*cdf0e10cSrcweir             UpdateAllListeners(),
2675*cdf0e10cSrcweir             ::std::select2nd< DispatcherContainer::value_type >()
2676*cdf0e10cSrcweir         )
2677*cdf0e10cSrcweir     );
2678*cdf0e10cSrcweir }
2679*cdf0e10cSrcweir 
2680*cdf0e10cSrcweir //------------------------------------------------------------------------------
2681*cdf0e10cSrcweir IMPL_LINK(FormController, OnLoad, void*, EMPTYARG)
2682*cdf0e10cSrcweir {
2683*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2684*cdf0e10cSrcweir     m_bLocked = determineLockState();
2685*cdf0e10cSrcweir 
2686*cdf0e10cSrcweir     setLocks();
2687*cdf0e10cSrcweir 
2688*cdf0e10cSrcweir     if (!m_bLocked)
2689*cdf0e10cSrcweir         startListening();
2690*cdf0e10cSrcweir 
2691*cdf0e10cSrcweir     // just one exception toggle the auto values
2692*cdf0e10cSrcweir     if (m_bCurrentRecordNew)
2693*cdf0e10cSrcweir         toggleAutoFields(sal_True);
2694*cdf0e10cSrcweir 
2695*cdf0e10cSrcweir     return 1L;
2696*cdf0e10cSrcweir }
2697*cdf0e10cSrcweir 
2698*cdf0e10cSrcweir //------------------------------------------------------------------------------
2699*cdf0e10cSrcweir void FormController::unloaded(const EventObject& /*rEvent*/) throw( RuntimeException )
2700*cdf0e10cSrcweir {
2701*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2702*cdf0e10cSrcweir     impl_checkDisposed_throw();
2703*cdf0e10cSrcweir 
2704*cdf0e10cSrcweir     updateAllDispatchers();
2705*cdf0e10cSrcweir }
2706*cdf0e10cSrcweir 
2707*cdf0e10cSrcweir //------------------------------------------------------------------------------
2708*cdf0e10cSrcweir void FormController::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2709*cdf0e10cSrcweir {
2710*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2711*cdf0e10cSrcweir     impl_checkDisposed_throw();
2712*cdf0e10cSrcweir 
2713*cdf0e10cSrcweir     // do the same like in unloading
2714*cdf0e10cSrcweir     // just one exception toggle the auto values
2715*cdf0e10cSrcweir     m_aToggleEvent.CancelPendingCall();
2716*cdf0e10cSrcweir     unload();
2717*cdf0e10cSrcweir }
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir //------------------------------------------------------------------------------
2720*cdf0e10cSrcweir void FormController::reloaded(const EventObject& aEvent) throw( RuntimeException )
2721*cdf0e10cSrcweir {
2722*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2723*cdf0e10cSrcweir     impl_checkDisposed_throw();
2724*cdf0e10cSrcweir 
2725*cdf0e10cSrcweir     loaded(aEvent);
2726*cdf0e10cSrcweir }
2727*cdf0e10cSrcweir 
2728*cdf0e10cSrcweir //------------------------------------------------------------------------------
2729*cdf0e10cSrcweir void FormController::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2730*cdf0e10cSrcweir {
2731*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2732*cdf0e10cSrcweir     impl_checkDisposed_throw();
2733*cdf0e10cSrcweir 
2734*cdf0e10cSrcweir     unload();
2735*cdf0e10cSrcweir }
2736*cdf0e10cSrcweir 
2737*cdf0e10cSrcweir //------------------------------------------------------------------------------
2738*cdf0e10cSrcweir void FormController::unload() throw( RuntimeException )
2739*cdf0e10cSrcweir {
2740*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2741*cdf0e10cSrcweir     impl_checkDisposed_throw();
2742*cdf0e10cSrcweir 
2743*cdf0e10cSrcweir     m_aLoadEvent.CancelPendingCall();
2744*cdf0e10cSrcweir 
2745*cdf0e10cSrcweir     // be sure not to have autofields
2746*cdf0e10cSrcweir     if (m_bCurrentRecordNew)
2747*cdf0e10cSrcweir         toggleAutoFields(sal_False);
2748*cdf0e10cSrcweir 
2749*cdf0e10cSrcweir 	// remove bound field listing again
2750*cdf0e10cSrcweir 	removeBoundFieldListener();
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir     if (m_bDBConnection && isListeningForChanges())
2753*cdf0e10cSrcweir         stopListening();
2754*cdf0e10cSrcweir 
2755*cdf0e10cSrcweir     Reference< XPropertySet >  xSet( m_xModelAsIndex, UNO_QUERY );
2756*cdf0e10cSrcweir     if ( m_bDBConnection && xSet.is() )
2757*cdf0e10cSrcweir 		stopFormListening( xSet, sal_False );
2758*cdf0e10cSrcweir 
2759*cdf0e10cSrcweir     m_bDBConnection = sal_False;
2760*cdf0e10cSrcweir     m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2761*cdf0e10cSrcweir     m_bCurrentRecordModified = m_bCurrentRecordNew = m_bLocked = sal_False;
2762*cdf0e10cSrcweir 
2763*cdf0e10cSrcweir     m_pColumnInfoCache.reset( NULL );
2764*cdf0e10cSrcweir }
2765*cdf0e10cSrcweir 
2766*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2767*cdf0e10cSrcweir void FormController::removeBoundFieldListener()
2768*cdf0e10cSrcweir {
2769*cdf0e10cSrcweir 	const Reference< XControl >* pControls = m_aControls.getConstArray();
2770*cdf0e10cSrcweir 	const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2771*cdf0e10cSrcweir     while ( pControls != pControlsEnd )
2772*cdf0e10cSrcweir     {
2773*cdf0e10cSrcweir 		Reference< XPropertySet > xProp( *pControls++, UNO_QUERY );
2774*cdf0e10cSrcweir 		if ( xProp.is() )
2775*cdf0e10cSrcweir 			xProp->removePropertyChangeListener( FM_PROP_BOUNDFIELD, this );
2776*cdf0e10cSrcweir 	}
2777*cdf0e10cSrcweir }
2778*cdf0e10cSrcweir 
2779*cdf0e10cSrcweir //------------------------------------------------------------------------------
2780*cdf0e10cSrcweir void FormController::startFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
2781*cdf0e10cSrcweir {
2782*cdf0e10cSrcweir     try
2783*cdf0e10cSrcweir     {
2784*cdf0e10cSrcweir         if ( m_bCanInsert || m_bCanUpdate )   // form can be modified
2785*cdf0e10cSrcweir         {
2786*cdf0e10cSrcweir             _rxForm->addPropertyChangeListener( FM_PROP_ISNEW, this );
2787*cdf0e10cSrcweir             _rxForm->addPropertyChangeListener( FM_PROP_ISMODIFIED, this );
2788*cdf0e10cSrcweir 
2789*cdf0e10cSrcweir 		    if ( !_bPropertiesOnly )
2790*cdf0e10cSrcweir 		    {
2791*cdf0e10cSrcweir 			    // set the Listener for UI interaction
2792*cdf0e10cSrcweir 			    Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2793*cdf0e10cSrcweir 			    if ( xApprove.is() )
2794*cdf0e10cSrcweir 				    xApprove->addRowSetApproveListener( this );
2795*cdf0e10cSrcweir 
2796*cdf0e10cSrcweir 			    // listener for row set changes
2797*cdf0e10cSrcweir 			    Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2798*cdf0e10cSrcweir 			    if ( xRowSet.is() )
2799*cdf0e10cSrcweir 				    xRowSet->addRowSetListener( this );
2800*cdf0e10cSrcweir 		    }
2801*cdf0e10cSrcweir         }
2802*cdf0e10cSrcweir 
2803*cdf0e10cSrcweir         Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2804*cdf0e10cSrcweir         if ( xInfo.is() && xInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER ) )
2805*cdf0e10cSrcweir             _rxForm->addPropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER, this );
2806*cdf0e10cSrcweir     }
2807*cdf0e10cSrcweir     catch( const Exception& )
2808*cdf0e10cSrcweir     {
2809*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
2810*cdf0e10cSrcweir     }
2811*cdf0e10cSrcweir }
2812*cdf0e10cSrcweir 
2813*cdf0e10cSrcweir //------------------------------------------------------------------------------
2814*cdf0e10cSrcweir void FormController::stopFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
2815*cdf0e10cSrcweir {
2816*cdf0e10cSrcweir     try
2817*cdf0e10cSrcweir     {
2818*cdf0e10cSrcweir         if ( m_bCanInsert || m_bCanUpdate )
2819*cdf0e10cSrcweir         {
2820*cdf0e10cSrcweir             _rxForm->removePropertyChangeListener( FM_PROP_ISNEW, this );
2821*cdf0e10cSrcweir             _rxForm->removePropertyChangeListener( FM_PROP_ISMODIFIED, this );
2822*cdf0e10cSrcweir 
2823*cdf0e10cSrcweir 		    if ( !_bPropertiesOnly )
2824*cdf0e10cSrcweir 		    {
2825*cdf0e10cSrcweir 			    Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2826*cdf0e10cSrcweir 			    if (xApprove.is())
2827*cdf0e10cSrcweir 				    xApprove->removeRowSetApproveListener(this);
2828*cdf0e10cSrcweir 
2829*cdf0e10cSrcweir 			    Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2830*cdf0e10cSrcweir 			    if ( xRowSet.is() )
2831*cdf0e10cSrcweir 				    xRowSet->removeRowSetListener( this );
2832*cdf0e10cSrcweir 		    }
2833*cdf0e10cSrcweir         }
2834*cdf0e10cSrcweir 
2835*cdf0e10cSrcweir         Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2836*cdf0e10cSrcweir         if ( xInfo.is() && xInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER ) )
2837*cdf0e10cSrcweir             _rxForm->removePropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER, this );
2838*cdf0e10cSrcweir     }
2839*cdf0e10cSrcweir     catch( const Exception& )
2840*cdf0e10cSrcweir     {
2841*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
2842*cdf0e10cSrcweir     }
2843*cdf0e10cSrcweir }
2844*cdf0e10cSrcweir 
2845*cdf0e10cSrcweir // com::sun::star::sdbc::XRowSetListener
2846*cdf0e10cSrcweir //------------------------------------------------------------------------------
2847*cdf0e10cSrcweir void FormController::cursorMoved(const EventObject& /*event*/) throw( RuntimeException )
2848*cdf0e10cSrcweir {
2849*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2850*cdf0e10cSrcweir     impl_checkDisposed_throw();
2851*cdf0e10cSrcweir 
2852*cdf0e10cSrcweir     // toggle the locking ?
2853*cdf0e10cSrcweir     if (m_bLocked != determineLockState())
2854*cdf0e10cSrcweir     {
2855*cdf0e10cSrcweir         m_bLocked = !m_bLocked;
2856*cdf0e10cSrcweir         setLocks();
2857*cdf0e10cSrcweir         if (isListeningForChanges())
2858*cdf0e10cSrcweir             startListening();
2859*cdf0e10cSrcweir         else
2860*cdf0e10cSrcweir             stopListening();
2861*cdf0e10cSrcweir     }
2862*cdf0e10cSrcweir 
2863*cdf0e10cSrcweir 	// neither the current control nor the current record are modified anymore
2864*cdf0e10cSrcweir 	m_bCurrentRecordModified = m_bModified = sal_False;
2865*cdf0e10cSrcweir }
2866*cdf0e10cSrcweir 
2867*cdf0e10cSrcweir //------------------------------------------------------------------------------
2868*cdf0e10cSrcweir void FormController::rowChanged(const EventObject& /*event*/) throw( RuntimeException )
2869*cdf0e10cSrcweir {
2870*cdf0e10cSrcweir     // not interested in ...
2871*cdf0e10cSrcweir }
2872*cdf0e10cSrcweir //------------------------------------------------------------------------------
2873*cdf0e10cSrcweir void FormController::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException )
2874*cdf0e10cSrcweir {
2875*cdf0e10cSrcweir     // not interested in ...
2876*cdf0e10cSrcweir }
2877*cdf0e10cSrcweir 
2878*cdf0e10cSrcweir 
2879*cdf0e10cSrcweir // XContainerListener
2880*cdf0e10cSrcweir //------------------------------------------------------------------------------
2881*cdf0e10cSrcweir void SAL_CALL FormController::elementInserted(const ContainerEvent& evt) throw( RuntimeException )
2882*cdf0e10cSrcweir {
2883*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2884*cdf0e10cSrcweir     impl_checkDisposed_throw();
2885*cdf0e10cSrcweir 
2886*cdf0e10cSrcweir     Reference< XControl > xControl( evt.Element, UNO_QUERY );
2887*cdf0e10cSrcweir     if ( !xControl.is() )
2888*cdf0e10cSrcweir         return;
2889*cdf0e10cSrcweir 
2890*cdf0e10cSrcweir     Reference< XFormComponent >  xModel(xControl->getModel(), UNO_QUERY);
2891*cdf0e10cSrcweir     if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2892*cdf0e10cSrcweir     {
2893*cdf0e10cSrcweir         insertControl(xControl);
2894*cdf0e10cSrcweir 
2895*cdf0e10cSrcweir         if ( m_aTabActivationTimer.IsActive() )
2896*cdf0e10cSrcweir             m_aTabActivationTimer.Stop();
2897*cdf0e10cSrcweir 
2898*cdf0e10cSrcweir         m_aTabActivationTimer.Start();
2899*cdf0e10cSrcweir     }
2900*cdf0e10cSrcweir     // are we in filtermode and a XModeSelector has inserted an element
2901*cdf0e10cSrcweir     else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2902*cdf0e10cSrcweir     {
2903*cdf0e10cSrcweir         xModel = Reference< XFormComponent > (evt.Source, UNO_QUERY);
2904*cdf0e10cSrcweir         if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2905*cdf0e10cSrcweir         {
2906*cdf0e10cSrcweir             Reference< XPropertySet >  xSet(xControl->getModel(), UNO_QUERY);
2907*cdf0e10cSrcweir             if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2908*cdf0e10cSrcweir             {
2909*cdf0e10cSrcweir                 // does the model use a bound field ?
2910*cdf0e10cSrcweir                 Reference< XPropertySet >  xField;
2911*cdf0e10cSrcweir                 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2912*cdf0e10cSrcweir 
2913*cdf0e10cSrcweir                 Reference< XTextComponent >  xText(xControl, UNO_QUERY);
2914*cdf0e10cSrcweir                 // may we filter the field?
2915*cdf0e10cSrcweir                 if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
2916*cdf0e10cSrcweir                     ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2917*cdf0e10cSrcweir                 {
2918*cdf0e10cSrcweir                     m_aFilterComponents.push_back( xText );
2919*cdf0e10cSrcweir                     xText->addTextListener( this );
2920*cdf0e10cSrcweir                 }
2921*cdf0e10cSrcweir             }
2922*cdf0e10cSrcweir         }
2923*cdf0e10cSrcweir     }
2924*cdf0e10cSrcweir }
2925*cdf0e10cSrcweir 
2926*cdf0e10cSrcweir //------------------------------------------------------------------------------
2927*cdf0e10cSrcweir void SAL_CALL FormController::elementReplaced(const ContainerEvent& evt) throw( RuntimeException )
2928*cdf0e10cSrcweir {
2929*cdf0e10cSrcweir     // simulate an elementRemoved
2930*cdf0e10cSrcweir     ContainerEvent aRemoveEvent( evt );
2931*cdf0e10cSrcweir     aRemoveEvent.Element = evt.ReplacedElement;
2932*cdf0e10cSrcweir     aRemoveEvent.ReplacedElement = Any();
2933*cdf0e10cSrcweir     elementRemoved( aRemoveEvent );
2934*cdf0e10cSrcweir 
2935*cdf0e10cSrcweir     // simulate an elementInserted
2936*cdf0e10cSrcweir     ContainerEvent aInsertEvent( evt );
2937*cdf0e10cSrcweir     aInsertEvent.ReplacedElement = Any();
2938*cdf0e10cSrcweir     elementInserted( aInsertEvent );
2939*cdf0e10cSrcweir }
2940*cdf0e10cSrcweir 
2941*cdf0e10cSrcweir //------------------------------------------------------------------------------
2942*cdf0e10cSrcweir void SAL_CALL FormController::elementRemoved(const ContainerEvent& evt) throw( RuntimeException )
2943*cdf0e10cSrcweir {
2944*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2945*cdf0e10cSrcweir     impl_checkDisposed_throw();
2946*cdf0e10cSrcweir 
2947*cdf0e10cSrcweir     Reference< XControl >  xControl;
2948*cdf0e10cSrcweir     evt.Element >>= xControl;
2949*cdf0e10cSrcweir     if (!xControl.is())
2950*cdf0e10cSrcweir         return;
2951*cdf0e10cSrcweir 
2952*cdf0e10cSrcweir     Reference< XFormComponent >  xModel(xControl->getModel(), UNO_QUERY);
2953*cdf0e10cSrcweir     if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2954*cdf0e10cSrcweir     {
2955*cdf0e10cSrcweir         removeControl(xControl);
2956*cdf0e10cSrcweir         // TabOrder nicht neu berechnen, da das intern schon funktionieren mu�!
2957*cdf0e10cSrcweir     }
2958*cdf0e10cSrcweir     // are we in filtermode and a XModeSelector has inserted an element
2959*cdf0e10cSrcweir     else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2960*cdf0e10cSrcweir     {
2961*cdf0e10cSrcweir         FilterComponents::iterator componentPos = ::std::find(
2962*cdf0e10cSrcweir             m_aFilterComponents.begin(), m_aFilterComponents.end(), xControl );
2963*cdf0e10cSrcweir         if ( componentPos != m_aFilterComponents.end() )
2964*cdf0e10cSrcweir             m_aFilterComponents.erase( componentPos );
2965*cdf0e10cSrcweir     }
2966*cdf0e10cSrcweir }
2967*cdf0e10cSrcweir 
2968*cdf0e10cSrcweir //------------------------------------------------------------------------------
2969*cdf0e10cSrcweir Reference< XControl >  FormController::isInList(const Reference< XWindowPeer > & xPeer) const
2970*cdf0e10cSrcweir {
2971*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2972*cdf0e10cSrcweir     const Reference< XControl >* pControls = m_aControls.getConstArray();
2973*cdf0e10cSrcweir 
2974*cdf0e10cSrcweir     sal_uInt32 nCtrls = m_aControls.getLength();
2975*cdf0e10cSrcweir     for ( sal_uInt32 n = 0; n < nCtrls && xPeer.is(); ++n, ++pControls )
2976*cdf0e10cSrcweir     {
2977*cdf0e10cSrcweir         if ( pControls->is() )
2978*cdf0e10cSrcweir         {
2979*cdf0e10cSrcweir             Reference< XVclWindowPeer >  xCtrlPeer( (*pControls)->getPeer(), UNO_QUERY);
2980*cdf0e10cSrcweir             if ( ( xCtrlPeer.get() == xPeer.get() ) || xCtrlPeer->isChild( xPeer ) )
2981*cdf0e10cSrcweir                 return *pControls;
2982*cdf0e10cSrcweir         }
2983*cdf0e10cSrcweir     }
2984*cdf0e10cSrcweir     return Reference< XControl > ();
2985*cdf0e10cSrcweir }
2986*cdf0e10cSrcweir 
2987*cdf0e10cSrcweir //------------------------------------------------------------------------------
2988*cdf0e10cSrcweir void FormController::activateFirst() throw( RuntimeException )
2989*cdf0e10cSrcweir {
2990*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
2991*cdf0e10cSrcweir     impl_checkDisposed_throw();
2992*cdf0e10cSrcweir 
2993*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::activateFirst : invalid aggregate !");
2994*cdf0e10cSrcweir     if (m_xTabController.is())
2995*cdf0e10cSrcweir         m_xTabController->activateFirst();
2996*cdf0e10cSrcweir }
2997*cdf0e10cSrcweir 
2998*cdf0e10cSrcweir //------------------------------------------------------------------------------
2999*cdf0e10cSrcweir void FormController::activateLast() throw( RuntimeException )
3000*cdf0e10cSrcweir {
3001*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3002*cdf0e10cSrcweir     impl_checkDisposed_throw();
3003*cdf0e10cSrcweir 
3004*cdf0e10cSrcweir     DBG_ASSERT(m_xTabController.is(), "FormController::activateLast : invalid aggregate !");
3005*cdf0e10cSrcweir     if (m_xTabController.is())
3006*cdf0e10cSrcweir         m_xTabController->activateLast();
3007*cdf0e10cSrcweir }
3008*cdf0e10cSrcweir 
3009*cdf0e10cSrcweir // XFormController
3010*cdf0e10cSrcweir //------------------------------------------------------------------------------
3011*cdf0e10cSrcweir Reference< XFormOperations > SAL_CALL FormController::getFormOperations() throw (RuntimeException)
3012*cdf0e10cSrcweir {
3013*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3014*cdf0e10cSrcweir     impl_checkDisposed_throw();
3015*cdf0e10cSrcweir 
3016*cdf0e10cSrcweir     return m_xFormOperations;
3017*cdf0e10cSrcweir }
3018*cdf0e10cSrcweir 
3019*cdf0e10cSrcweir //------------------------------------------------------------------------------
3020*cdf0e10cSrcweir Reference< XControl> SAL_CALL FormController::getCurrentControl(void) throw( RuntimeException )
3021*cdf0e10cSrcweir {
3022*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3023*cdf0e10cSrcweir     impl_checkDisposed_throw();
3024*cdf0e10cSrcweir 	return m_xCurrentControl;
3025*cdf0e10cSrcweir }
3026*cdf0e10cSrcweir 
3027*cdf0e10cSrcweir //------------------------------------------------------------------------------
3028*cdf0e10cSrcweir void SAL_CALL FormController::addActivateListener(const Reference< XFormControllerListener > & l) throw( RuntimeException )
3029*cdf0e10cSrcweir {
3030*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3031*cdf0e10cSrcweir     impl_checkDisposed_throw();
3032*cdf0e10cSrcweir 	m_aActivateListeners.addInterface(l);
3033*cdf0e10cSrcweir }
3034*cdf0e10cSrcweir //------------------------------------------------------------------------------
3035*cdf0e10cSrcweir void SAL_CALL FormController::removeActivateListener(const Reference< XFormControllerListener > & l) throw( RuntimeException )
3036*cdf0e10cSrcweir {
3037*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3038*cdf0e10cSrcweir     impl_checkDisposed_throw();
3039*cdf0e10cSrcweir 	m_aActivateListeners.removeInterface(l);
3040*cdf0e10cSrcweir }
3041*cdf0e10cSrcweir 
3042*cdf0e10cSrcweir //------------------------------------------------------------------------------
3043*cdf0e10cSrcweir void SAL_CALL FormController::addChildController( const Reference< XFormController >& _ChildController ) throw( RuntimeException, IllegalArgumentException )
3044*cdf0e10cSrcweir {
3045*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3046*cdf0e10cSrcweir     impl_checkDisposed_throw();
3047*cdf0e10cSrcweir 
3048*cdf0e10cSrcweir     if ( !_ChildController.is() )
3049*cdf0e10cSrcweir         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
3050*cdf0e10cSrcweir         // TODO: (localized) error message
3051*cdf0e10cSrcweir 
3052*cdf0e10cSrcweir     // the parent of our (to-be-)child must be our own model
3053*cdf0e10cSrcweir     Reference< XFormComponent > xFormOfChild( _ChildController->getModel(), UNO_QUERY );
3054*cdf0e10cSrcweir     if ( !xFormOfChild.is() )
3055*cdf0e10cSrcweir         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
3056*cdf0e10cSrcweir         // TODO: (localized) error message
3057*cdf0e10cSrcweir 
3058*cdf0e10cSrcweir     if ( xFormOfChild->getParent() != m_xModelAsIndex )
3059*cdf0e10cSrcweir         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
3060*cdf0e10cSrcweir         // TODO: (localized) error message
3061*cdf0e10cSrcweir 
3062*cdf0e10cSrcweir     m_aChilds.push_back( _ChildController );
3063*cdf0e10cSrcweir     _ChildController->setParent( *this );
3064*cdf0e10cSrcweir 
3065*cdf0e10cSrcweir     // search the position of the model within the form
3066*cdf0e10cSrcweir     sal_uInt32 nPos = m_xModelAsIndex->getCount();
3067*cdf0e10cSrcweir     Reference< XFormComponent > xTemp;
3068*cdf0e10cSrcweir     for( ; nPos; )
3069*cdf0e10cSrcweir     {
3070*cdf0e10cSrcweir         m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
3071*cdf0e10cSrcweir         if ( xFormOfChild == xTemp )
3072*cdf0e10cSrcweir         {
3073*cdf0e10cSrcweir             Reference< XInterface >  xIfc( _ChildController, UNO_QUERY );
3074*cdf0e10cSrcweir             m_xModelAsManager->attach( nPos, xIfc, makeAny( _ChildController) );
3075*cdf0e10cSrcweir             break;
3076*cdf0e10cSrcweir         }
3077*cdf0e10cSrcweir     }
3078*cdf0e10cSrcweir }
3079*cdf0e10cSrcweir 
3080*cdf0e10cSrcweir //------------------------------------------------------------------------------
3081*cdf0e10cSrcweir Reference< XFormControllerContext > SAL_CALL FormController::getContext() throw (RuntimeException)
3082*cdf0e10cSrcweir {
3083*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3084*cdf0e10cSrcweir     impl_checkDisposed_throw();
3085*cdf0e10cSrcweir     return m_xContext;
3086*cdf0e10cSrcweir }
3087*cdf0e10cSrcweir 
3088*cdf0e10cSrcweir //------------------------------------------------------------------------------
3089*cdf0e10cSrcweir void SAL_CALL FormController::setContext( const Reference< XFormControllerContext >& _context ) throw (RuntimeException)
3090*cdf0e10cSrcweir {
3091*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3092*cdf0e10cSrcweir     impl_checkDisposed_throw();
3093*cdf0e10cSrcweir     m_xContext = _context;
3094*cdf0e10cSrcweir }
3095*cdf0e10cSrcweir 
3096*cdf0e10cSrcweir //------------------------------------------------------------------------------
3097*cdf0e10cSrcweir Reference< XInteractionHandler > SAL_CALL FormController::getInteractionHandler() throw (RuntimeException)
3098*cdf0e10cSrcweir {
3099*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3100*cdf0e10cSrcweir     impl_checkDisposed_throw();
3101*cdf0e10cSrcweir     return m_xInteractionHandler;
3102*cdf0e10cSrcweir }
3103*cdf0e10cSrcweir 
3104*cdf0e10cSrcweir //------------------------------------------------------------------------------
3105*cdf0e10cSrcweir void SAL_CALL FormController::setInteractionHandler( const Reference< XInteractionHandler >& _interactionHandler ) throw (RuntimeException)
3106*cdf0e10cSrcweir {
3107*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
3108*cdf0e10cSrcweir     impl_checkDisposed_throw();
3109*cdf0e10cSrcweir     m_xInteractionHandler = _interactionHandler;
3110*cdf0e10cSrcweir }
3111*cdf0e10cSrcweir 
3112*cdf0e10cSrcweir //------------------------------------------------------------------------------
3113*cdf0e10cSrcweir void FormController::setFilter(::std::vector<FmFieldInfo>& rFieldInfos)
3114*cdf0e10cSrcweir {
3115*cdf0e10cSrcweir 	OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3116*cdf0e10cSrcweir 	// create the composer
3117*cdf0e10cSrcweir 	Reference< XRowSet > xForm(m_xModelAsIndex, UNO_QUERY);
3118*cdf0e10cSrcweir 	Reference< XConnection > xConnection(OStaticDataAccessTools().getRowSetConnection(xForm));
3119*cdf0e10cSrcweir 	if (xForm.is())
3120*cdf0e10cSrcweir 	{
3121*cdf0e10cSrcweir         try
3122*cdf0e10cSrcweir         {
3123*cdf0e10cSrcweir             Reference< XMultiServiceFactory > xFactory( xConnection, UNO_QUERY_THROW );
3124*cdf0e10cSrcweir             m_xComposer.set(
3125*cdf0e10cSrcweir                 xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
3126*cdf0e10cSrcweir                 UNO_QUERY_THROW );
3127*cdf0e10cSrcweir 
3128*cdf0e10cSrcweir             Reference< XPropertySet > xSet( xForm, UNO_QUERY );
3129*cdf0e10cSrcweir 			::rtl::OUString	sStatement	= ::comphelper::getString( xSet->getPropertyValue( FM_PROP_ACTIVECOMMAND ) );
3130*cdf0e10cSrcweir 			::rtl::OUString sFilter		= ::comphelper::getString( xSet->getPropertyValue( FM_PROP_FILTER ) );
3131*cdf0e10cSrcweir 			m_xComposer->setElementaryQuery( sStatement );
3132*cdf0e10cSrcweir 			m_xComposer->setFilter( sFilter );
3133*cdf0e10cSrcweir         }
3134*cdf0e10cSrcweir         catch( const Exception& )
3135*cdf0e10cSrcweir         {
3136*cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
3137*cdf0e10cSrcweir         }
3138*cdf0e10cSrcweir 	}
3139*cdf0e10cSrcweir 
3140*cdf0e10cSrcweir 	if (m_xComposer.is())
3141*cdf0e10cSrcweir 	{
3142*cdf0e10cSrcweir 		Sequence < PropertyValue> aLevel;
3143*cdf0e10cSrcweir 		Sequence< Sequence < PropertyValue > > aFilterRows = m_xComposer->getStructuredFilter();
3144*cdf0e10cSrcweir 
3145*cdf0e10cSrcweir 		// ok, we recieve the list of filters as sequence of fieldnames, value
3146*cdf0e10cSrcweir 		// now we have to transform the fieldname into UI names, that could be a label of the field or
3147*cdf0e10cSrcweir 		// a aliasname or the fieldname itself
3148*cdf0e10cSrcweir 
3149*cdf0e10cSrcweir 		// first adjust the field names if necessary
3150*cdf0e10cSrcweir 		Reference< XNameAccess > xQueryColumns =
3151*cdf0e10cSrcweir             Reference< XColumnsSupplier >( m_xComposer, UNO_QUERY_THROW )->getColumns();
3152*cdf0e10cSrcweir 
3153*cdf0e10cSrcweir 		for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
3154*cdf0e10cSrcweir 			iter != rFieldInfos.end(); iter++)
3155*cdf0e10cSrcweir 		{
3156*cdf0e10cSrcweir 			if ( xQueryColumns->hasByName((*iter).aFieldName) )
3157*cdf0e10cSrcweir 			{
3158*cdf0e10cSrcweir 				if ( (xQueryColumns->getByName((*iter).aFieldName) >>= (*iter).xField) && (*iter).xField.is() )
3159*cdf0e10cSrcweir 					(*iter).xField->getPropertyValue(FM_PROP_REALNAME) >>= (*iter).aFieldName;
3160*cdf0e10cSrcweir 			}
3161*cdf0e10cSrcweir 		}
3162*cdf0e10cSrcweir 
3163*cdf0e10cSrcweir 		Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
3164*cdf0e10cSrcweir 		// now transfer the filters into Value/TextComponent pairs
3165*cdf0e10cSrcweir 		::comphelper::UStringMixEqual aCompare(xMetaData->storesMixedCaseQuotedIdentifiers());
3166*cdf0e10cSrcweir 
3167*cdf0e10cSrcweir 		// need to parse criteria localized
3168*cdf0e10cSrcweir 		OStaticDataAccessTools aStaticTools;
3169*cdf0e10cSrcweir 		Reference< XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
3170*cdf0e10cSrcweir         Reference< XNumberFormatter> xFormatter( m_aContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY );
3171*cdf0e10cSrcweir         xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3172*cdf0e10cSrcweir 		Locale aAppLocale = Application::GetSettings().GetUILocale();
3173*cdf0e10cSrcweir 		LocaleDataWrapper aLocaleWrapper( m_aContext.getLegacyServiceFactory(), aAppLocale );
3174*cdf0e10cSrcweir 
3175*cdf0e10cSrcweir 		// retrieving the filter
3176*cdf0e10cSrcweir 		const Sequence < PropertyValue >* pRow = aFilterRows.getConstArray();
3177*cdf0e10cSrcweir 		for (sal_Int32 i = 0, nLen = aFilterRows.getLength(); i < nLen; ++i)
3178*cdf0e10cSrcweir 		{
3179*cdf0e10cSrcweir 			FmFilterRow aRow;
3180*cdf0e10cSrcweir 
3181*cdf0e10cSrcweir 			// search a field for the given name
3182*cdf0e10cSrcweir 			const PropertyValue* pRefValues = pRow[i].getConstArray();
3183*cdf0e10cSrcweir 			for (sal_Int32 j = 0, nLen1 = pRow[i].getLength(); j < nLen1; j++)
3184*cdf0e10cSrcweir 			{
3185*cdf0e10cSrcweir 				// look for the text component
3186*cdf0e10cSrcweir 				Reference< XPropertySet > xField;
3187*cdf0e10cSrcweir 				try
3188*cdf0e10cSrcweir 				{
3189*cdf0e10cSrcweir 					Reference< XPropertySet > xSet;
3190*cdf0e10cSrcweir 					::rtl::OUString aRealName;
3191*cdf0e10cSrcweir 
3192*cdf0e10cSrcweir 					// first look with the given name
3193*cdf0e10cSrcweir 					if (xQueryColumns->hasByName(pRefValues[j].Name))
3194*cdf0e10cSrcweir 					{
3195*cdf0e10cSrcweir 						xQueryColumns->getByName(pRefValues[j].Name) >>= xSet;
3196*cdf0e10cSrcweir 
3197*cdf0e10cSrcweir 						// get the RealName
3198*cdf0e10cSrcweir 						xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
3199*cdf0e10cSrcweir 
3200*cdf0e10cSrcweir 						// compare the condition field name and the RealName
3201*cdf0e10cSrcweir 						if (aCompare(aRealName, pRefValues[j].Name))
3202*cdf0e10cSrcweir 							xField = xSet;
3203*cdf0e10cSrcweir 					}
3204*cdf0e10cSrcweir 					if (!xField.is())
3205*cdf0e10cSrcweir 					{
3206*cdf0e10cSrcweir 						// no we have to check every column to find the realname
3207*cdf0e10cSrcweir 						Reference< XIndexAccess > xColumnsByIndex(xQueryColumns, UNO_QUERY);
3208*cdf0e10cSrcweir 						for (sal_Int32 n = 0, nCount = xColumnsByIndex->getCount(); n < nCount; n++)
3209*cdf0e10cSrcweir 						{
3210*cdf0e10cSrcweir 							xColumnsByIndex->getByIndex(n) >>= xSet;
3211*cdf0e10cSrcweir 							xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
3212*cdf0e10cSrcweir 							if (aCompare(aRealName, pRefValues[j].Name))
3213*cdf0e10cSrcweir 							{
3214*cdf0e10cSrcweir 								// get the column by its alias
3215*cdf0e10cSrcweir 								xField = xSet;
3216*cdf0e10cSrcweir 								break;
3217*cdf0e10cSrcweir 							}
3218*cdf0e10cSrcweir 						}
3219*cdf0e10cSrcweir 					}
3220*cdf0e10cSrcweir 					if (!xField.is())
3221*cdf0e10cSrcweir 						continue;
3222*cdf0e10cSrcweir 				}
3223*cdf0e10cSrcweir 				catch (const Exception&)
3224*cdf0e10cSrcweir 				{
3225*cdf0e10cSrcweir 					continue;
3226*cdf0e10cSrcweir 				}
3227*cdf0e10cSrcweir 
3228*cdf0e10cSrcweir 				// find the text component
3229*cdf0e10cSrcweir 				for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
3230*cdf0e10cSrcweir 					iter != rFieldInfos.end(); iter++)
3231*cdf0e10cSrcweir 				{
3232*cdf0e10cSrcweir 					// we found the field so insert a new entry to the filter row
3233*cdf0e10cSrcweir 					if ((*iter).xField == xField)
3234*cdf0e10cSrcweir 					{
3235*cdf0e10cSrcweir 						// do we already have the control ?
3236*cdf0e10cSrcweir 						if (aRow.find((*iter).xText) != aRow.end())
3237*cdf0e10cSrcweir 						{
3238*cdf0e10cSrcweir 							::rtl::OUString aCompText = aRow[(*iter).xText];
3239*cdf0e10cSrcweir 							aCompText += ::rtl::OUString::createFromAscii(" ");
3240*cdf0e10cSrcweir 							::rtl::OString aVal = m_xParser->getContext().getIntlKeywordAscii(OParseContext::KEY_AND);
3241*cdf0e10cSrcweir 							aCompText += ::rtl::OUString(aVal.getStr(),aVal.getLength(),RTL_TEXTENCODING_ASCII_US);
3242*cdf0e10cSrcweir 							aCompText += ::rtl::OUString::createFromAscii(" ");
3243*cdf0e10cSrcweir 							aCompText += ::comphelper::getString(pRefValues[j].Value);
3244*cdf0e10cSrcweir 							aRow[(*iter).xText] = aCompText;
3245*cdf0e10cSrcweir 						}
3246*cdf0e10cSrcweir 						else
3247*cdf0e10cSrcweir 						{
3248*cdf0e10cSrcweir 							::rtl::OUString sPredicate,sErrorMsg;
3249*cdf0e10cSrcweir 							pRefValues[j].Value >>= sPredicate;
3250*cdf0e10cSrcweir 							::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(sErrorMsg, sPredicate, xFormatter, xField);
3251*cdf0e10cSrcweir                             if ( xParseNode.is() )
3252*cdf0e10cSrcweir                             {
3253*cdf0e10cSrcweir 								::rtl::OUString sCriteria;
3254*cdf0e10cSrcweir 								xParseNode->parseNodeToPredicateStr( sCriteria
3255*cdf0e10cSrcweir 																	,xConnection
3256*cdf0e10cSrcweir 																	,xFormatter
3257*cdf0e10cSrcweir 																	,xField
3258*cdf0e10cSrcweir 																	,aAppLocale
3259*cdf0e10cSrcweir 																	,(sal_Char)aLocaleWrapper.getNumDecimalSep().GetChar(0)
3260*cdf0e10cSrcweir 																	,getParseContext());
3261*cdf0e10cSrcweir                                 aRow[(*iter).xText] = sCriteria;
3262*cdf0e10cSrcweir                             }
3263*cdf0e10cSrcweir 						}
3264*cdf0e10cSrcweir 					}
3265*cdf0e10cSrcweir 				}
3266*cdf0e10cSrcweir 			}
3267*cdf0e10cSrcweir 
3268*cdf0e10cSrcweir 			if (aRow.empty())
3269*cdf0e10cSrcweir 				continue;
3270*cdf0e10cSrcweir 
3271*cdf0e10cSrcweir             impl_addFilterRow( aRow );
3272*cdf0e10cSrcweir 		}
3273*cdf0e10cSrcweir 	}
3274*cdf0e10cSrcweir 
3275*cdf0e10cSrcweir 	// now set the filter controls
3276*cdf0e10cSrcweir     for (   ::std::vector<FmFieldInfo>::iterator field = rFieldInfos.begin();
3277*cdf0e10cSrcweir             field != rFieldInfos.end();
3278*cdf0e10cSrcweir             ++field
3279*cdf0e10cSrcweir         )
3280*cdf0e10cSrcweir     {
3281*cdf0e10cSrcweir         m_aFilterComponents.push_back( field->xText );
3282*cdf0e10cSrcweir     }
3283*cdf0e10cSrcweir }
3284*cdf0e10cSrcweir 
3285*cdf0e10cSrcweir //------------------------------------------------------------------------------
3286*cdf0e10cSrcweir void FormController::startFiltering()
3287*cdf0e10cSrcweir {
3288*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3289*cdf0e10cSrcweir 
3290*cdf0e10cSrcweir 	OStaticDataAccessTools aStaticTools;
3291*cdf0e10cSrcweir     Reference< XConnection >  xConnection( aStaticTools.getRowSetConnection( Reference< XRowSet >( m_xModelAsIndex, UNO_QUERY ) ) );
3292*cdf0e10cSrcweir 	if ( !xConnection.is() )
3293*cdf0e10cSrcweir 		// nothing to do - can't filter a form which is not connected
3294*cdf0e10cSrcweir 		// 98023 - 19.03.2002 - fs@openoffice.org
3295*cdf0e10cSrcweir 		return;
3296*cdf0e10cSrcweir 
3297*cdf0e10cSrcweir     // stop listening for controls
3298*cdf0e10cSrcweir     if (isListeningForChanges())
3299*cdf0e10cSrcweir         stopListening();
3300*cdf0e10cSrcweir 
3301*cdf0e10cSrcweir     m_bFiltering = sal_True;
3302*cdf0e10cSrcweir 
3303*cdf0e10cSrcweir     // as we don't want new controls to be attached to the scripting environment
3304*cdf0e10cSrcweir     // we change attach flags
3305*cdf0e10cSrcweir     m_bAttachEvents = sal_False;
3306*cdf0e10cSrcweir 
3307*cdf0e10cSrcweir     // Austauschen der Kontrols fuer das aktuelle Formular
3308*cdf0e10cSrcweir     Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3309*cdf0e10cSrcweir     const Reference< XControl >* pControls = aControlsCopy.getConstArray();
3310*cdf0e10cSrcweir     sal_Int32 nControlCount = aControlsCopy.getLength();
3311*cdf0e10cSrcweir 
3312*cdf0e10cSrcweir     // the control we have to activate after replacement
3313*cdf0e10cSrcweir     Reference< XDatabaseMetaData >  xMetaData(xConnection->getMetaData());
3314*cdf0e10cSrcweir     Reference< XNumberFormatsSupplier >  xFormatSupplier = aStaticTools.getNumberFormats(xConnection, sal_True);
3315*cdf0e10cSrcweir     Reference< XNumberFormatter >  xFormatter( m_aContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY );
3316*cdf0e10cSrcweir     xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3317*cdf0e10cSrcweir 
3318*cdf0e10cSrcweir     // structure for storing the field info
3319*cdf0e10cSrcweir     ::std::vector<FmFieldInfo> aFieldInfos;
3320*cdf0e10cSrcweir 
3321*cdf0e10cSrcweir     for (sal_Int32 i = nControlCount; i > 0;)
3322*cdf0e10cSrcweir     {
3323*cdf0e10cSrcweir         Reference< XControl > xControl = pControls[--i];
3324*cdf0e10cSrcweir         if (xControl.is())
3325*cdf0e10cSrcweir         {
3326*cdf0e10cSrcweir             // no events for the control anymore
3327*cdf0e10cSrcweir             removeFromEventAttacher(xControl);
3328*cdf0e10cSrcweir 
3329*cdf0e10cSrcweir             // do we have a mode selector
3330*cdf0e10cSrcweir             Reference< XModeSelector >  xSelector(xControl, UNO_QUERY);
3331*cdf0e10cSrcweir             if (xSelector.is())
3332*cdf0e10cSrcweir             {
3333*cdf0e10cSrcweir                 xSelector->setMode( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterMode" ) ) );
3334*cdf0e10cSrcweir 
3335*cdf0e10cSrcweir                 // listening for new controls of the selector
3336*cdf0e10cSrcweir                 Reference< XContainer >  xContainer(xSelector, UNO_QUERY);
3337*cdf0e10cSrcweir                 if (xContainer.is())
3338*cdf0e10cSrcweir                     xContainer->addContainerListener(this);
3339*cdf0e10cSrcweir 
3340*cdf0e10cSrcweir                 Reference< XEnumerationAccess >  xElementAccess(xSelector, UNO_QUERY);
3341*cdf0e10cSrcweir                 if (xElementAccess.is())
3342*cdf0e10cSrcweir                 {
3343*cdf0e10cSrcweir                     Reference< XEnumeration >  xEnumeration(xElementAccess->createEnumeration());
3344*cdf0e10cSrcweir                     Reference< XControl >  xSubControl;
3345*cdf0e10cSrcweir                     while (xEnumeration->hasMoreElements())
3346*cdf0e10cSrcweir                     {
3347*cdf0e10cSrcweir                         xEnumeration->nextElement() >>= xSubControl;
3348*cdf0e10cSrcweir                         if (xSubControl.is())
3349*cdf0e10cSrcweir                         {
3350*cdf0e10cSrcweir                             Reference< XPropertySet >  xSet(xSubControl->getModel(), UNO_QUERY);
3351*cdf0e10cSrcweir                             if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
3352*cdf0e10cSrcweir                             {
3353*cdf0e10cSrcweir                                 // does the model use a bound field ?
3354*cdf0e10cSrcweir                                 Reference< XPropertySet >  xField;
3355*cdf0e10cSrcweir                                 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3356*cdf0e10cSrcweir 
3357*cdf0e10cSrcweir                                 Reference< XTextComponent >  xText(xSubControl, UNO_QUERY);
3358*cdf0e10cSrcweir                                 // may we filter the field?
3359*cdf0e10cSrcweir                                 if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
3360*cdf0e10cSrcweir                                     ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
3361*cdf0e10cSrcweir                                 {
3362*cdf0e10cSrcweir                                     aFieldInfos.push_back(FmFieldInfo(xField, xText));
3363*cdf0e10cSrcweir                                     xText->addTextListener(this);
3364*cdf0e10cSrcweir                                 }
3365*cdf0e10cSrcweir                             }
3366*cdf0e10cSrcweir                         }
3367*cdf0e10cSrcweir                     }
3368*cdf0e10cSrcweir                 }
3369*cdf0e10cSrcweir                 continue;
3370*cdf0e10cSrcweir             }
3371*cdf0e10cSrcweir 
3372*cdf0e10cSrcweir             Reference< XPropertySet >  xModel( xControl->getModel(), UNO_QUERY );
3373*cdf0e10cSrcweir             if (xModel.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xModel))
3374*cdf0e10cSrcweir             {
3375*cdf0e10cSrcweir                 // does the model use a bound field ?
3376*cdf0e10cSrcweir                 Any aVal = xModel->getPropertyValue(FM_PROP_BOUNDFIELD);
3377*cdf0e10cSrcweir                 Reference< XPropertySet >  xField;
3378*cdf0e10cSrcweir                 aVal >>= xField;
3379*cdf0e10cSrcweir 
3380*cdf0e10cSrcweir                 // may we filter the field?
3381*cdf0e10cSrcweir 
3382*cdf0e10cSrcweir                 if  (   xField.is()
3383*cdf0e10cSrcweir                     &&  ::comphelper::hasProperty( FM_PROP_SEARCHABLE, xField )
3384*cdf0e10cSrcweir                     && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_SEARCHABLE ) )
3385*cdf0e10cSrcweir                     )
3386*cdf0e10cSrcweir                 {
3387*cdf0e10cSrcweir                     // create a filter control
3388*cdf0e10cSrcweir                     Sequence< Any > aCreationArgs( 3 );
3389*cdf0e10cSrcweir                     aCreationArgs[ 0 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "MessageParent" ), makeAny( VCLUnoHelper::GetInterface( getDialogParentWindow() ) ) );
3390*cdf0e10cSrcweir                     aCreationArgs[ 1 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "NumberFormatter" ), makeAny( xFormatter ) );
3391*cdf0e10cSrcweir                     aCreationArgs[ 2 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "ControlModel" ), makeAny( xModel ) );
3392*cdf0e10cSrcweir                     Reference< XControl > xFilterControl(
3393*cdf0e10cSrcweir                         m_aContext.createComponentWithArguments( "com.sun.star.form.control.FilterControl", aCreationArgs ),
3394*cdf0e10cSrcweir                         UNO_QUERY
3395*cdf0e10cSrcweir                     );
3396*cdf0e10cSrcweir                     DBG_ASSERT( xFilterControl.is(), "FormController::startFiltering: could not create a filter control!" );
3397*cdf0e10cSrcweir 
3398*cdf0e10cSrcweir                     if ( replaceControl( xControl, xFilterControl ) )
3399*cdf0e10cSrcweir                     {
3400*cdf0e10cSrcweir                         Reference< XTextComponent > xFilterText( xFilterControl, UNO_QUERY );
3401*cdf0e10cSrcweir                         aFieldInfos.push_back( FmFieldInfo( xField, xFilterText ) );
3402*cdf0e10cSrcweir                         xFilterText->addTextListener(this);
3403*cdf0e10cSrcweir                     }
3404*cdf0e10cSrcweir                 }
3405*cdf0e10cSrcweir             }
3406*cdf0e10cSrcweir             else
3407*cdf0e10cSrcweir             {
3408*cdf0e10cSrcweir                 // abmelden vom EventManager
3409*cdf0e10cSrcweir             }
3410*cdf0e10cSrcweir         }
3411*cdf0e10cSrcweir     }
3412*cdf0e10cSrcweir 
3413*cdf0e10cSrcweir     // we have all filter controls now, so the next step is to read the filters from the form
3414*cdf0e10cSrcweir     // resolve all aliases and set the current filter to the according structure
3415*cdf0e10cSrcweir     setFilter(aFieldInfos);
3416*cdf0e10cSrcweir 
3417*cdf0e10cSrcweir     Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3418*cdf0e10cSrcweir 	if ( xSet.is() )
3419*cdf0e10cSrcweir 		stopFormListening( xSet, sal_True );
3420*cdf0e10cSrcweir 
3421*cdf0e10cSrcweir     impl_setTextOnAllFilter_throw();
3422*cdf0e10cSrcweir 
3423*cdf0e10cSrcweir     // lock all controls which are not used for filtering
3424*cdf0e10cSrcweir     m_bLocked = determineLockState();
3425*cdf0e10cSrcweir     setLocks();
3426*cdf0e10cSrcweir     m_bAttachEvents = sal_True;
3427*cdf0e10cSrcweir }
3428*cdf0e10cSrcweir 
3429*cdf0e10cSrcweir //------------------------------------------------------------------------------
3430*cdf0e10cSrcweir void FormController::stopFiltering()
3431*cdf0e10cSrcweir {
3432*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3433*cdf0e10cSrcweir 	if ( !m_bFiltering ) // #104693# OJ
3434*cdf0e10cSrcweir 	{	// nothing to do
3435*cdf0e10cSrcweir 		return;
3436*cdf0e10cSrcweir 	}
3437*cdf0e10cSrcweir 
3438*cdf0e10cSrcweir     m_bFiltering = sal_False;
3439*cdf0e10cSrcweir     m_bDetachEvents = sal_False;
3440*cdf0e10cSrcweir 
3441*cdf0e10cSrcweir     ::comphelper::disposeComponent(m_xComposer);
3442*cdf0e10cSrcweir 
3443*cdf0e10cSrcweir     // Austauschen der Kontrols fuer das aktuelle Formular
3444*cdf0e10cSrcweir     Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3445*cdf0e10cSrcweir     const Reference< XControl > * pControls = aControlsCopy.getConstArray();
3446*cdf0e10cSrcweir     sal_Int32 nControlCount = aControlsCopy.getLength();
3447*cdf0e10cSrcweir 
3448*cdf0e10cSrcweir     // clear the filter control map
3449*cdf0e10cSrcweir     ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), RemoveComponentTextListener( this ) );
3450*cdf0e10cSrcweir     m_aFilterComponents.clear();
3451*cdf0e10cSrcweir 
3452*cdf0e10cSrcweir     for ( sal_Int32 i = nControlCount; i > 0; )
3453*cdf0e10cSrcweir     {
3454*cdf0e10cSrcweir         Reference< XControl > xControl = pControls[--i];
3455*cdf0e10cSrcweir         if (xControl.is())
3456*cdf0e10cSrcweir         {
3457*cdf0e10cSrcweir             // now enable eventhandling again
3458*cdf0e10cSrcweir             addToEventAttacher(xControl);
3459*cdf0e10cSrcweir 
3460*cdf0e10cSrcweir             Reference< XModeSelector >  xSelector(xControl, UNO_QUERY);
3461*cdf0e10cSrcweir             if (xSelector.is())
3462*cdf0e10cSrcweir             {
3463*cdf0e10cSrcweir                 xSelector->setMode( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ) );
3464*cdf0e10cSrcweir 
3465*cdf0e10cSrcweir                 // listening for new controls of the selector
3466*cdf0e10cSrcweir                 Reference< XContainer >  xContainer(xSelector, UNO_QUERY);
3467*cdf0e10cSrcweir                 if (xContainer.is())
3468*cdf0e10cSrcweir                     xContainer->removeContainerListener(this);
3469*cdf0e10cSrcweir                 continue;
3470*cdf0e10cSrcweir             }
3471*cdf0e10cSrcweir 
3472*cdf0e10cSrcweir             Reference< XPropertySet >  xSet(xControl->getModel(), UNO_QUERY);
3473*cdf0e10cSrcweir             if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
3474*cdf0e10cSrcweir             {
3475*cdf0e10cSrcweir                 // does the model use a bound field ?
3476*cdf0e10cSrcweir                 Reference< XPropertySet >  xField;
3477*cdf0e10cSrcweir                 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3478*cdf0e10cSrcweir 
3479*cdf0e10cSrcweir                 // may we filter the field?
3480*cdf0e10cSrcweir                 if  (   xField.is()
3481*cdf0e10cSrcweir                     &&  ::comphelper::hasProperty( FM_PROP_SEARCHABLE, xField )
3482*cdf0e10cSrcweir                     &&  ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_SEARCHABLE ) )
3483*cdf0e10cSrcweir                     )
3484*cdf0e10cSrcweir                 {
3485*cdf0e10cSrcweir                     ::rtl::OUString sServiceName;
3486*cdf0e10cSrcweir                     OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DEFAULTCONTROL ) >>= sServiceName );
3487*cdf0e10cSrcweir                     Reference< XControl > xNewControl( m_aContext.createComponent( sServiceName ), UNO_QUERY );
3488*cdf0e10cSrcweir                     replaceControl( xControl, xNewControl );
3489*cdf0e10cSrcweir                 }
3490*cdf0e10cSrcweir             }
3491*cdf0e10cSrcweir         }
3492*cdf0e10cSrcweir     }
3493*cdf0e10cSrcweir 
3494*cdf0e10cSrcweir     Reference< XPropertySet >  xSet( m_xModelAsIndex, UNO_QUERY );
3495*cdf0e10cSrcweir     if ( xSet.is() )
3496*cdf0e10cSrcweir 		startFormListening( xSet, sal_True );
3497*cdf0e10cSrcweir 
3498*cdf0e10cSrcweir     m_bDetachEvents = sal_True;
3499*cdf0e10cSrcweir 
3500*cdf0e10cSrcweir     m_aFilterRows.clear();
3501*cdf0e10cSrcweir     m_nCurrentFilterPosition = -1;
3502*cdf0e10cSrcweir 
3503*cdf0e10cSrcweir     // release the locks if possible
3504*cdf0e10cSrcweir     // lock all controls which are not used for filtering
3505*cdf0e10cSrcweir     m_bLocked = determineLockState();
3506*cdf0e10cSrcweir     setLocks();
3507*cdf0e10cSrcweir 
3508*cdf0e10cSrcweir     // restart listening for control modifications
3509*cdf0e10cSrcweir     if (isListeningForChanges())
3510*cdf0e10cSrcweir         startListening();
3511*cdf0e10cSrcweir }
3512*cdf0e10cSrcweir 
3513*cdf0e10cSrcweir // XModeSelector
3514*cdf0e10cSrcweir //------------------------------------------------------------------------------
3515*cdf0e10cSrcweir void FormController::setMode(const ::rtl::OUString& Mode) throw( NoSupportException, RuntimeException )
3516*cdf0e10cSrcweir {
3517*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3518*cdf0e10cSrcweir     impl_checkDisposed_throw();
3519*cdf0e10cSrcweir 
3520*cdf0e10cSrcweir     if (!supportsMode(Mode))
3521*cdf0e10cSrcweir         throw NoSupportException();
3522*cdf0e10cSrcweir 
3523*cdf0e10cSrcweir     if (Mode == m_aMode)
3524*cdf0e10cSrcweir         return;
3525*cdf0e10cSrcweir 
3526*cdf0e10cSrcweir     m_aMode = Mode;
3527*cdf0e10cSrcweir 
3528*cdf0e10cSrcweir     if ( Mode.equalsAscii( "FilterMode" ) )
3529*cdf0e10cSrcweir         startFiltering();
3530*cdf0e10cSrcweir     else
3531*cdf0e10cSrcweir         stopFiltering();
3532*cdf0e10cSrcweir 
3533*cdf0e10cSrcweir     for (FmFormControllers::const_iterator i = m_aChilds.begin();
3534*cdf0e10cSrcweir         i != m_aChilds.end(); ++i)
3535*cdf0e10cSrcweir     {
3536*cdf0e10cSrcweir 		Reference< XModeSelector > xMode(*i, UNO_QUERY);
3537*cdf0e10cSrcweir 		if ( xMode.is() )
3538*cdf0e10cSrcweir 			xMode->setMode(Mode);
3539*cdf0e10cSrcweir     }
3540*cdf0e10cSrcweir }
3541*cdf0e10cSrcweir 
3542*cdf0e10cSrcweir //------------------------------------------------------------------------------
3543*cdf0e10cSrcweir ::rtl::OUString SAL_CALL FormController::getMode(void) throw( RuntimeException )
3544*cdf0e10cSrcweir {
3545*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3546*cdf0e10cSrcweir     impl_checkDisposed_throw();
3547*cdf0e10cSrcweir 
3548*cdf0e10cSrcweir     return m_aMode;
3549*cdf0e10cSrcweir }
3550*cdf0e10cSrcweir 
3551*cdf0e10cSrcweir //------------------------------------------------------------------------------
3552*cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL FormController::getSupportedModes(void) throw( RuntimeException )
3553*cdf0e10cSrcweir {
3554*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3555*cdf0e10cSrcweir     impl_checkDisposed_throw();
3556*cdf0e10cSrcweir 
3557*cdf0e10cSrcweir     static Sequence< ::rtl::OUString > aModes;
3558*cdf0e10cSrcweir     if (!aModes.getLength())
3559*cdf0e10cSrcweir     {
3560*cdf0e10cSrcweir         aModes.realloc(2);
3561*cdf0e10cSrcweir         ::rtl::OUString* pModes = aModes.getArray();
3562*cdf0e10cSrcweir         pModes[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) );
3563*cdf0e10cSrcweir         pModes[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterMode" ) );
3564*cdf0e10cSrcweir     }
3565*cdf0e10cSrcweir     return aModes;
3566*cdf0e10cSrcweir }
3567*cdf0e10cSrcweir 
3568*cdf0e10cSrcweir //------------------------------------------------------------------------------
3569*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::supportsMode(const ::rtl::OUString& Mode) throw( RuntimeException )
3570*cdf0e10cSrcweir {
3571*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3572*cdf0e10cSrcweir     impl_checkDisposed_throw();
3573*cdf0e10cSrcweir 
3574*cdf0e10cSrcweir     Sequence< ::rtl::OUString > aModes(getSupportedModes());
3575*cdf0e10cSrcweir     const ::rtl::OUString* pModes = aModes.getConstArray();
3576*cdf0e10cSrcweir     for (sal_Int32 i = aModes.getLength(); i > 0; )
3577*cdf0e10cSrcweir     {
3578*cdf0e10cSrcweir         if (pModes[--i] == Mode)
3579*cdf0e10cSrcweir             return sal_True;
3580*cdf0e10cSrcweir     }
3581*cdf0e10cSrcweir     return sal_False;
3582*cdf0e10cSrcweir }
3583*cdf0e10cSrcweir 
3584*cdf0e10cSrcweir //------------------------------------------------------------------------------
3585*cdf0e10cSrcweir Window* FormController::getDialogParentWindow()
3586*cdf0e10cSrcweir {
3587*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3588*cdf0e10cSrcweir     Window* pParentWindow = NULL;
3589*cdf0e10cSrcweir     try
3590*cdf0e10cSrcweir     {
3591*cdf0e10cSrcweir         Reference< XControl > xContainerControl( getContainer(), UNO_QUERY_THROW );
3592*cdf0e10cSrcweir         Reference< XWindowPeer > xContainerPeer( xContainerControl->getPeer(), UNO_QUERY_THROW );
3593*cdf0e10cSrcweir         pParentWindow = VCLUnoHelper::GetWindow( xContainerPeer );
3594*cdf0e10cSrcweir     }
3595*cdf0e10cSrcweir     catch( const Exception& )
3596*cdf0e10cSrcweir     {
3597*cdf0e10cSrcweir 	    DBG_UNHANDLED_EXCEPTION();
3598*cdf0e10cSrcweir     }
3599*cdf0e10cSrcweir     return pParentWindow;
3600*cdf0e10cSrcweir }
3601*cdf0e10cSrcweir //------------------------------------------------------------------------------
3602*cdf0e10cSrcweir bool FormController::checkFormComponentValidity( ::rtl::OUString& /* [out] */ _rFirstInvalidityExplanation, Reference< XControlModel >& /* [out] */ _rxFirstInvalidModel ) SAL_THROW(())
3603*cdf0e10cSrcweir {
3604*cdf0e10cSrcweir     try
3605*cdf0e10cSrcweir     {
3606*cdf0e10cSrcweir         Reference< XEnumerationAccess > xControlEnumAcc( getModel(), UNO_QUERY );
3607*cdf0e10cSrcweir         Reference< XEnumeration > xControlEnumeration;
3608*cdf0e10cSrcweir         if ( xControlEnumAcc.is() )
3609*cdf0e10cSrcweir             xControlEnumeration = xControlEnumAcc->createEnumeration();
3610*cdf0e10cSrcweir         OSL_ENSURE( xControlEnumeration.is(), "FormController::checkFormComponentValidity: cannot enumerate the controls!" );
3611*cdf0e10cSrcweir         if ( !xControlEnumeration.is() )
3612*cdf0e10cSrcweir             // assume all valid
3613*cdf0e10cSrcweir             return true;
3614*cdf0e10cSrcweir 
3615*cdf0e10cSrcweir         Reference< XValidatableFormComponent > xValidatable;
3616*cdf0e10cSrcweir         while ( xControlEnumeration->hasMoreElements() )
3617*cdf0e10cSrcweir         {
3618*cdf0e10cSrcweir             if ( !( xControlEnumeration->nextElement() >>= xValidatable ) )
3619*cdf0e10cSrcweir                 // control does not support validation
3620*cdf0e10cSrcweir                 continue;
3621*cdf0e10cSrcweir 
3622*cdf0e10cSrcweir             if ( xValidatable->isValid() )
3623*cdf0e10cSrcweir                 continue;
3624*cdf0e10cSrcweir 
3625*cdf0e10cSrcweir             Reference< XValidator > xValidator( xValidatable->getValidator() );
3626*cdf0e10cSrcweir             OSL_ENSURE( xValidator.is(), "FormController::checkFormComponentValidity: invalid, but no validator?" );
3627*cdf0e10cSrcweir             if ( !xValidator.is() )
3628*cdf0e10cSrcweir                 // this violates the interface definition of css.form.validation.XValidatableFormComponent ...
3629*cdf0e10cSrcweir                 continue;
3630*cdf0e10cSrcweir 
3631*cdf0e10cSrcweir             _rFirstInvalidityExplanation = xValidator->explainInvalid( xValidatable->getCurrentValue() );
3632*cdf0e10cSrcweir             _rxFirstInvalidModel = _rxFirstInvalidModel.query( xValidatable );
3633*cdf0e10cSrcweir             return false;
3634*cdf0e10cSrcweir         }
3635*cdf0e10cSrcweir     }
3636*cdf0e10cSrcweir     catch( const Exception& )
3637*cdf0e10cSrcweir     {
3638*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
3639*cdf0e10cSrcweir     }
3640*cdf0e10cSrcweir     return true;
3641*cdf0e10cSrcweir }
3642*cdf0e10cSrcweir 
3643*cdf0e10cSrcweir //------------------------------------------------------------------------------
3644*cdf0e10cSrcweir Reference< XControl > FormController::locateControl( const Reference< XControlModel >& _rxModel ) SAL_THROW(())
3645*cdf0e10cSrcweir {
3646*cdf0e10cSrcweir     try
3647*cdf0e10cSrcweir     {
3648*cdf0e10cSrcweir         Sequence< Reference< XControl > > aControls( getControls() );
3649*cdf0e10cSrcweir         const Reference< XControl >* pControls = aControls.getConstArray();
3650*cdf0e10cSrcweir         const Reference< XControl >* pControlsEnd = aControls.getConstArray() + aControls.getLength();
3651*cdf0e10cSrcweir 
3652*cdf0e10cSrcweir         for ( ; pControls != pControlsEnd; ++pControls )
3653*cdf0e10cSrcweir         {
3654*cdf0e10cSrcweir             OSL_ENSURE( pControls->is(), "FormController::locateControl: NULL-control?" );
3655*cdf0e10cSrcweir             if ( pControls->is() )
3656*cdf0e10cSrcweir             {
3657*cdf0e10cSrcweir                 if ( ( *pControls)->getModel() == _rxModel )
3658*cdf0e10cSrcweir                     return *pControls;
3659*cdf0e10cSrcweir             }
3660*cdf0e10cSrcweir         }
3661*cdf0e10cSrcweir         OSL_ENSURE( sal_False, "FormController::locateControl: did not find a control for this model!" );
3662*cdf0e10cSrcweir     }
3663*cdf0e10cSrcweir     catch( const Exception& )
3664*cdf0e10cSrcweir     {
3665*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
3666*cdf0e10cSrcweir     }
3667*cdf0e10cSrcweir     return NULL;
3668*cdf0e10cSrcweir }
3669*cdf0e10cSrcweir 
3670*cdf0e10cSrcweir //------------------------------------------------------------------------------
3671*cdf0e10cSrcweir namespace
3672*cdf0e10cSrcweir {
3673*cdf0e10cSrcweir     void displayErrorSetFocus( const String& _rMessage, const Reference< XControl >& _rxFocusControl, Window* _pDialogParent )
3674*cdf0e10cSrcweir     {
3675*cdf0e10cSrcweir 	    SQLContext aError;
3676*cdf0e10cSrcweir 	    aError.Message = String( SVX_RES( RID_STR_WRITEERROR ) );
3677*cdf0e10cSrcweir 	    aError.Details = _rMessage;
3678*cdf0e10cSrcweir 	    displayException( aError, _pDialogParent );
3679*cdf0e10cSrcweir 
3680*cdf0e10cSrcweir         if ( _rxFocusControl.is() )
3681*cdf0e10cSrcweir         {
3682*cdf0e10cSrcweir             Reference< XWindow > xControlWindow( _rxFocusControl, UNO_QUERY );
3683*cdf0e10cSrcweir             OSL_ENSURE( xControlWindow.is(), "displayErrorSetFocus: invalid control!" );
3684*cdf0e10cSrcweir             if ( xControlWindow.is() )
3685*cdf0e10cSrcweir                 xControlWindow->setFocus();
3686*cdf0e10cSrcweir         }
3687*cdf0e10cSrcweir     }
3688*cdf0e10cSrcweir 
3689*cdf0e10cSrcweir     sal_Bool lcl_shouldValidateRequiredFields_nothrow( const Reference< XInterface >& _rxForm )
3690*cdf0e10cSrcweir     {
3691*cdf0e10cSrcweir         try
3692*cdf0e10cSrcweir         {
3693*cdf0e10cSrcweir             static ::rtl::OUString s_sFormsCheckRequiredFields( RTL_CONSTASCII_USTRINGPARAM( "FormsCheckRequiredFields" ) );
3694*cdf0e10cSrcweir 
3695*cdf0e10cSrcweir             // first, check whether the form has a property telling us the answer
3696*cdf0e10cSrcweir             // this allows people to use the XPropertyContainer interface of a form to control
3697*cdf0e10cSrcweir             // the behaviour on a per-form basis.
3698*cdf0e10cSrcweir             Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY_THROW );
3699*cdf0e10cSrcweir             Reference< XPropertySetInfo > xPSI( xFormProps->getPropertySetInfo() );
3700*cdf0e10cSrcweir             if ( xPSI->hasPropertyByName( s_sFormsCheckRequiredFields ) )
3701*cdf0e10cSrcweir             {
3702*cdf0e10cSrcweir                 sal_Bool bShouldValidate = true;
3703*cdf0e10cSrcweir                 OSL_VERIFY( xFormProps->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3704*cdf0e10cSrcweir                 return bShouldValidate;
3705*cdf0e10cSrcweir             }
3706*cdf0e10cSrcweir 
3707*cdf0e10cSrcweir             // next, check the data source which created the connection
3708*cdf0e10cSrcweir             Reference< XChild > xConnectionAsChild( xFormProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ), UNO_QUERY_THROW );
3709*cdf0e10cSrcweir             Reference< XPropertySet > xDataSource( xConnectionAsChild->getParent(), UNO_QUERY );
3710*cdf0e10cSrcweir             if ( !xDataSource.is() )
3711*cdf0e10cSrcweir                 // seldom (but possible): this is not a connection created by a data source
3712*cdf0e10cSrcweir                 return sal_True;
3713*cdf0e10cSrcweir 
3714*cdf0e10cSrcweir             Reference< XPropertySet > xDataSourceSettings(
3715*cdf0e10cSrcweir                 xDataSource->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings" ) ) ),
3716*cdf0e10cSrcweir                 UNO_QUERY_THROW );
3717*cdf0e10cSrcweir 
3718*cdf0e10cSrcweir             sal_Bool bShouldValidate = true;
3719*cdf0e10cSrcweir             OSL_VERIFY( xDataSourceSettings->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3720*cdf0e10cSrcweir             return bShouldValidate;
3721*cdf0e10cSrcweir         }
3722*cdf0e10cSrcweir         catch( const Exception& )
3723*cdf0e10cSrcweir         {
3724*cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
3725*cdf0e10cSrcweir         }
3726*cdf0e10cSrcweir 
3727*cdf0e10cSrcweir         return sal_True;
3728*cdf0e10cSrcweir     }
3729*cdf0e10cSrcweir }
3730*cdf0e10cSrcweir 
3731*cdf0e10cSrcweir // XRowSetApproveListener
3732*cdf0e10cSrcweir //------------------------------------------------------------------------------
3733*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::approveRowChange(const RowChangeEvent& _rEvent) throw( RuntimeException )
3734*cdf0e10cSrcweir {
3735*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
3736*cdf0e10cSrcweir     impl_checkDisposed_throw();
3737*cdf0e10cSrcweir 
3738*cdf0e10cSrcweir     ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3739*cdf0e10cSrcweir     sal_Bool bValid = sal_True;
3740*cdf0e10cSrcweir     if (aIter.hasMoreElements())
3741*cdf0e10cSrcweir     {
3742*cdf0e10cSrcweir         RowChangeEvent aEvt( _rEvent );
3743*cdf0e10cSrcweir         aEvt.Source = *this;
3744*cdf0e10cSrcweir         bValid = ((XRowSetApproveListener*)aIter.next())->approveRowChange(aEvt);
3745*cdf0e10cSrcweir     }
3746*cdf0e10cSrcweir 
3747*cdf0e10cSrcweir     if ( !bValid )
3748*cdf0e10cSrcweir         return bValid;
3749*cdf0e10cSrcweir 
3750*cdf0e10cSrcweir     if  (   ( _rEvent.Action != RowChangeAction::INSERT )
3751*cdf0e10cSrcweir         &&  ( _rEvent.Action != RowChangeAction::UPDATE )
3752*cdf0e10cSrcweir         )
3753*cdf0e10cSrcweir         return bValid;
3754*cdf0e10cSrcweir 
3755*cdf0e10cSrcweir     // if some of the control models are bound to validators, check them
3756*cdf0e10cSrcweir     ::rtl::OUString sInvalidityExplanation;
3757*cdf0e10cSrcweir     Reference< XControlModel > xInvalidModel;
3758*cdf0e10cSrcweir     if ( !checkFormComponentValidity( sInvalidityExplanation, xInvalidModel ) )
3759*cdf0e10cSrcweir     {
3760*cdf0e10cSrcweir         Reference< XControl > xControl( locateControl( xInvalidModel ) );
3761*cdf0e10cSrcweir         aGuard.clear();
3762*cdf0e10cSrcweir         displayErrorSetFocus( sInvalidityExplanation, xControl, getDialogParentWindow() );
3763*cdf0e10cSrcweir         return false;
3764*cdf0e10cSrcweir     }
3765*cdf0e10cSrcweir 
3766*cdf0e10cSrcweir     // check values on NULL and required flag
3767*cdf0e10cSrcweir     if ( !lcl_shouldValidateRequiredFields_nothrow( _rEvent.Source ) )
3768*cdf0e10cSrcweir         return sal_True;
3769*cdf0e10cSrcweir 
3770*cdf0e10cSrcweir     OSL_ENSURE( m_pColumnInfoCache.get(), "FormController::approveRowChange: no column infos!" );
3771*cdf0e10cSrcweir     if ( !m_pColumnInfoCache.get() )
3772*cdf0e10cSrcweir         return sal_True;
3773*cdf0e10cSrcweir 
3774*cdf0e10cSrcweir     try
3775*cdf0e10cSrcweir     {
3776*cdf0e10cSrcweir         if ( !m_pColumnInfoCache->controlsInitialized() )
3777*cdf0e10cSrcweir             m_pColumnInfoCache->initializeControls( getControls() );
3778*cdf0e10cSrcweir 
3779*cdf0e10cSrcweir         size_t colCount = m_pColumnInfoCache->getColumnCount();
3780*cdf0e10cSrcweir         for ( size_t col = 0; col < colCount; ++col )
3781*cdf0e10cSrcweir         {
3782*cdf0e10cSrcweir             const ColumnInfo& rColInfo = m_pColumnInfoCache->getColumnInfo( col );
3783*cdf0e10cSrcweir             if ( rColInfo.nNullable != ColumnValue::NO_NULLS )
3784*cdf0e10cSrcweir                 continue;
3785*cdf0e10cSrcweir 
3786*cdf0e10cSrcweir             if ( rColInfo.bAutoIncrement )
3787*cdf0e10cSrcweir                 continue;
3788*cdf0e10cSrcweir 
3789*cdf0e10cSrcweir             if ( rColInfo.bReadOnly )
3790*cdf0e10cSrcweir                 continue;
3791*cdf0e10cSrcweir 
3792*cdf0e10cSrcweir             if ( !rColInfo.xFirstControlWithInputRequired.is() && !rColInfo.xFirstGridWithInputRequiredColumn.is() )
3793*cdf0e10cSrcweir                 continue;
3794*cdf0e10cSrcweir 
3795*cdf0e10cSrcweir             // TODO: in case of binary fields, this "getString" below is extremely expensive
3796*cdf0e10cSrcweir             if ( rColInfo.xColumn->getString().getLength() || !rColInfo.xColumn->wasNull() )
3797*cdf0e10cSrcweir                 continue;
3798*cdf0e10cSrcweir 
3799*cdf0e10cSrcweir             String sMessage( SVX_RES( RID_ERR_FIELDREQUIRED ) );
3800*cdf0e10cSrcweir             sMessage.SearchAndReplace( '#', rColInfo.sName );
3801*cdf0e10cSrcweir 
3802*cdf0e10cSrcweir             // the control to focus
3803*cdf0e10cSrcweir             Reference< XControl > xControl( rColInfo.xFirstControlWithInputRequired );
3804*cdf0e10cSrcweir             if ( !xControl.is() )
3805*cdf0e10cSrcweir                 xControl.set( rColInfo.xFirstGridWithInputRequiredColumn, UNO_QUERY );
3806*cdf0e10cSrcweir 
3807*cdf0e10cSrcweir             aGuard.clear();
3808*cdf0e10cSrcweir             displayErrorSetFocus( sMessage, rColInfo.xFirstControlWithInputRequired, getDialogParentWindow() );
3809*cdf0e10cSrcweir             return sal_False;
3810*cdf0e10cSrcweir         }
3811*cdf0e10cSrcweir     }
3812*cdf0e10cSrcweir     catch( const Exception& )
3813*cdf0e10cSrcweir     {
3814*cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
3815*cdf0e10cSrcweir     }
3816*cdf0e10cSrcweir 
3817*cdf0e10cSrcweir     return true;
3818*cdf0e10cSrcweir }
3819*cdf0e10cSrcweir 
3820*cdf0e10cSrcweir //------------------------------------------------------------------------------
3821*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::approveCursorMove(const EventObject& event) throw( RuntimeException )
3822*cdf0e10cSrcweir {
3823*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3824*cdf0e10cSrcweir     impl_checkDisposed_throw();
3825*cdf0e10cSrcweir 
3826*cdf0e10cSrcweir     ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3827*cdf0e10cSrcweir     if (aIter.hasMoreElements())
3828*cdf0e10cSrcweir     {
3829*cdf0e10cSrcweir         EventObject aEvt(event);
3830*cdf0e10cSrcweir         aEvt.Source = *this;
3831*cdf0e10cSrcweir         return ((XRowSetApproveListener*)aIter.next())->approveCursorMove(aEvt);
3832*cdf0e10cSrcweir     }
3833*cdf0e10cSrcweir 
3834*cdf0e10cSrcweir     return sal_True;
3835*cdf0e10cSrcweir }
3836*cdf0e10cSrcweir 
3837*cdf0e10cSrcweir //------------------------------------------------------------------------------
3838*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::approveRowSetChange(const EventObject& event) throw( RuntimeException )
3839*cdf0e10cSrcweir {
3840*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3841*cdf0e10cSrcweir     impl_checkDisposed_throw();
3842*cdf0e10cSrcweir 
3843*cdf0e10cSrcweir     ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3844*cdf0e10cSrcweir     if (aIter.hasMoreElements())
3845*cdf0e10cSrcweir     {
3846*cdf0e10cSrcweir         EventObject aEvt(event);
3847*cdf0e10cSrcweir         aEvt.Source = *this;
3848*cdf0e10cSrcweir         return ((XRowSetApproveListener*)aIter.next())->approveRowSetChange(aEvt);
3849*cdf0e10cSrcweir     }
3850*cdf0e10cSrcweir 
3851*cdf0e10cSrcweir     return sal_True;
3852*cdf0e10cSrcweir }
3853*cdf0e10cSrcweir 
3854*cdf0e10cSrcweir // XRowSetApproveBroadcaster
3855*cdf0e10cSrcweir //------------------------------------------------------------------------------
3856*cdf0e10cSrcweir void SAL_CALL FormController::addRowSetApproveListener(const Reference< XRowSetApproveListener > & _rxListener) throw( RuntimeException )
3857*cdf0e10cSrcweir {
3858*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3859*cdf0e10cSrcweir     impl_checkDisposed_throw();
3860*cdf0e10cSrcweir 
3861*cdf0e10cSrcweir     m_aRowSetApproveListeners.addInterface(_rxListener);
3862*cdf0e10cSrcweir }
3863*cdf0e10cSrcweir 
3864*cdf0e10cSrcweir //------------------------------------------------------------------------------
3865*cdf0e10cSrcweir void SAL_CALL FormController::removeRowSetApproveListener(const Reference< XRowSetApproveListener > & _rxListener) throw( RuntimeException )
3866*cdf0e10cSrcweir {
3867*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3868*cdf0e10cSrcweir     impl_checkDisposed_throw();
3869*cdf0e10cSrcweir 
3870*cdf0e10cSrcweir     m_aRowSetApproveListeners.removeInterface(_rxListener);
3871*cdf0e10cSrcweir }
3872*cdf0e10cSrcweir 
3873*cdf0e10cSrcweir // XErrorListener
3874*cdf0e10cSrcweir //------------------------------------------------------------------------------
3875*cdf0e10cSrcweir void SAL_CALL FormController::errorOccured(const SQLErrorEvent& aEvent) throw( RuntimeException )
3876*cdf0e10cSrcweir {
3877*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
3878*cdf0e10cSrcweir     impl_checkDisposed_throw();
3879*cdf0e10cSrcweir 
3880*cdf0e10cSrcweir     ::cppu::OInterfaceIteratorHelper aIter(m_aErrorListeners);
3881*cdf0e10cSrcweir     if (aIter.hasMoreElements())
3882*cdf0e10cSrcweir     {
3883*cdf0e10cSrcweir         SQLErrorEvent aEvt(aEvent);
3884*cdf0e10cSrcweir         aEvt.Source = *this;
3885*cdf0e10cSrcweir         ((XSQLErrorListener*)aIter.next())->errorOccured(aEvt);
3886*cdf0e10cSrcweir     }
3887*cdf0e10cSrcweir     else
3888*cdf0e10cSrcweir     {
3889*cdf0e10cSrcweir         aGuard.clear();
3890*cdf0e10cSrcweir         displayException( aEvent );
3891*cdf0e10cSrcweir     }
3892*cdf0e10cSrcweir }
3893*cdf0e10cSrcweir 
3894*cdf0e10cSrcweir // XErrorBroadcaster
3895*cdf0e10cSrcweir //------------------------------------------------------------------------------
3896*cdf0e10cSrcweir void SAL_CALL FormController::addSQLErrorListener(const Reference< XSQLErrorListener > & aListener) throw( RuntimeException )
3897*cdf0e10cSrcweir {
3898*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3899*cdf0e10cSrcweir     impl_checkDisposed_throw();
3900*cdf0e10cSrcweir 
3901*cdf0e10cSrcweir     m_aErrorListeners.addInterface(aListener);
3902*cdf0e10cSrcweir }
3903*cdf0e10cSrcweir 
3904*cdf0e10cSrcweir //------------------------------------------------------------------------------
3905*cdf0e10cSrcweir void SAL_CALL FormController::removeSQLErrorListener(const Reference< XSQLErrorListener > & aListener) throw( RuntimeException )
3906*cdf0e10cSrcweir {
3907*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3908*cdf0e10cSrcweir     impl_checkDisposed_throw();
3909*cdf0e10cSrcweir 
3910*cdf0e10cSrcweir     m_aErrorListeners.removeInterface(aListener);
3911*cdf0e10cSrcweir }
3912*cdf0e10cSrcweir 
3913*cdf0e10cSrcweir // XDatabaseParameterBroadcaster2
3914*cdf0e10cSrcweir //------------------------------------------------------------------------------
3915*cdf0e10cSrcweir void SAL_CALL FormController::addDatabaseParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3916*cdf0e10cSrcweir {
3917*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3918*cdf0e10cSrcweir     impl_checkDisposed_throw();
3919*cdf0e10cSrcweir 
3920*cdf0e10cSrcweir     m_aParameterListeners.addInterface(aListener);
3921*cdf0e10cSrcweir }
3922*cdf0e10cSrcweir 
3923*cdf0e10cSrcweir //------------------------------------------------------------------------------
3924*cdf0e10cSrcweir void SAL_CALL FormController::removeDatabaseParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3925*cdf0e10cSrcweir {
3926*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3927*cdf0e10cSrcweir     impl_checkDisposed_throw();
3928*cdf0e10cSrcweir 
3929*cdf0e10cSrcweir     m_aParameterListeners.removeInterface(aListener);
3930*cdf0e10cSrcweir }
3931*cdf0e10cSrcweir 
3932*cdf0e10cSrcweir // XDatabaseParameterBroadcaster
3933*cdf0e10cSrcweir //------------------------------------------------------------------------------
3934*cdf0e10cSrcweir void SAL_CALL FormController::addParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3935*cdf0e10cSrcweir {
3936*cdf0e10cSrcweir     FormController::addDatabaseParameterListener( aListener );
3937*cdf0e10cSrcweir }
3938*cdf0e10cSrcweir 
3939*cdf0e10cSrcweir //------------------------------------------------------------------------------
3940*cdf0e10cSrcweir void SAL_CALL FormController::removeParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3941*cdf0e10cSrcweir {
3942*cdf0e10cSrcweir     FormController::removeDatabaseParameterListener( aListener );
3943*cdf0e10cSrcweir }
3944*cdf0e10cSrcweir 
3945*cdf0e10cSrcweir // XDatabaseParameterListener
3946*cdf0e10cSrcweir //------------------------------------------------------------------------------
3947*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::approveParameter(const DatabaseParameterEvent& aEvent) throw( RuntimeException )
3948*cdf0e10cSrcweir {
3949*cdf0e10cSrcweir     ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
3950*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
3951*cdf0e10cSrcweir     impl_checkDisposed_throw();
3952*cdf0e10cSrcweir 
3953*cdf0e10cSrcweir     ::cppu::OInterfaceIteratorHelper aIter(m_aParameterListeners);
3954*cdf0e10cSrcweir     if (aIter.hasMoreElements())
3955*cdf0e10cSrcweir     {
3956*cdf0e10cSrcweir         DatabaseParameterEvent aEvt(aEvent);
3957*cdf0e10cSrcweir         aEvt.Source = *this;
3958*cdf0e10cSrcweir         return ((XDatabaseParameterListener*)aIter.next())->approveParameter(aEvt);
3959*cdf0e10cSrcweir     }
3960*cdf0e10cSrcweir     else
3961*cdf0e10cSrcweir     {
3962*cdf0e10cSrcweir         // default handling: instantiate an interaction handler and let it handle the parameter request
3963*cdf0e10cSrcweir         try
3964*cdf0e10cSrcweir         {
3965*cdf0e10cSrcweir             if ( !ensureInteractionHandler() )
3966*cdf0e10cSrcweir                 return sal_False;
3967*cdf0e10cSrcweir 
3968*cdf0e10cSrcweir             // two continuations allowed: OK and Cancel
3969*cdf0e10cSrcweir             OParameterContinuation* pParamValues = new OParameterContinuation;
3970*cdf0e10cSrcweir             OInteractionAbort* pAbort = new OInteractionAbort;
3971*cdf0e10cSrcweir             // the request
3972*cdf0e10cSrcweir             ParametersRequest aRequest;
3973*cdf0e10cSrcweir             aRequest.Parameters = aEvent.Parameters;
3974*cdf0e10cSrcweir             aRequest.Connection = OStaticDataAccessTools().getRowSetConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
3975*cdf0e10cSrcweir             OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
3976*cdf0e10cSrcweir             Reference< XInteractionRequest > xParamRequest(pParamRequest);
3977*cdf0e10cSrcweir             // some knittings
3978*cdf0e10cSrcweir             pParamRequest->addContinuation(pParamValues);
3979*cdf0e10cSrcweir             pParamRequest->addContinuation(pAbort);
3980*cdf0e10cSrcweir 
3981*cdf0e10cSrcweir             // handle the request
3982*cdf0e10cSrcweir             m_xInteractionHandler->handle(xParamRequest);
3983*cdf0e10cSrcweir 
3984*cdf0e10cSrcweir             if (!pParamValues->wasSelected())
3985*cdf0e10cSrcweir                 // canceled
3986*cdf0e10cSrcweir                 return sal_False;
3987*cdf0e10cSrcweir 
3988*cdf0e10cSrcweir             // transfer the values into the parameter supplier
3989*cdf0e10cSrcweir             Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
3990*cdf0e10cSrcweir             if (aFinalValues.getLength() != aRequest.Parameters->getCount())
3991*cdf0e10cSrcweir             {
3992*cdf0e10cSrcweir                 DBG_ERROR("FormController::approveParameter: the InteractionHandler returned nonsense!");
3993*cdf0e10cSrcweir                 return sal_False;
3994*cdf0e10cSrcweir             }
3995*cdf0e10cSrcweir             const PropertyValue* pFinalValues = aFinalValues.getConstArray();
3996*cdf0e10cSrcweir             for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
3997*cdf0e10cSrcweir             {
3998*cdf0e10cSrcweir                 Reference< XPropertySet > xParam;
3999*cdf0e10cSrcweir                 ::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i));
4000*cdf0e10cSrcweir                 if (xParam.is())
4001*cdf0e10cSrcweir                 {
4002*cdf0e10cSrcweir #ifdef DBG_UTIL
4003*cdf0e10cSrcweir                     ::rtl::OUString sName;
4004*cdf0e10cSrcweir                     xParam->getPropertyValue(FM_PROP_NAME) >>= sName;
4005*cdf0e10cSrcweir                     DBG_ASSERT(sName.equals(pFinalValues->Name), "FormController::approveParameter: suspicious value names!");
4006*cdf0e10cSrcweir #endif
4007*cdf0e10cSrcweir                     try { xParam->setPropertyValue(FM_PROP_VALUE, pFinalValues->Value); }
4008*cdf0e10cSrcweir                     catch(Exception&)
4009*cdf0e10cSrcweir                     {
4010*cdf0e10cSrcweir                         DBG_ERROR("FormController::approveParameter: setting one of the properties failed!");
4011*cdf0e10cSrcweir                     }
4012*cdf0e10cSrcweir                 }
4013*cdf0e10cSrcweir             }
4014*cdf0e10cSrcweir         }
4015*cdf0e10cSrcweir         catch(Exception&)
4016*cdf0e10cSrcweir         {
4017*cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
4018*cdf0e10cSrcweir         }
4019*cdf0e10cSrcweir     }
4020*cdf0e10cSrcweir     return sal_True;
4021*cdf0e10cSrcweir }
4022*cdf0e10cSrcweir 
4023*cdf0e10cSrcweir // XConfirmDeleteBroadcaster
4024*cdf0e10cSrcweir //------------------------------------------------------------------------------
4025*cdf0e10cSrcweir void SAL_CALL FormController::addConfirmDeleteListener(const Reference< XConfirmDeleteListener > & aListener) throw( RuntimeException )
4026*cdf0e10cSrcweir {
4027*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
4028*cdf0e10cSrcweir     impl_checkDisposed_throw();
4029*cdf0e10cSrcweir 
4030*cdf0e10cSrcweir     m_aDeleteListeners.addInterface(aListener);
4031*cdf0e10cSrcweir }
4032*cdf0e10cSrcweir 
4033*cdf0e10cSrcweir //------------------------------------------------------------------------------
4034*cdf0e10cSrcweir void SAL_CALL FormController::removeConfirmDeleteListener(const Reference< XConfirmDeleteListener > & aListener) throw( RuntimeException )
4035*cdf0e10cSrcweir {
4036*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
4037*cdf0e10cSrcweir     impl_checkDisposed_throw();
4038*cdf0e10cSrcweir 
4039*cdf0e10cSrcweir     m_aDeleteListeners.removeInterface(aListener);
4040*cdf0e10cSrcweir }
4041*cdf0e10cSrcweir 
4042*cdf0e10cSrcweir // XConfirmDeleteListener
4043*cdf0e10cSrcweir //------------------------------------------------------------------------------
4044*cdf0e10cSrcweir sal_Bool SAL_CALL FormController::confirmDelete(const RowChangeEvent& aEvent) throw( RuntimeException )
4045*cdf0e10cSrcweir {
4046*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
4047*cdf0e10cSrcweir     impl_checkDisposed_throw();
4048*cdf0e10cSrcweir 
4049*cdf0e10cSrcweir     ::cppu::OInterfaceIteratorHelper aIter(m_aDeleteListeners);
4050*cdf0e10cSrcweir     if (aIter.hasMoreElements())
4051*cdf0e10cSrcweir     {
4052*cdf0e10cSrcweir         RowChangeEvent aEvt(aEvent);
4053*cdf0e10cSrcweir         aEvt.Source = *this;
4054*cdf0e10cSrcweir         return ((XConfirmDeleteListener*)aIter.next())->confirmDelete(aEvt);
4055*cdf0e10cSrcweir     }
4056*cdf0e10cSrcweir     // default handling: instantiate an interaction handler and let it handle the request
4057*cdf0e10cSrcweir 
4058*cdf0e10cSrcweir     String sTitle;
4059*cdf0e10cSrcweir     sal_Int32 nLength = aEvent.Rows;
4060*cdf0e10cSrcweir     if ( nLength > 1 )
4061*cdf0e10cSrcweir     {
4062*cdf0e10cSrcweir         sTitle = SVX_RES( RID_STR_DELETECONFIRM_RECORDS );
4063*cdf0e10cSrcweir         sTitle.SearchAndReplace( '#', String::CreateFromInt32( nLength ) );
4064*cdf0e10cSrcweir     }
4065*cdf0e10cSrcweir     else
4066*cdf0e10cSrcweir         sTitle = SVX_RES( RID_STR_DELETECONFIRM_RECORD );
4067*cdf0e10cSrcweir 
4068*cdf0e10cSrcweir     try
4069*cdf0e10cSrcweir     {
4070*cdf0e10cSrcweir         if ( !ensureInteractionHandler() )
4071*cdf0e10cSrcweir             return sal_False;
4072*cdf0e10cSrcweir 
4073*cdf0e10cSrcweir         // two continuations allowed: Yes and No
4074*cdf0e10cSrcweir         OInteractionApprove* pApprove = new OInteractionApprove;
4075*cdf0e10cSrcweir         OInteractionDisapprove* pDisapprove = new OInteractionDisapprove;
4076*cdf0e10cSrcweir 
4077*cdf0e10cSrcweir         // the request
4078*cdf0e10cSrcweir         SQLWarning aWarning;
4079*cdf0e10cSrcweir         aWarning.Message = sTitle;
4080*cdf0e10cSrcweir         SQLWarning aDetails;
4081*cdf0e10cSrcweir         aDetails.Message = String( SVX_RES( RID_STR_DELETECONFIRM ) );
4082*cdf0e10cSrcweir         aWarning.NextException <<= aDetails;
4083*cdf0e10cSrcweir 
4084*cdf0e10cSrcweir         OInteractionRequest* pRequest = new OInteractionRequest( makeAny( aWarning ) );
4085*cdf0e10cSrcweir         Reference< XInteractionRequest > xRequest( pRequest );
4086*cdf0e10cSrcweir 
4087*cdf0e10cSrcweir         // some knittings
4088*cdf0e10cSrcweir         pRequest->addContinuation( pApprove );
4089*cdf0e10cSrcweir         pRequest->addContinuation( pDisapprove );
4090*cdf0e10cSrcweir 
4091*cdf0e10cSrcweir         // handle the request
4092*cdf0e10cSrcweir         m_xInteractionHandler->handle( xRequest );
4093*cdf0e10cSrcweir 
4094*cdf0e10cSrcweir         if ( pApprove->wasSelected() )
4095*cdf0e10cSrcweir             return sal_True;
4096*cdf0e10cSrcweir     }
4097*cdf0e10cSrcweir     catch( const Exception& )
4098*cdf0e10cSrcweir     {
4099*cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
4100*cdf0e10cSrcweir     }
4101*cdf0e10cSrcweir 
4102*cdf0e10cSrcweir     return sal_False;
4103*cdf0e10cSrcweir }
4104*cdf0e10cSrcweir 
4105*cdf0e10cSrcweir //------------------------------------------------------------------------------
4106*cdf0e10cSrcweir void SAL_CALL FormController::invalidateFeatures( const Sequence< ::sal_Int16 >& _Features ) throw (RuntimeException)
4107*cdf0e10cSrcweir {
4108*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
4109*cdf0e10cSrcweir     // for now, just copy the ids of the features, because ....
4110*cdf0e10cSrcweir     ::std::copy( _Features.getConstArray(), _Features.getConstArray() + _Features.getLength(),
4111*cdf0e10cSrcweir         ::std::insert_iterator< ::std::set< sal_Int16 > >( m_aInvalidFeatures, m_aInvalidFeatures.begin() )
4112*cdf0e10cSrcweir     );
4113*cdf0e10cSrcweir 
4114*cdf0e10cSrcweir     // ... we will do the real invalidation asynchronously
4115*cdf0e10cSrcweir     if ( !m_aFeatureInvalidationTimer.IsActive() )
4116*cdf0e10cSrcweir         m_aFeatureInvalidationTimer.Start();
4117*cdf0e10cSrcweir }
4118*cdf0e10cSrcweir 
4119*cdf0e10cSrcweir //------------------------------------------------------------------------------
4120*cdf0e10cSrcweir void SAL_CALL FormController::invalidateAllFeatures(  ) throw (RuntimeException)
4121*cdf0e10cSrcweir {
4122*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( m_aMutex );
4123*cdf0e10cSrcweir 
4124*cdf0e10cSrcweir     Sequence< sal_Int16 > aInterceptedFeatures( m_aFeatureDispatchers.size() );
4125*cdf0e10cSrcweir     ::std::transform(
4126*cdf0e10cSrcweir         m_aFeatureDispatchers.begin(),
4127*cdf0e10cSrcweir         m_aFeatureDispatchers.end(),
4128*cdf0e10cSrcweir         aInterceptedFeatures.getArray(),
4129*cdf0e10cSrcweir         ::std::select1st< DispatcherContainer::value_type >()
4130*cdf0e10cSrcweir     );
4131*cdf0e10cSrcweir 
4132*cdf0e10cSrcweir     aGuard.clear();
4133*cdf0e10cSrcweir     if ( aInterceptedFeatures.getLength() )
4134*cdf0e10cSrcweir         invalidateFeatures( aInterceptedFeatures );
4135*cdf0e10cSrcweir }
4136*cdf0e10cSrcweir 
4137*cdf0e10cSrcweir //------------------------------------------------------------------------------
4138*cdf0e10cSrcweir Reference< XDispatch >
4139*cdf0e10cSrcweir FormController::interceptedQueryDispatch( const URL& aURL,
4140*cdf0e10cSrcweir                                             const ::rtl::OUString& /*aTargetFrameName*/, sal_Int32 /*nSearchFlags*/)
4141*cdf0e10cSrcweir                                             throw( RuntimeException )
4142*cdf0e10cSrcweir {
4143*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
4144*cdf0e10cSrcweir     Reference< XDispatch >  xReturn;
4145*cdf0e10cSrcweir     // dispatches handled by ourself
4146*cdf0e10cSrcweir     if  (   ( aURL.Complete == FMURL_CONFIRM_DELETION )
4147*cdf0e10cSrcweir         ||  (   ( aURL.Complete.equalsAscii( "private:/InteractionHandler" ) )
4148*cdf0e10cSrcweir             &&  ensureInteractionHandler()
4149*cdf0e10cSrcweir             )
4150*cdf0e10cSrcweir         )
4151*cdf0e10cSrcweir 		xReturn = static_cast< XDispatch* >( this );
4152*cdf0e10cSrcweir 
4153*cdf0e10cSrcweir     // dispatches of FormSlot-URLs we have to translate
4154*cdf0e10cSrcweir     if ( !xReturn.is() && m_xFormOperations.is() )
4155*cdf0e10cSrcweir     {
4156*cdf0e10cSrcweir         // find the slot id which corresponds to the URL
4157*cdf0e10cSrcweir         sal_Int32 nFeatureSlotId = ::svx::FeatureSlotTranslation::getControllerFeatureSlotIdForURL( aURL.Main );
4158*cdf0e10cSrcweir         sal_Int16 nFormFeature = ( nFeatureSlotId != -1 ) ? ::svx::FeatureSlotTranslation::getFormFeatureForSlotId( nFeatureSlotId ) : -1;
4159*cdf0e10cSrcweir         if ( nFormFeature > 0 )
4160*cdf0e10cSrcweir         {
4161*cdf0e10cSrcweir             // get the dispatcher for this feature, create if necessary
4162*cdf0e10cSrcweir             DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( nFormFeature );
4163*cdf0e10cSrcweir             if ( aDispatcherPos == m_aFeatureDispatchers.end() )
4164*cdf0e10cSrcweir             {
4165*cdf0e10cSrcweir                 aDispatcherPos = m_aFeatureDispatchers.insert(
4166*cdf0e10cSrcweir                     DispatcherContainer::value_type( nFormFeature, new ::svx::OSingleFeatureDispatcher( aURL, nFormFeature, m_xFormOperations, m_aMutex ) )
4167*cdf0e10cSrcweir                 ).first;
4168*cdf0e10cSrcweir             }
4169*cdf0e10cSrcweir 
4170*cdf0e10cSrcweir             OSL_ENSURE( aDispatcherPos->second.is(), "FormController::interceptedQueryDispatch: should have a dispatcher by now!" );
4171*cdf0e10cSrcweir             return aDispatcherPos->second;
4172*cdf0e10cSrcweir         }
4173*cdf0e10cSrcweir     }
4174*cdf0e10cSrcweir 
4175*cdf0e10cSrcweir     // no more to offer
4176*cdf0e10cSrcweir     return xReturn;
4177*cdf0e10cSrcweir }
4178*cdf0e10cSrcweir 
4179*cdf0e10cSrcweir //------------------------------------------------------------------------------
4180*cdf0e10cSrcweir void SAL_CALL FormController::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArgs ) throw (RuntimeException)
4181*cdf0e10cSrcweir {
4182*cdf0e10cSrcweir     if ( _rArgs.getLength() != 1 )
4183*cdf0e10cSrcweir     {
4184*cdf0e10cSrcweir         DBG_ERROR( "FormController::dispatch: no arguments -> no dispatch!" );
4185*cdf0e10cSrcweir         return;
4186*cdf0e10cSrcweir     }
4187*cdf0e10cSrcweir 
4188*cdf0e10cSrcweir     if ( _rURL.Complete.equalsAscii( "private:/InteractionHandler" ) )
4189*cdf0e10cSrcweir     {
4190*cdf0e10cSrcweir         Reference< XInteractionRequest > xRequest;
4191*cdf0e10cSrcweir         OSL_VERIFY( _rArgs[0].Value >>= xRequest );
4192*cdf0e10cSrcweir         if ( xRequest.is() )
4193*cdf0e10cSrcweir             handle( xRequest );
4194*cdf0e10cSrcweir         return;
4195*cdf0e10cSrcweir     }
4196*cdf0e10cSrcweir 
4197*cdf0e10cSrcweir     if  ( _rURL.Complete == FMURL_CONFIRM_DELETION )
4198*cdf0e10cSrcweir     {
4199*cdf0e10cSrcweir         DBG_ERROR( "FormController::dispatch: How do you expect me to return something via this call?" );
4200*cdf0e10cSrcweir             // confirmDelete has a return value - dispatch hasn't
4201*cdf0e10cSrcweir         return;
4202*cdf0e10cSrcweir     }
4203*cdf0e10cSrcweir 
4204*cdf0e10cSrcweir 	DBG_ERROR( "FormController::dispatch: unknown URL!" );
4205*cdf0e10cSrcweir }
4206*cdf0e10cSrcweir 
4207*cdf0e10cSrcweir //------------------------------------------------------------------------------
4208*cdf0e10cSrcweir void SAL_CALL FormController::addStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
4209*cdf0e10cSrcweir {
4210*cdf0e10cSrcweir     if (_rURL.Complete == FMURL_CONFIRM_DELETION)
4211*cdf0e10cSrcweir 	{
4212*cdf0e10cSrcweir 		if (_rxListener.is())
4213*cdf0e10cSrcweir 		{	// send an initial statusChanged event
4214*cdf0e10cSrcweir 			FeatureStateEvent aEvent;
4215*cdf0e10cSrcweir 			aEvent.FeatureURL = _rURL;
4216*cdf0e10cSrcweir 			aEvent.IsEnabled = sal_True;
4217*cdf0e10cSrcweir 			_rxListener->statusChanged(aEvent);
4218*cdf0e10cSrcweir 			// and don't add the listener at all (the status will never change)
4219*cdf0e10cSrcweir 		}
4220*cdf0e10cSrcweir 	}
4221*cdf0e10cSrcweir 	else
4222*cdf0e10cSrcweir 		OSL_ENSURE(sal_False, "FormController::addStatusListener: invalid (unsupported) URL!");
4223*cdf0e10cSrcweir }
4224*cdf0e10cSrcweir 
4225*cdf0e10cSrcweir //------------------------------------------------------------------------------
4226*cdf0e10cSrcweir Reference< XInterface > SAL_CALL FormController::getParent() throw( RuntimeException )
4227*cdf0e10cSrcweir {
4228*cdf0e10cSrcweir     return m_xParent;
4229*cdf0e10cSrcweir }
4230*cdf0e10cSrcweir 
4231*cdf0e10cSrcweir //------------------------------------------------------------------------------
4232*cdf0e10cSrcweir void SAL_CALL FormController::setParent( const Reference< XInterface >& Parent) throw( NoSupportException, RuntimeException )
4233*cdf0e10cSrcweir {
4234*cdf0e10cSrcweir     m_xParent = Parent;
4235*cdf0e10cSrcweir }
4236*cdf0e10cSrcweir 
4237*cdf0e10cSrcweir //------------------------------------------------------------------------------
4238*cdf0e10cSrcweir void SAL_CALL FormController::removeStatusListener( const Reference< XStatusListener >& /*_rxListener*/, const URL& _rURL ) throw (RuntimeException)
4239*cdf0e10cSrcweir {
4240*cdf0e10cSrcweir     (void)_rURL;
4241*cdf0e10cSrcweir 	OSL_ENSURE(_rURL.Complete == FMURL_CONFIRM_DELETION, "FormController::removeStatusListener: invalid (unsupported) URL!");
4242*cdf0e10cSrcweir 	// we never really added the listener, so we don't need to remove it
4243*cdf0e10cSrcweir }
4244*cdf0e10cSrcweir 
4245*cdf0e10cSrcweir //------------------------------------------------------------------------------
4246*cdf0e10cSrcweir Reference< XDispatchProviderInterceptor >  FormController::createInterceptor(const Reference< XDispatchProviderInterception > & _xInterception)
4247*cdf0e10cSrcweir {
4248*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
4249*cdf0e10cSrcweir #ifdef DBG_UTIL
4250*cdf0e10cSrcweir     // check if we already have a interceptor for the given object
4251*cdf0e10cSrcweir     for (   ConstInterceptorsIterator aIter = m_aControlDispatchInterceptors.begin();
4252*cdf0e10cSrcweir             aIter != m_aControlDispatchInterceptors.end();
4253*cdf0e10cSrcweir             ++aIter
4254*cdf0e10cSrcweir         )
4255*cdf0e10cSrcweir     {
4256*cdf0e10cSrcweir         if ((*aIter)->getIntercepted() == _xInterception)
4257*cdf0e10cSrcweir             DBG_ERROR("FormController::createInterceptor : we already do intercept this objects dispatches !");
4258*cdf0e10cSrcweir     }
4259*cdf0e10cSrcweir #endif
4260*cdf0e10cSrcweir 
4261*cdf0e10cSrcweir     DispatchInterceptionMultiplexer* pInterceptor = new DispatchInterceptionMultiplexer( _xInterception, this );
4262*cdf0e10cSrcweir     pInterceptor->acquire();
4263*cdf0e10cSrcweir     m_aControlDispatchInterceptors.insert( m_aControlDispatchInterceptors.end(), pInterceptor );
4264*cdf0e10cSrcweir 
4265*cdf0e10cSrcweir     return pInterceptor;
4266*cdf0e10cSrcweir }
4267*cdf0e10cSrcweir 
4268*cdf0e10cSrcweir //------------------------------------------------------------------------------
4269*cdf0e10cSrcweir bool FormController::ensureInteractionHandler()
4270*cdf0e10cSrcweir {
4271*cdf0e10cSrcweir     if ( m_xInteractionHandler.is() )
4272*cdf0e10cSrcweir         return true;
4273*cdf0e10cSrcweir     if ( m_bAttemptedHandlerCreation )
4274*cdf0e10cSrcweir         return false;
4275*cdf0e10cSrcweir     m_bAttemptedHandlerCreation = true;
4276*cdf0e10cSrcweir 
4277*cdf0e10cSrcweir     m_xInteractionHandler.set( m_aContext.createComponent( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), UNO_QUERY );
4278*cdf0e10cSrcweir     OSL_ENSURE( m_xInteractionHandler.is(), "FormController::ensureInteractionHandler: could not create an interaction handler!" );
4279*cdf0e10cSrcweir     return m_xInteractionHandler.is();
4280*cdf0e10cSrcweir }
4281*cdf0e10cSrcweir 
4282*cdf0e10cSrcweir //------------------------------------------------------------------------------
4283*cdf0e10cSrcweir void SAL_CALL FormController::handle( const Reference< XInteractionRequest >& _rRequest ) throw (RuntimeException)
4284*cdf0e10cSrcweir {
4285*cdf0e10cSrcweir     if ( !ensureInteractionHandler() )
4286*cdf0e10cSrcweir         return;
4287*cdf0e10cSrcweir     m_xInteractionHandler->handle( _rRequest );
4288*cdf0e10cSrcweir }
4289*cdf0e10cSrcweir 
4290*cdf0e10cSrcweir //------------------------------------------------------------------------------
4291*cdf0e10cSrcweir void FormController::deleteInterceptor(const Reference< XDispatchProviderInterception > & _xInterception)
4292*cdf0e10cSrcweir {
4293*cdf0e10cSrcweir     OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
4294*cdf0e10cSrcweir     // search the interceptor responsible for the given object
4295*cdf0e10cSrcweir     InterceptorsIterator aIter;
4296*cdf0e10cSrcweir     for (   aIter = m_aControlDispatchInterceptors.begin();
4297*cdf0e10cSrcweir             aIter != m_aControlDispatchInterceptors.end();
4298*cdf0e10cSrcweir             ++aIter
4299*cdf0e10cSrcweir         )
4300*cdf0e10cSrcweir     {
4301*cdf0e10cSrcweir         if ((*aIter)->getIntercepted() == _xInterception)
4302*cdf0e10cSrcweir             break;
4303*cdf0e10cSrcweir     }
4304*cdf0e10cSrcweir     if (aIter == m_aControlDispatchInterceptors.end())
4305*cdf0e10cSrcweir     {
4306*cdf0e10cSrcweir         return;
4307*cdf0e10cSrcweir     }
4308*cdf0e10cSrcweir 
4309*cdf0e10cSrcweir     // log off the interception from it's interception object
4310*cdf0e10cSrcweir     DispatchInterceptionMultiplexer* pInterceptorImpl = *aIter;
4311*cdf0e10cSrcweir     pInterceptorImpl->dispose();
4312*cdf0e10cSrcweir     pInterceptorImpl->release();
4313*cdf0e10cSrcweir 
4314*cdf0e10cSrcweir     // remove the interceptor from our array
4315*cdf0e10cSrcweir     m_aControlDispatchInterceptors.erase(aIter);
4316*cdf0e10cSrcweir }
4317*cdf0e10cSrcweir 
4318*cdf0e10cSrcweir //--------------------------------------------------------------------
4319*cdf0e10cSrcweir void FormController::implInvalidateCurrentControlDependentFeatures()
4320*cdf0e10cSrcweir {
4321*cdf0e10cSrcweir     Sequence< sal_Int16 > aCurrentControlDependentFeatures(4);
4322*cdf0e10cSrcweir 
4323*cdf0e10cSrcweir     aCurrentControlDependentFeatures[0] = FormFeature::SortAscending;
4324*cdf0e10cSrcweir     aCurrentControlDependentFeatures[1] = FormFeature::SortDescending;
4325*cdf0e10cSrcweir     aCurrentControlDependentFeatures[2] = FormFeature::AutoFilter;
4326*cdf0e10cSrcweir     aCurrentControlDependentFeatures[3] = FormFeature::RefreshCurrentControl;
4327*cdf0e10cSrcweir 
4328*cdf0e10cSrcweir     invalidateFeatures( aCurrentControlDependentFeatures );
4329*cdf0e10cSrcweir }
4330*cdf0e10cSrcweir 
4331*cdf0e10cSrcweir //--------------------------------------------------------------------
4332*cdf0e10cSrcweir void SAL_CALL FormController::columnChanged( const EventObject& /*_event*/ ) throw (RuntimeException)
4333*cdf0e10cSrcweir {
4334*cdf0e10cSrcweir     implInvalidateCurrentControlDependentFeatures();
4335*cdf0e10cSrcweir }
4336*cdf0e10cSrcweir 
4337*cdf0e10cSrcweir }   // namespace svxform
4338