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