1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "fmcontrolbordermanager.hxx"
31 #include "fmcontrollayout.hxx"
32 #include "formcontroller.hxx"
33 #include "formfeaturedispatcher.hxx"
34 #include "fmdocumentclassification.hxx"
35 #include "formcontrolling.hxx"
37 #include "svx/dialmgr.hxx"
38 #include "svx/fmresids.hrc"
39 #include "fmservs.hxx"
40 #include "svx/fmtools.hxx"
43 /** === begin UNO includes === **/
44 #include <com/sun/star/awt/FocusChangeReason.hpp>
45 #include <com/sun/star/awt/XCheckBox.hpp>
46 #include <com/sun/star/awt/XComboBox.hpp>
47 #include <com/sun/star/awt/XListBox.hpp>
48 #include <com/sun/star/awt/XVclWindowPeer.hpp>
49 #include <com/sun/star/beans/NamedValue.hpp>
50 #include <com/sun/star/beans/PropertyAttribute.hpp>
51 #include <com/sun/star/container/XIdentifierReplace.hpp>
52 #include <com/sun/star/form/TabulatorCycle.hpp>
53 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
54 #include <com/sun/star/form/XBoundComponent.hpp>
55 #include <com/sun/star/form/XBoundControl.hpp>
56 #include <com/sun/star/form/XGridControl.hpp>
57 #include <com/sun/star/form/XLoadable.hpp>
58 #include <com/sun/star/form/XReset.hpp>
59 #include <com/sun/star/frame/XController.hpp>
60 #include <com/sun/star/sdb/ParametersRequest.hpp>
61 #include <com/sun/star/sdb/RowChangeAction.hpp>
62 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
63 #include <com/sun/star/sdbc/ColumnValue.hpp>
64 #include <com/sun/star/sdbc/DataType.hpp>
65 #include <com/sun/star/util/XURLTransformer.hpp>
66 #include <com/sun/star/form/runtime/FormOperations.hpp>
67 #include <com/sun/star/form/runtime/FormFeature.hpp>
68 #include <com/sun/star/container/XContainer.hpp>
69 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
70 #include <com/sun/star/util/XNumberFormatter.hpp>
71 #include <com/sun/star/sdb/SQLContext.hpp>
72 #include <com/sun/star/sdb/XColumn.hpp>
73 /** === end UNO includes === **/
75 #include <comphelper/enumhelper.hxx>
76 #include <comphelper/extract.hxx>
77 #include <comphelper/interaction.hxx>
78 #include <comphelper/namedvaluecollection.hxx>
79 #include <comphelper/propagg.hxx>
80 #include <comphelper/property.hxx>
81 #include <comphelper/sequence.hxx>
82 #include <comphelper/uno3.hxx>
83 #include <comphelper/flagguard.hxx>
84 #include <cppuhelper/queryinterface.hxx>
85 #include <cppuhelper/typeprovider.hxx>
86 #include <toolkit/controls/unocontrol.hxx>
87 #include <toolkit/helper/vclunohelper.hxx>
88 #include <tools/debug.hxx>
89 #include <tools/diagnose_ex.h>
90 #include <tools/shl.hxx>
91 #include <vcl/msgbox.hxx>
92 #include <vcl/svapp.hxx>
93 #include <osl/mutex.hxx>
94 #include <rtl/logfile.hxx>
98 #include <o3tl/compat_functional.hxx>
100 using namespace ::com::sun::star
;
101 using namespace ::comphelper
;
102 using namespace ::connectivity
;
103 using namespace ::connectivity::simple
;
105 //------------------------------------------------------------------
106 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> SAL_CALL
107 FormController_NewInstance_Impl( const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> & _rxORB
)
109 return *( new ::svxform::FormController( _rxORB
) );
115 /** === begin UNO using === **/
116 using ::com::sun::star::sdb::XColumn
;
117 using ::com::sun::star::awt::XControl
;
118 using ::com::sun::star::awt::XTabController
;
119 using ::com::sun::star::awt::XToolkit
;
120 using ::com::sun::star::awt::XWindowPeer
;
121 using ::com::sun::star::form::XGrid
;
122 using ::com::sun::star::beans::XPropertySet
;
123 using ::com::sun::star::uno::UNO_SET_THROW
;
124 using ::com::sun::star::uno::UNO_QUERY_THROW
;
125 using ::com::sun::star::container::XIndexAccess
;
126 using ::com::sun::star::uno::Exception
;
127 using ::com::sun::star::uno::XInterface
;
128 using ::com::sun::star::uno::UNO_QUERY
;
129 using ::com::sun::star::uno::Sequence
;
130 using ::com::sun::star::uno::Reference
;
131 using ::com::sun::star::beans::XPropertySetInfo
;
132 using ::com::sun::star::beans::PropertyValue
;
133 using ::com::sun::star::uno::RuntimeException
;
134 using ::com::sun::star::lang::IndexOutOfBoundsException
;
135 using ::com::sun::star::sdb::XInteractionSupplyParameters
;
136 using ::com::sun::star::awt::XTextComponent
;
137 using ::com::sun::star::awt::XTextListener
;
138 using ::com::sun::star::uno::Any
;
139 using ::com::sun::star::frame::XDispatch
;
140 using ::com::sun::star::lang::XMultiServiceFactory
;
141 using ::com::sun::star::uno::XAggregation
;
142 using ::com::sun::star::uno::Type
;
143 using ::com::sun::star::lang::IllegalArgumentException
;
144 using ::com::sun::star::sdbc::XConnection
;
145 using ::com::sun::star::sdbc::XRowSet
;
146 using ::com::sun::star::sdbc::XDatabaseMetaData
;
147 using ::com::sun::star::util::XNumberFormatsSupplier
;
148 using ::com::sun::star::util::XNumberFormatter
;
149 using ::com::sun::star::sdbcx::XColumnsSupplier
;
150 using ::com::sun::star::container::XNameAccess
;
151 using ::com::sun::star::lang::EventObject
;
152 using ::com::sun::star::beans::Property
;
153 using ::com::sun::star::container::XEnumeration
;
154 using ::com::sun::star::form::XFormComponent
;
155 using ::com::sun::star::form::runtime::XFormOperations
;
156 using ::com::sun::star::form::runtime::FilterEvent
;
157 using ::com::sun::star::form::runtime::XFilterControllerListener
;
158 using ::com::sun::star::awt::XControlContainer
;
159 using ::com::sun::star::container::XIdentifierReplace
;
160 using ::com::sun::star::lang::WrappedTargetException
;
161 using ::com::sun::star::form::XFormControllerListener
;
162 using ::com::sun::star::awt::XWindow
;
163 using ::com::sun::star::sdbc::XResultSet
;
164 using ::com::sun::star::awt::XControlModel
;
165 using ::com::sun::star::awt::XTabControllerModel
;
166 using ::com::sun::star::beans::PropertyChangeEvent
;
167 using ::com::sun::star::form::validation::XValidatableFormComponent
;
168 using ::com::sun::star::form::XLoadable
;
169 using ::com::sun::star::script::XEventAttacherManager
;
170 using ::com::sun::star::form::XBoundControl
;
171 using ::com::sun::star::beans::XPropertyChangeListener
;
172 using ::com::sun::star::awt::TextEvent
;
173 using ::com::sun::star::form::XBoundComponent
;
174 using ::com::sun::star::awt::XCheckBox
;
175 using ::com::sun::star::awt::XComboBox
;
176 using ::com::sun::star::awt::XListBox
;
177 using ::com::sun::star::awt::ItemEvent
;
178 using ::com::sun::star::util::XModifyListener
;
179 using ::com::sun::star::form::XReset
;
180 using ::com::sun::star::frame::XDispatchProviderInterception
;
181 using ::com::sun::star::form::XGridControl
;
182 using ::com::sun::star::awt::XVclWindowPeer
;
183 using ::com::sun::star::form::validation::XValidator
;
184 using ::com::sun::star::awt::FocusEvent
;
185 using ::com::sun::star::sdb::SQLContext
;
186 using ::com::sun::star::container::XChild
;
187 using ::com::sun::star::form::TabulatorCycle_RECORDS
;
188 using ::com::sun::star::container::ContainerEvent
;
189 using ::com::sun::star::lang::DisposedException
;
190 using ::com::sun::star::lang::Locale
;
191 using ::com::sun::star::beans::NamedValue
;
192 using ::com::sun::star::lang::NoSupportException
;
193 using ::com::sun::star::sdb::RowChangeEvent
;
194 using ::com::sun::star::frame::XStatusListener
;
195 using ::com::sun::star::frame::XDispatchProviderInterceptor
;
196 using ::com::sun::star::sdb::SQLErrorEvent
;
197 using ::com::sun::star::form::DatabaseParameterEvent
;
198 using ::com::sun::star::sdb::ParametersRequest
;
199 using ::com::sun::star::task::XInteractionRequest
;
200 using ::com::sun::star::util::URL
;
201 using ::com::sun::star::frame::FeatureStateEvent
;
202 using ::com::sun::star::form::runtime::XFormControllerContext
;
203 using ::com::sun::star::task::XInteractionHandler
;
204 using ::com::sun::star::form::runtime::FormOperations
;
205 using ::com::sun::star::container::XContainer
;
206 using ::com::sun::star::sdbc::SQLWarning
;
207 /** === end UNO using === **/
208 namespace ColumnValue
= ::com::sun::star::sdbc::ColumnValue
;
209 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
210 namespace FocusChangeReason
= ::com::sun::star::awt::FocusChangeReason
;
211 namespace RowChangeAction
= ::com::sun::star::sdb::RowChangeAction
;
212 namespace FormFeature
= ::com::sun::star::form::runtime::FormFeature
;
213 namespace DataType
= ::com::sun::star::sdbc::DataType
;
215 //==============================================================================
217 //==============================================================================
220 // information about the column itself
221 Reference
< XColumn
> xColumn
;
223 sal_Bool bAutoIncrement
;
225 ::rtl::OUString sName
;
227 // information about the control(s) bound to this column
229 /// the first control which is bound to the given column, and which requires input
230 Reference
< XControl
> xFirstControlWithInputRequired
;
231 /** the first grid control which contains a column which is bound to the given database column, and requires
234 Reference
< XGrid
> xFirstGridWithInputRequiredColumn
;
235 /** if xFirstControlWithInputRequired is a grid control, then nRequiredGridColumn specifies the position
236 of the grid column which is actually bound
238 sal_Int32 nRequiredGridColumn
;
242 ,nNullable( ColumnValue::NULLABLE_UNKNOWN
)
243 ,bAutoIncrement( sal_False
)
244 ,bReadOnly( sal_False
)
246 ,xFirstControlWithInputRequired()
247 ,xFirstGridWithInputRequiredColumn()
248 ,nRequiredGridColumn( -1 )
253 //==============================================================================
255 //==============================================================================
256 class ColumnInfoCache
259 ColumnInfoCache( const Reference
< XColumnsSupplier
>& _rxColSupplier
);
261 size_t getColumnCount() const { return m_aColumns
.size(); }
262 const ColumnInfo
& getColumnInfo( size_t _pos
);
264 bool controlsInitialized() const { return m_bControlsInitialized
; }
265 void initializeControls( const Sequence
< Reference
< XControl
> >& _rControls
);
266 void deinitializeControls();
269 typedef ::std::vector
< ColumnInfo
> ColumnInfos
;
270 ColumnInfos m_aColumns
;
271 bool m_bControlsInitialized
;
274 //------------------------------------------------------------------------------
275 ColumnInfoCache::ColumnInfoCache( const Reference
< XColumnsSupplier
>& _rxColSupplier
)
277 ,m_bControlsInitialized( false )
283 Reference
< XColumnsSupplier
> xSupplyCols( _rxColSupplier
, UNO_SET_THROW
);
284 Reference
< XIndexAccess
> xColumns( xSupplyCols
->getColumns(), UNO_QUERY_THROW
);
285 sal_Int32 nColumnCount
= xColumns
->getCount();
286 m_aColumns
.reserve( nColumnCount
);
288 Reference
< XPropertySet
> xColumnProps
;
289 for ( sal_Int32 i
= 0; i
< nColumnCount
; ++i
)
292 aColInfo
.xColumn
.set( xColumns
->getByIndex(i
), UNO_QUERY_THROW
);
294 xColumnProps
.set( aColInfo
.xColumn
, UNO_QUERY_THROW
);
295 OSL_VERIFY( xColumnProps
->getPropertyValue( FM_PROP_ISNULLABLE
) >>= aColInfo
.nNullable
);
296 OSL_VERIFY( xColumnProps
->getPropertyValue( FM_PROP_AUTOINCREMENT
) >>= aColInfo
.bAutoIncrement
);
297 OSL_VERIFY( xColumnProps
->getPropertyValue( FM_PROP_NAME
) >>= aColInfo
.sName
);
298 OSL_VERIFY( xColumnProps
->getPropertyValue( FM_PROP_ISREADONLY
) >>= aColInfo
.bReadOnly
);
300 m_aColumns
.push_back( aColInfo
);
303 catch( const Exception
& )
305 DBG_UNHANDLED_EXCEPTION();
309 //------------------------------------------------------------------------------
312 bool lcl_isBoundTo( const Reference
< XPropertySet
>& _rxControlModel
, const Reference
< XInterface
>& _rxNormDBField
)
314 Reference
< XInterface
> xNormBoundField( _rxControlModel
->getPropertyValue( FM_PROP_BOUNDFIELD
), UNO_QUERY
);
315 return ( xNormBoundField
.get() == _rxNormDBField
.get() );
318 bool lcl_isInputRequired( const Reference
< XPropertySet
>& _rxControlModel
)
320 sal_Bool bInputRequired
= sal_True
;
321 OSL_VERIFY( _rxControlModel
->getPropertyValue( FM_PROP_INPUT_REQUIRED
) >>= bInputRequired
);
322 return ( bInputRequired
!= sal_False
);
325 void lcl_resetColumnControlInfo( ColumnInfo
& _rColInfo
)
327 _rColInfo
.xFirstControlWithInputRequired
.clear();
328 _rColInfo
.xFirstGridWithInputRequiredColumn
.clear();
329 _rColInfo
.nRequiredGridColumn
= -1;
333 //------------------------------------------------------------------------------
334 void ColumnInfoCache::deinitializeControls()
336 for ( ColumnInfos::iterator col
= m_aColumns
.begin();
337 col
!= m_aColumns
.end();
341 lcl_resetColumnControlInfo( *col
);
345 //------------------------------------------------------------------------------
346 void ColumnInfoCache::initializeControls( const Sequence
< Reference
< XControl
> >& _rControls
)
350 // for every of our known columns, find the controls which are bound to this column
351 for ( ColumnInfos::iterator col
= m_aColumns
.begin();
352 col
!= m_aColumns
.end();
356 OSL_ENSURE( !col
->xFirstControlWithInputRequired
.is() && !col
->xFirstGridWithInputRequiredColumn
.is()
357 && ( col
->nRequiredGridColumn
== -1 ), "ColumnInfoCache::initializeControls: called me twice?" );
359 lcl_resetColumnControlInfo( *col
);
361 Reference
< XInterface
> xNormColumn( col
->xColumn
, UNO_QUERY_THROW
);
363 const Reference
< XControl
>* pControl( _rControls
.getConstArray() );
364 const Reference
< XControl
>* pControlEnd( pControl
+ _rControls
.getLength() );
365 for ( ; pControl
!= pControlEnd
; ++pControl
)
367 if ( !pControl
->is() )
370 Reference
< XPropertySet
> xModel( (*pControl
)->getModel(), UNO_QUERY_THROW
);
371 Reference
< XPropertySetInfo
> xModelPSI( xModel
->getPropertySetInfo(), UNO_SET_THROW
);
373 // special handling for grid controls
374 Reference
< XGrid
> xGrid( *pControl
, UNO_QUERY
);
377 Reference
< XIndexAccess
> xGridColAccess( xModel
, UNO_QUERY_THROW
);
378 sal_Int32 gridColCount
= xGridColAccess
->getCount();
379 sal_Int32 gridCol
= 0;
380 for ( gridCol
= 0; gridCol
< gridColCount
; ++gridCol
)
382 Reference
< XPropertySet
> xGridColumnModel( xGridColAccess
->getByIndex( gridCol
), UNO_QUERY_THROW
);
384 if ( !lcl_isBoundTo( xGridColumnModel
, xNormColumn
)
385 || !lcl_isInputRequired( xGridColumnModel
)
387 continue; // with next grid column
392 if ( gridCol
< gridColCount
)
394 // found a grid column which is bound to the given
395 col
->xFirstGridWithInputRequiredColumn
= xGrid
;
396 col
->nRequiredGridColumn
= gridCol
;
400 continue; // with next control
403 if ( !xModelPSI
->hasPropertyByName( FM_PROP_BOUNDFIELD
)
404 || !lcl_isBoundTo( xModel
, xNormColumn
)
405 || !lcl_isInputRequired( xModel
)
407 continue; // with next control
412 if ( pControl
== pControlEnd
)
413 // did not find a control which is bound to this particular column, and for which the input is required
414 continue; // with next DB column
416 col
->xFirstControlWithInputRequired
= *pControl
;
419 catch( const Exception
& )
421 DBG_UNHANDLED_EXCEPTION();
424 m_bControlsInitialized
= true;
427 //------------------------------------------------------------------------------
428 const ColumnInfo
& ColumnInfoCache::getColumnInfo( size_t _pos
)
430 if ( _pos
>= m_aColumns
.size() )
431 throw IndexOutOfBoundsException();
433 return m_aColumns
[ _pos
];
436 //==================================================================
437 // OParameterContinuation
438 //==================================================================
439 class OParameterContinuation
: public OInteraction
< XInteractionSupplyParameters
>
441 Sequence
< PropertyValue
> m_aValues
;
444 OParameterContinuation() { }
446 Sequence
< PropertyValue
> getValues() const { return m_aValues
; }
448 // XInteractionSupplyParameters
449 virtual void SAL_CALL
setParameters( const Sequence
< PropertyValue
>& _rValues
) throw(RuntimeException
);
452 //------------------------------------------------------------------
453 void SAL_CALL
OParameterContinuation::setParameters( const Sequence
< PropertyValue
>& _rValues
) throw(RuntimeException
)
455 m_aValues
= _rValues
;
458 //==================================================================
460 //==================================================================
463 rtl::OUString aFieldName
;
464 Reference
< XPropertySet
> xField
;
465 Reference
< XTextComponent
> xText
;
467 FmFieldInfo(const Reference
< XPropertySet
>& _xField
, const Reference
< XTextComponent
>& _xText
)
470 {xField
->getPropertyValue(FM_PROP_NAME
) >>= aFieldName
;}
473 //==================================================================
475 //==================================================================
476 class FmXAutoControl
: public UnoControl
479 friend Reference
< XInterface
> SAL_CALL
FmXAutoControl_NewInstance_Impl();
482 FmXAutoControl( const ::comphelper::ComponentContext
& i_context
)
483 :UnoControl( i_context
.getLegacyServiceFactory() )
487 virtual ::rtl::OUString
GetComponentServiceName() {return ::rtl::OUString("Edit");}
488 virtual void SAL_CALL
createPeer( const Reference
< XToolkit
> & rxToolkit
, const Reference
< XWindowPeer
> & rParentPeer
) throw( RuntimeException
);
491 virtual void ImplSetPeerProperty( const ::rtl::OUString
& rPropName
, const Any
& rVal
);
494 //------------------------------------------------------------------------------
495 void FmXAutoControl::createPeer( const Reference
< XToolkit
> & rxToolkit
, const Reference
< XWindowPeer
> & rParentPeer
) throw( RuntimeException
)
497 UnoControl::createPeer( rxToolkit
, rParentPeer
);
499 Reference
< XTextComponent
> xText(getPeer() , UNO_QUERY
);
502 xText
->setText(::rtl::OUString(String(SVX_RES(RID_STR_AUTOFIELD
))));
503 xText
->setEditable(sal_False
);
507 //------------------------------------------------------------------------------
508 void FmXAutoControl::ImplSetPeerProperty( const ::rtl::OUString
& rPropName
, const Any
& rVal
)
510 // these properties are ignored
511 if (rPropName
== FM_PROP_TEXT
)
514 UnoControl::ImplSetPeerProperty( rPropName
, rVal
);
517 //------------------------------------------------------------------------------
518 IMPL_LINK( FormController
, OnActivateTabOrder
, void*, /*EMPTYTAG*/ )
524 //------------------------------------------------------------------------------
525 struct UpdateAllListeners
: public ::std::unary_function
< Reference
< XDispatch
>, bool >
527 bool operator()( const Reference
< XDispatch
>& _rxDispatcher
) const
529 static_cast< ::svx::OSingleFeatureDispatcher
* >( _rxDispatcher
.get() )->updateAllListeners();
530 // the return is a dummy only so we can use this struct in a o3tl::compose1 call
534 //..............................................................................
535 IMPL_LINK( FormController
, OnInvalidateFeatures
, void*, /*_pNotInterestedInThisParam*/ )
537 ::osl::MutexGuard
aGuard( m_aMutex
);
538 for ( ::std::set
< sal_Int16
>::const_iterator aLoop
= m_aInvalidFeatures
.begin();
539 aLoop
!= m_aInvalidFeatures
.end();
543 DispatcherContainer::const_iterator aDispatcherPos
= m_aFeatureDispatchers
.find( *aLoop
);
544 if ( aDispatcherPos
!= m_aFeatureDispatchers
.end() )
546 // TODO: for the real and actual listener notifications, we should release
548 UpdateAllListeners( )( aDispatcherPos
->second
);
554 /*************************************************************************/
556 DBG_NAME( FormController
)
557 //------------------------------------------------------------------
558 FormController::FormController(const Reference
< XMultiServiceFactory
> & _rxORB
)
559 :FormController_BASE( m_aMutex
)
560 ,OPropertySetHelper( FormController_BASE::rBHelper
)
561 ,OSQLParserClient( _rxORB
)
562 ,m_aContext( _rxORB
)
563 ,m_aActivateListeners(m_aMutex
)
564 ,m_aModifyListeners(m_aMutex
)
565 ,m_aErrorListeners(m_aMutex
)
566 ,m_aDeleteListeners(m_aMutex
)
567 ,m_aRowSetApproveListeners(m_aMutex
)
568 ,m_aParameterListeners(m_aMutex
)
569 ,m_aFilterListeners(m_aMutex
)
570 ,m_pControlBorderManager( new ::svxform::ControlBorderManager
)
572 ,m_aMode( ::rtl::OUString( "DataMode" ) )
573 ,m_aLoadEvent( LINK( this, FormController
, OnLoad
) )
574 ,m_aToggleEvent( LINK( this, FormController
, OnToggleAutoFields
) )
575 ,m_aActivationEvent( LINK( this, FormController
, OnActivated
) )
576 ,m_aDeactivationEvent( LINK( this, FormController
, OnDeactivated
) )
577 ,m_nCurrentFilterPosition(-1)
578 ,m_bCurrentRecordModified(sal_False
)
579 ,m_bCurrentRecordNew(sal_False
)
580 ,m_bLocked(sal_False
)
581 ,m_bDBConnection(sal_False
)
583 ,m_bCanInsert(sal_False
)
584 ,m_bCanUpdate(sal_False
)
585 ,m_bCommitLock(sal_False
)
586 ,m_bModified(sal_False
)
587 ,m_bControlsSorted(sal_False
)
588 ,m_bFiltering(sal_False
)
589 ,m_bAttachEvents(sal_True
)
590 ,m_bDetachEvents(sal_True
)
591 ,m_bAttemptedHandlerCreation( false )
592 ,m_bSuspendFilterTextListening( false )
594 DBG_CTOR( FormController
, NULL
);
596 ::comphelper::increment(m_refCount
);
599 m_xAggregate
= Reference
< XAggregation
>(
600 m_aContext
.createComponent( "com.sun.star.awt.TabController" ),
603 DBG_ASSERT( m_xAggregate
.is(), "FormController::FormController : could not create my aggregate !" );
604 m_xTabController
= Reference
< XTabController
>( m_xAggregate
, UNO_QUERY
);
607 if ( m_xAggregate
.is() )
608 m_xAggregate
->setDelegator( *this );
610 ::comphelper::decrement(m_refCount
);
612 m_aTabActivationTimer
.SetTimeout( 500 );
613 m_aTabActivationTimer
.SetTimeoutHdl( LINK( this, FormController
, OnActivateTabOrder
) );
615 m_aFeatureInvalidationTimer
.SetTimeout( 200 );
616 m_aFeatureInvalidationTimer
.SetTimeoutHdl( LINK( this, FormController
, OnInvalidateFeatures
) );
619 //------------------------------------------------------------------
620 FormController::~FormController()
623 ::osl::MutexGuard
aGuard( m_aMutex
);
625 m_aLoadEvent
.CancelPendingCall();
626 m_aToggleEvent
.CancelPendingCall();
627 m_aActivationEvent
.CancelPendingCall();
628 m_aDeactivationEvent
.CancelPendingCall();
630 if ( m_aTabActivationTimer
.IsActive() )
631 m_aTabActivationTimer
.Stop();
634 if ( m_aFeatureInvalidationTimer
.IsActive() )
635 m_aFeatureInvalidationTimer
.Stop();
637 disposeAllFeaturesAndDispatchers();
639 if ( m_xFormOperations
.is() )
640 m_xFormOperations
->dispose();
641 m_xFormOperations
.clear();
643 // Freigeben der Aggregation
644 if ( m_xAggregate
.is() )
646 m_xAggregate
->setDelegator( NULL
);
647 m_xAggregate
.clear();
650 DELETEZ( m_pControlBorderManager
);
652 DBG_DTOR( FormController
, NULL
);
655 // -----------------------------------------------------------------------------
656 void SAL_CALL
FormController::acquire() throw ()
658 FormController_BASE::acquire();
661 // -----------------------------------------------------------------------------
662 void SAL_CALL
FormController::release() throw ()
664 FormController_BASE::release();
667 //------------------------------------------------------------------
668 Any SAL_CALL
FormController::queryInterface( const Type
& _rType
) throw(RuntimeException
)
670 Any aRet
= FormController_BASE::queryInterface( _rType
);
671 if ( !aRet
.hasValue() )
672 aRet
= OPropertySetHelper::queryInterface( _rType
);
673 if ( !aRet
.hasValue() )
674 aRet
= m_xAggregate
->queryAggregation( _rType
);
678 //------------------------------------------------------------------------------
679 Sequence
< sal_Int8
> SAL_CALL
FormController::getImplementationId() throw( RuntimeException
)
681 static ::cppu::OImplementationId
* pId
= NULL
;
684 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
687 static ::cppu::OImplementationId aId
;
691 return pId
->getImplementationId();
694 //------------------------------------------------------------------------------
695 Sequence
< Type
> SAL_CALL
FormController::getTypes( ) throw(RuntimeException
)
697 return comphelper::concatSequences(
698 FormController_BASE::getTypes(),
699 ::cppu::OPropertySetHelper::getTypes()
704 //------------------------------------------------------------------------------
705 sal_Bool SAL_CALL
FormController::supportsService(const ::rtl::OUString
& ServiceName
) throw( RuntimeException
)
707 Sequence
< ::rtl::OUString
> aSNL(getSupportedServiceNames());
708 const ::rtl::OUString
* pArray
= aSNL
.getConstArray();
709 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
710 if( pArray
[i
] == ServiceName
)
715 //------------------------------------------------------------------------------
716 ::rtl::OUString SAL_CALL
FormController::getImplementationName() throw( RuntimeException
)
718 return ::rtl::OUString("org.openoffice.comp.svx.FormController");
721 //------------------------------------------------------------------------------
722 Sequence
< ::rtl::OUString
> SAL_CALL
FormController::getSupportedServiceNames(void) throw( RuntimeException
)
724 // service names which are supported only, but cannot be used to created an
725 // instance at a service factory
726 Sequence
< ::rtl::OUString
> aNonCreatableServiceNames( 1 );
727 aNonCreatableServiceNames
[ 0 ] = ::rtl::OUString( "com.sun.star.form.FormControllerDispatcher" );
729 // services which can be used to created an instance at a service factory
730 Sequence
< ::rtl::OUString
> aCreatableServiceNames( getSupportedServiceNames_Static() );
731 return ::comphelper::concatSequences( aCreatableServiceNames
, aNonCreatableServiceNames
);
734 //------------------------------------------------------------------------------
735 sal_Bool SAL_CALL
FormController::approveReset(const EventObject
& /*rEvent*/) throw( RuntimeException
)
740 //------------------------------------------------------------------------------
741 void SAL_CALL
FormController::resetted(const EventObject
& rEvent
) throw( RuntimeException
)
743 ::osl::MutexGuard
aGuard(m_aMutex
);
744 if (getCurrentControl().is() && (getCurrentControl()->getModel() == rEvent
.Source
))
745 m_bModified
= sal_False
;
748 //------------------------------------------------------------------------------
749 Sequence
< ::rtl::OUString
> FormController::getSupportedServiceNames_Static(void)
751 static Sequence
< ::rtl::OUString
> aServices
;
752 if (!aServices
.getLength())
754 aServices
.realloc(2);
755 aServices
.getArray()[0] = FM_FORM_CONTROLLER
;
756 aServices
.getArray()[1] = ::rtl::OUString("com.sun.star.awt.control.TabController");
761 // -----------------------------------------------------------------------------
764 struct ResetComponentText
: public ::std::unary_function
< Reference
< XTextComponent
>, void >
766 void operator()( const Reference
< XTextComponent
>& _rxText
)
768 _rxText
->setText( ::rtl::OUString() );
772 struct RemoveComponentTextListener
: public ::std::unary_function
< Reference
< XTextComponent
>, void >
774 RemoveComponentTextListener( const Reference
< XTextListener
>& _rxListener
)
775 :m_xListener( _rxListener
)
779 void operator()( const Reference
< XTextComponent
>& _rxText
)
781 _rxText
->removeTextListener( m_xListener
);
785 Reference
< XTextListener
> m_xListener
;
789 // -----------------------------------------------------------------------------
790 void FormController::impl_setTextOnAllFilter_throw()
792 m_bSuspendFilterTextListening
= true;
793 ::comphelper::FlagGuard
aResetFlag( m_bSuspendFilterTextListening
);
795 // reset the text for all controls
796 ::std::for_each( m_aFilterComponents
.begin(), m_aFilterComponents
.end(), ResetComponentText() );
798 if ( m_aFilterRows
.empty() )
799 // nothing to do anymore
802 if ( m_nCurrentFilterPosition
< 0 )
805 // set the text for all filters
806 OSL_ENSURE( m_aFilterRows
.size() > (size_t)m_nCurrentFilterPosition
,
807 "FormController::impl_setTextOnAllFilter_throw: m_nCurrentFilterPosition too big" );
809 if ( (size_t)m_nCurrentFilterPosition
< m_aFilterRows
.size() )
811 FmFilterRow
& rRow
= m_aFilterRows
[ m_nCurrentFilterPosition
];
812 for ( FmFilterRow::const_iterator iter2
= rRow
.begin();
817 iter2
->first
->setText( iter2
->second
);
821 // OPropertySetHelper
822 //------------------------------------------------------------------------------
823 sal_Bool
FormController::convertFastPropertyValue( Any
& /*rConvertedValue*/, Any
& /*rOldValue*/,
824 sal_Int32
/*nHandle*/, const Any
& /*rValue*/ )
825 throw( IllegalArgumentException
)
830 //------------------------------------------------------------------------------
831 void FormController::setFastPropertyValue_NoBroadcast( sal_Int32
/*nHandle*/, const Any
& /*rValue*/ )
836 //------------------------------------------------------------------------------
837 void FormController::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
843 ::rtl::OUStringBuffer aFilter
;
844 OStaticDataAccessTools aStaticTools
;
845 Reference
<XConnection
> xConnection(aStaticTools
.getRowSetConnection(Reference
< XRowSet
>(m_xModelAsIndex
, UNO_QUERY
)));
846 if (xConnection
.is())
848 Reference
< XDatabaseMetaData
> xMetaData(xConnection
->getMetaData());
849 Reference
< XNumberFormatsSupplier
> xFormatSupplier( aStaticTools
.getNumberFormats( xConnection
, sal_True
) );
850 Reference
< XNumberFormatter
> xFormatter( m_aContext
.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW
);
851 xFormatter
->attachNumberFormatsSupplier(xFormatSupplier
);
853 Reference
< XColumnsSupplier
> xSupplyCols(m_xModelAsIndex
, UNO_QUERY
);
854 Reference
< XNameAccess
> xFields(xSupplyCols
->getColumns(), UNO_QUERY
);
856 ::rtl::OUString
aQuote( xMetaData
->getIdentifierQuoteString() );
858 // now add the filter rows
861 for ( FmFilterRows::const_iterator row
= m_aFilterRows
.begin(); row
!= m_aFilterRows
.end(); ++row
)
863 const FmFilterRow
& rRow
= *row
;
868 ::rtl::OUStringBuffer aRowFilter
;
869 for ( FmFilterRow::const_iterator condition
= rRow
.begin(); condition
!= rRow
.end(); ++condition
)
871 // get the field of the controls map
872 Reference
< XControl
> xControl( condition
->first
, UNO_QUERY_THROW
);
873 Reference
< XPropertySet
> xModelProps( xControl
->getModel(), UNO_QUERY_THROW
);
874 Reference
< XPropertySet
> xField( xModelProps
->getPropertyValue( FM_PROP_BOUNDFIELD
), UNO_QUERY_THROW
);
876 ::rtl::OUString
sFilterValue( condition
->second
);
878 ::rtl::OUString sErrorMsg
, sCriteria
;
879 const ::rtl::Reference
< ISQLParseNode
> xParseNode
=
880 predicateTree( sErrorMsg
, sFilterValue
, xFormatter
, xField
);
881 OSL_ENSURE( xParseNode
.is(), "FormController::getFastPropertyValue: could not parse the field value predicate!" );
882 if ( xParseNode
.is() )
884 // don't use a parse context here, we need it unlocalized
885 xParseNode
->parseNodeToStr( sCriteria
, xConnection
, NULL
);
886 if ( condition
!= rRow
.begin() )
887 aRowFilter
.appendAscii( " AND " );
888 aRowFilter
.append( sCriteria
);
891 if ( aRowFilter
.getLength() > 0 )
893 if ( aFilter
.getLength() )
894 aFilter
.appendAscii( " OR " );
896 aFilter
.appendAscii( "( " );
897 aFilter
.append( aRowFilter
.makeStringAndClear() );
898 aFilter
.appendAscii( " )" );
902 catch( const Exception
& )
904 DBG_UNHANDLED_EXCEPTION();
905 aFilter
.setLength(0);
908 rValue
<<= aFilter
.makeStringAndClear();
912 case FM_ATTR_FORM_OPERATIONS
:
913 rValue
<<= m_xFormOperations
;
918 //------------------------------------------------------------------------------
919 Reference
< XPropertySetInfo
> FormController::getPropertySetInfo() throw( RuntimeException
)
921 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
925 //------------------------------------------------------------------------------
926 #define DECL_PROP_CORE(varname, type) \
927 pDesc[nPos++] = Property(FM_PROP_##varname, FM_ATTR_##varname, ::getCppuType((const type*)0),
930 #define DECL_PROP1(varname, type, attrib1) \
931 DECL_PROP_CORE(varname, type) PropertyAttribute::attrib1)
933 //------------------------------------------------------------------------------
934 void FormController::fillProperties(
935 Sequence
< Property
>& /* [out] */ _rProps
,
936 Sequence
< Property
>& /* [out] */ /*_rAggregateProps*/
941 Property
* pDesc
= _rProps
.getArray();
942 DECL_PROP1(FILTER
, rtl::OUString
, READONLY
);
943 DECL_PROP1(FORM_OPERATIONS
, Reference
< XFormOperations
>, READONLY
);
946 //------------------------------------------------------------------------------
947 ::cppu::IPropertyArrayHelper
& FormController::getInfoHelper()
949 return *getArrayHelper();
953 //------------------------------------------------------------------------------
954 void SAL_CALL
FormController::addFilterControllerListener( const Reference
< XFilterControllerListener
>& _Listener
) throw( RuntimeException
)
956 m_aFilterListeners
.addInterface( _Listener
);
959 //------------------------------------------------------------------------------
960 void SAL_CALL
FormController::removeFilterControllerListener( const Reference
< XFilterControllerListener
>& _Listener
) throw( RuntimeException
)
962 m_aFilterListeners
.removeInterface( _Listener
);
965 //------------------------------------------------------------------------------
966 ::sal_Int32 SAL_CALL
FormController::getFilterComponents() throw( ::com::sun::star::uno::RuntimeException
)
968 ::osl::MutexGuard
aGuard( m_aMutex
);
969 impl_checkDisposed_throw();
971 return m_aFilterComponents
.size();
974 //------------------------------------------------------------------------------
975 ::sal_Int32 SAL_CALL
FormController::getDisjunctiveTerms() throw( ::com::sun::star::uno::RuntimeException
)
977 ::osl::MutexGuard
aGuard( m_aMutex
);
978 impl_checkDisposed_throw();
980 return m_aFilterRows
.size();
983 //------------------------------------------------------------------------------
984 void SAL_CALL
FormController::setPredicateExpression( ::sal_Int32 _Component
, ::sal_Int32 _Term
, const ::rtl::OUString
& _PredicateExpression
) throw( RuntimeException
, IndexOutOfBoundsException
)
986 ::osl::MutexGuard
aGuard( m_aMutex
);
987 impl_checkDisposed_throw();
989 if ( ( _Component
< 0 ) || ( _Component
>= getFilterComponents() ) || ( _Term
< 0 ) || ( _Term
>= getDisjunctiveTerms() ) )
990 throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
992 Reference
< XTextComponent
> xText( m_aFilterComponents
[ _Component
] );
993 xText
->setText( _PredicateExpression
);
995 FmFilterRow
& rFilterRow
= m_aFilterRows
[ _Term
];
996 if ( !_PredicateExpression
.isEmpty() )
997 rFilterRow
[ xText
] = _PredicateExpression
;
999 rFilterRow
.erase( xText
);
1002 //------------------------------------------------------------------------------
1003 Reference
< XControl
> FormController::getFilterComponent( ::sal_Int32 _Component
) throw( RuntimeException
, IndexOutOfBoundsException
)
1005 ::osl::MutexGuard
aGuard( m_aMutex
);
1006 impl_checkDisposed_throw();
1008 if ( ( _Component
< 0 ) || ( _Component
>= getFilterComponents() ) )
1009 throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
1011 return Reference
< XControl
>( m_aFilterComponents
[ _Component
], UNO_QUERY
);
1014 //------------------------------------------------------------------------------
1015 Sequence
< Sequence
< ::rtl::OUString
> > FormController::getPredicateExpressions() throw( RuntimeException
)
1017 ::osl::MutexGuard
aGuard( m_aMutex
);
1018 impl_checkDisposed_throw();
1020 Sequence
< Sequence
< ::rtl::OUString
> > aExpressions( m_aFilterRows
.size() );
1021 sal_Int32 termIndex
= 0;
1022 for ( FmFilterRows::const_iterator row
= m_aFilterRows
.begin();
1023 row
!= m_aFilterRows
.end();
1027 const FmFilterRow
& rRow( *row
);
1029 Sequence
< ::rtl::OUString
> aConjunction( m_aFilterComponents
.size() );
1030 sal_Int32 componentIndex
= 0;
1031 for ( FilterComponents::const_iterator comp
= m_aFilterComponents
.begin();
1032 comp
!= m_aFilterComponents
.end();
1033 ++comp
, ++componentIndex
1036 FmFilterRow::const_iterator predicate
= rRow
.find( *comp
);
1037 if ( predicate
!= rRow
.end() )
1038 aConjunction
[ componentIndex
] = predicate
->second
;
1041 aExpressions
[ termIndex
] = aConjunction
;
1044 return aExpressions
;
1047 //------------------------------------------------------------------------------
1048 void SAL_CALL
FormController::removeDisjunctiveTerm( ::sal_Int32 _Term
) throw (IndexOutOfBoundsException
, RuntimeException
)
1051 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1052 impl_checkDisposed_throw();
1054 if ( ( _Term
< 0 ) || ( _Term
>= getDisjunctiveTerms() ) )
1055 throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
1057 // if the to-be-deleted row is our current row, we need to shift
1058 if ( _Term
== m_nCurrentFilterPosition
)
1060 if ( m_nCurrentFilterPosition
< sal_Int32( m_aFilterRows
.size() - 1 ) )
1061 ++m_nCurrentFilterPosition
;
1063 --m_nCurrentFilterPosition
;
1066 FmFilterRows::iterator pos
= m_aFilterRows
.begin() + _Term
;
1067 m_aFilterRows
.erase( pos
);
1069 // adjust m_nCurrentFilterPosition if the removed row preceeded it
1070 if ( _Term
< m_nCurrentFilterPosition
)
1071 --m_nCurrentFilterPosition
;
1073 OSL_POSTCOND( ( m_nCurrentFilterPosition
< 0 ) == ( m_aFilterRows
.empty() ),
1074 "FormController::removeDisjunctiveTerm: inconsistency!" );
1076 // update the texts in the filter controls
1077 impl_setTextOnAllFilter_throw();
1080 aEvent
.Source
= *this;
1081 aEvent
.DisjunctiveTerm
= _Term
;
1085 m_aFilterListeners
.notifyEach( &XFilterControllerListener::disjunctiveTermRemoved
, aEvent
);
1088 //------------------------------------------------------------------------------
1089 void SAL_CALL
FormController::appendEmptyDisjunctiveTerm() throw (RuntimeException
)
1092 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1093 impl_checkDisposed_throw();
1095 impl_appendEmptyFilterRow( aGuard
);
1099 //------------------------------------------------------------------------------
1100 ::sal_Int32 SAL_CALL
FormController::getActiveTerm() throw (RuntimeException
)
1102 ::osl::MutexGuard
aGuard( m_aMutex
);
1103 impl_checkDisposed_throw();
1105 return m_nCurrentFilterPosition
;
1108 //------------------------------------------------------------------------------
1109 void SAL_CALL
FormController::setActiveTerm( ::sal_Int32 _ActiveTerm
) throw (IndexOutOfBoundsException
, RuntimeException
)
1111 ::osl::MutexGuard
aGuard( m_aMutex
);
1112 impl_checkDisposed_throw();
1114 if ( ( _ActiveTerm
< 0 ) || ( _ActiveTerm
>= getDisjunctiveTerms() ) )
1115 throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
1117 if ( _ActiveTerm
== getActiveTerm() )
1120 m_nCurrentFilterPosition
= _ActiveTerm
;
1121 impl_setTextOnAllFilter_throw();
1125 //------------------------------------------------------------------------------
1126 sal_Bool SAL_CALL
FormController::hasElements(void) throw( RuntimeException
)
1128 ::osl::MutexGuard
aGuard( m_aMutex
);
1129 return !m_aChildren
.empty();
1132 //------------------------------------------------------------------------------
1133 Type SAL_CALL
FormController::getElementType(void) throw( RuntimeException
)
1135 return ::getCppuType((const Reference
< XFormController
>*)0);
1139 // XEnumerationAccess
1140 //------------------------------------------------------------------------------
1141 Reference
< XEnumeration
> SAL_CALL
FormController::createEnumeration(void) throw( RuntimeException
)
1143 ::osl::MutexGuard
aGuard( m_aMutex
);
1144 return new ::comphelper::OEnumerationByIndex(this);
1148 //------------------------------------------------------------------------------
1149 sal_Int32 SAL_CALL
FormController::getCount(void) throw( RuntimeException
)
1151 ::osl::MutexGuard
aGuard( m_aMutex
);
1152 return m_aChildren
.size();
1155 //------------------------------------------------------------------------------
1156 Any SAL_CALL
FormController::getByIndex(sal_Int32 Index
) throw( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
1158 ::osl::MutexGuard
aGuard( m_aMutex
);
1160 Index
>= (sal_Int32
)m_aChildren
.size())
1161 throw IndexOutOfBoundsException();
1163 return makeAny( m_aChildren
[ Index
] );
1167 //------------------------------------------------------------------------------
1168 void SAL_CALL
FormController::disposing(const EventObject
& e
) throw( RuntimeException
)
1170 // Ist der Container disposed worden
1171 ::osl::MutexGuard
aGuard( m_aMutex
);
1172 Reference
< XControlContainer
> xContainer(e
.Source
, UNO_QUERY
);
1173 if (xContainer
.is())
1175 setContainer(Reference
< XControlContainer
> ());
1179 // ist ein Control disposed worden
1180 Reference
< XControl
> xControl(e
.Source
, UNO_QUERY
);
1183 if (getContainer().is())
1184 removeControl(xControl
);
1190 //-----------------------------------------------------------------------------
1191 void FormController::disposeAllFeaturesAndDispatchers() SAL_THROW(())
1193 for ( DispatcherContainer::iterator aDispatcher
= m_aFeatureDispatchers
.begin();
1194 aDispatcher
!= m_aFeatureDispatchers
.end();
1200 ::comphelper::disposeComponent( aDispatcher
->second
);
1202 catch( const Exception
& )
1204 DBG_UNHANDLED_EXCEPTION();
1207 m_aFeatureDispatchers
.clear();
1210 //-----------------------------------------------------------------------------
1211 void FormController::disposing(void)
1213 EventObject
aEvt( *this );
1215 // if we're still active, simulate a "deactivated" event
1216 if ( m_xActiveControl
.is() )
1217 m_aActivateListeners
.notifyEach( &XFormControllerListener::formDeactivated
, aEvt
);
1219 // notify all our listeners
1220 m_aActivateListeners
.disposeAndClear(aEvt
);
1221 m_aModifyListeners
.disposeAndClear(aEvt
);
1222 m_aErrorListeners
.disposeAndClear(aEvt
);
1223 m_aDeleteListeners
.disposeAndClear(aEvt
);
1224 m_aRowSetApproveListeners
.disposeAndClear(aEvt
);
1225 m_aParameterListeners
.disposeAndClear(aEvt
);
1226 m_aFilterListeners
.disposeAndClear(aEvt
);
1228 removeBoundFieldListener();
1231 m_pControlBorderManager
->restoreAll();
1233 m_aFilterRows
.clear();
1235 ::osl::MutexGuard
aGuard( m_aMutex
);
1236 m_xActiveControl
= NULL
;
1237 implSetCurrentControl( NULL
);
1239 // clean up our children
1240 for (FmFormControllers::const_iterator i
= m_aChildren
.begin();
1241 i
!= m_aChildren
.end(); ++i
)
1243 // search the position of the model within the form
1244 Reference
< XFormComponent
> xForm((*i
)->getModel(), UNO_QUERY
);
1245 sal_uInt32 nPos
= m_xModelAsIndex
->getCount();
1246 Reference
< XFormComponent
> xTemp
;
1250 m_xModelAsIndex
->getByIndex( --nPos
) >>= xTemp
;
1251 if ( xForm
.get() == xTemp
.get() )
1253 Reference
< XInterface
> xIfc( *i
, UNO_QUERY
);
1254 m_xModelAsManager
->detach( nPos
, xIfc
);
1259 Reference
< XComponent
> (*i
, UNO_QUERY
)->dispose();
1261 m_aChildren
.clear();
1263 disposeAllFeaturesAndDispatchers();
1265 if ( m_xFormOperations
.is() )
1266 m_xFormOperations
->dispose();
1267 m_xFormOperations
.clear();
1269 if (m_bDBConnection
)
1272 setContainer( NULL
);
1276 ::comphelper::disposeComponent( m_xComposer
);
1278 m_bDBConnection
= sal_False
;
1281 //------------------------------------------------------------------------------
1284 static bool lcl_shouldUseDynamicControlBorder( const Reference
< XInterface
>& _rxForm
, const Any
& _rDynamicColorProp
)
1286 bool bDoUse
= false;
1287 if ( !( _rDynamicColorProp
>>= bDoUse
) )
1289 DocumentType eDocType
= DocumentClassification::classifyHostDocument( _rxForm
);
1290 return ControlLayouter::useDynamicBorderColor( eDocType
);
1296 //------------------------------------------------------------------------------
1297 void SAL_CALL
FormController::propertyChange(const PropertyChangeEvent
& evt
) throw( RuntimeException
)
1299 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1300 if ( evt
.PropertyName
== FM_PROP_BOUNDFIELD
)
1302 Reference
<XPropertySet
> xOldBound
;
1303 evt
.OldValue
>>= xOldBound
;
1304 if ( !xOldBound
.is() && evt
.NewValue
.hasValue() )
1306 Reference
< XControlModel
> xControlModel(evt
.Source
,UNO_QUERY
);
1307 Reference
< XControl
> xControl
= findControl(m_aControls
,xControlModel
,sal_False
,sal_False
);
1308 if ( xControl
.is() )
1310 startControlModifyListening( xControl
);
1311 Reference
<XPropertySet
> xProp(xControlModel
,UNO_QUERY
);
1313 xProp
->removePropertyChangeListener(FM_PROP_BOUNDFIELD
, this);
1319 sal_Bool bModifiedChanged
= (evt
.PropertyName
== FM_PROP_ISMODIFIED
);
1320 sal_Bool bNewChanged
= (evt
.PropertyName
== FM_PROP_ISNEW
);
1321 if (bModifiedChanged
|| bNewChanged
)
1323 ::osl::MutexGuard
aGuard( m_aMutex
);
1324 if (bModifiedChanged
)
1325 m_bCurrentRecordModified
= ::comphelper::getBOOL(evt
.NewValue
);
1327 m_bCurrentRecordNew
= ::comphelper::getBOOL(evt
.NewValue
);
1329 // toggle the locking
1330 if (m_bLocked
!= determineLockState())
1332 m_bLocked
= !m_bLocked
;
1334 if (isListeningForChanges())
1341 m_aToggleEvent
.Call();
1343 if (!m_bCurrentRecordModified
)
1344 m_bModified
= sal_False
;
1346 else if ( evt
.PropertyName
== FM_PROP_DYNAMIC_CONTROL_BORDER
)
1348 bool bEnable
= lcl_shouldUseDynamicControlBorder( evt
.Source
, evt
.NewValue
);
1351 m_pControlBorderManager
->enableDynamicBorderColor();
1352 if ( m_xActiveControl
.is() )
1353 m_pControlBorderManager
->focusGained( m_xActiveControl
.get() );
1357 m_pControlBorderManager
->disableDynamicBorderColor();
1363 //------------------------------------------------------------------------------
1364 bool FormController::replaceControl( const Reference
< XControl
>& _rxExistentControl
, const Reference
< XControl
>& _rxNewControl
)
1366 bool bSuccess
= false;
1369 Reference
< XIdentifierReplace
> xContainer( getContainer(), UNO_QUERY
);
1370 DBG_ASSERT( xContainer
.is(), "FormController::replaceControl: yes, it's not required by the service description, but XItentifierReplaces would be nice!" );
1371 if ( xContainer
.is() )
1373 // look up the ID of _rxExistentControl
1374 Sequence
< sal_Int32
> aIdentifiers( xContainer
->getIdentifiers() );
1375 const sal_Int32
* pIdentifiers
= aIdentifiers
.getConstArray();
1376 const sal_Int32
* pIdentifiersEnd
= aIdentifiers
.getConstArray() + aIdentifiers
.getLength();
1377 for ( ; pIdentifiers
!= pIdentifiersEnd
; ++pIdentifiers
)
1379 Reference
< XControl
> xCheck( xContainer
->getByIdentifier( *pIdentifiers
), UNO_QUERY
);
1380 if ( xCheck
== _rxExistentControl
)
1383 DBG_ASSERT( pIdentifiers
!= pIdentifiersEnd
, "FormController::replaceControl: did not find the control in the container!" );
1384 if ( pIdentifiers
!= pIdentifiersEnd
)
1386 bool bReplacedWasActive
= ( m_xActiveControl
.get() == _rxExistentControl
.get() );
1387 bool bReplacedWasCurrent
= ( m_xCurrentControl
.get() == _rxExistentControl
.get() );
1389 if ( bReplacedWasActive
)
1391 m_xActiveControl
= NULL
;
1392 implSetCurrentControl( NULL
);
1394 else if ( bReplacedWasCurrent
)
1396 implSetCurrentControl( _rxNewControl
);
1399 // carry over the model
1400 _rxNewControl
->setModel( _rxExistentControl
->getModel() );
1402 xContainer
->replaceByIdentifer( *pIdentifiers
, makeAny( _rxNewControl
) );
1405 if ( bReplacedWasActive
)
1407 Reference
< XWindow
> xControlWindow( _rxNewControl
, UNO_QUERY
);
1408 if ( xControlWindow
.is() )
1409 xControlWindow
->setFocus();
1414 catch( const Exception
& )
1416 DBG_UNHANDLED_EXCEPTION();
1419 Reference
< XControl
> xDisposeIt( bSuccess
? _rxExistentControl
: _rxNewControl
);
1420 ::comphelper::disposeComponent( xDisposeIt
);
1424 //------------------------------------------------------------------------------
1425 void FormController::toggleAutoFields(sal_Bool bAutoFields
)
1427 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1430 Sequence
< Reference
< XControl
> > aControlsCopy( m_aControls
);
1431 const Reference
< XControl
>* pControls
= aControlsCopy
.getConstArray();
1432 sal_Int32 nControls
= aControlsCopy
.getLength();
1436 // as we don't want new controls to be attached to the scripting environment
1437 // we change attach flags
1438 m_bAttachEvents
= sal_False
;
1439 for (sal_Int32 i
= nControls
; i
> 0;)
1441 Reference
< XControl
> xControl
= pControls
[--i
];
1444 Reference
< XPropertySet
> xSet(xControl
->getModel(), UNO_QUERY
);
1445 if (xSet
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
1447 // does the model use a bound field ?
1448 Reference
< XPropertySet
> xField
;
1449 xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
1451 // is it a autofield?
1453 && ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT
, xField
)
1454 && ::comphelper::getBOOL( xField
->getPropertyValue( FM_PROP_AUTOINCREMENT
) )
1457 replaceControl( xControl
, new FmXAutoControl( m_aContext
) );
1462 m_bAttachEvents
= sal_True
;
1466 m_bDetachEvents
= sal_False
;
1467 for (sal_Int32 i
= nControls
; i
> 0;)
1469 Reference
< XControl
> xControl
= pControls
[--i
];
1472 Reference
< XPropertySet
> xSet(xControl
->getModel(), UNO_QUERY
);
1473 if (xSet
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
1475 // does the model use a bound field ?
1476 Reference
< XPropertySet
> xField
;
1477 xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
1479 // is it a autofield?
1481 && ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT
, xField
)
1482 && ::comphelper::getBOOL( xField
->getPropertyValue(FM_PROP_AUTOINCREMENT
) )
1485 ::rtl::OUString sServiceName
;
1486 OSL_VERIFY( xSet
->getPropertyValue( FM_PROP_DEFAULTCONTROL
) >>= sServiceName
);
1487 Reference
< XControl
> xNewControl( m_aContext
.createComponent( sServiceName
), UNO_QUERY
);
1488 replaceControl( xControl
, xNewControl
);
1493 m_bDetachEvents
= sal_True
;
1497 //------------------------------------------------------------------------------
1498 IMPL_LINK_NOARG(FormController
, OnToggleAutoFields
)
1500 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1502 toggleAutoFields(m_bCurrentRecordNew
);
1507 //------------------------------------------------------------------------------
1508 void SAL_CALL
FormController::textChanged(const TextEvent
& e
) throw( RuntimeException
)
1511 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1512 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1513 if ( !m_bFiltering
)
1519 if ( m_bSuspendFilterTextListening
)
1522 Reference
< XTextComponent
> xText(e
.Source
,UNO_QUERY
);
1523 ::rtl::OUString aText
= xText
->getText();
1525 if ( m_aFilterRows
.empty() )
1526 appendEmptyDisjunctiveTerm();
1528 // Suchen der aktuellen Row
1529 if ( ( (size_t)m_nCurrentFilterPosition
>= m_aFilterRows
.size() ) || ( m_nCurrentFilterPosition
< 0 ) )
1531 OSL_ENSURE( false, "FormController::textChanged: m_nCurrentFilterPosition is wrong!" );
1535 FmFilterRow
& rRow
= m_aFilterRows
[ m_nCurrentFilterPosition
];
1537 // do we have a new filter
1538 if (!aText
.isEmpty())
1539 rRow
[xText
] = aText
;
1542 // do we have the control in the row
1543 FmFilterRow::iterator iter
= rRow
.find(xText
);
1544 // erase the entry out of the row
1545 if (iter
!= rRow
.end())
1549 // multiplex the event to our FilterControllerListeners
1551 aEvent
.Source
= *this;
1552 aEvent
.FilterComponent
= ::std::find( m_aFilterComponents
.begin(), m_aFilterComponents
.end(), xText
) - m_aFilterComponents
.begin();
1553 aEvent
.DisjunctiveTerm
= getActiveTerm();
1554 aEvent
.PredicateExpression
= aText
;
1559 // notify the changed filter expression
1560 m_aFilterListeners
.notifyEach( &XFilterControllerListener::predicateExpressionChanged
, aEvent
);
1564 //------------------------------------------------------------------------------
1565 void SAL_CALL
FormController::itemStateChanged(const ItemEvent
& /*rEvent*/) throw( RuntimeException
)
1567 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1571 // XModificationBroadcaster
1572 //------------------------------------------------------------------------------
1573 void SAL_CALL
FormController::addModifyListener(const Reference
< XModifyListener
> & l
) throw( RuntimeException
)
1575 ::osl::MutexGuard
aGuard( m_aMutex
);
1576 impl_checkDisposed_throw();
1577 m_aModifyListeners
.addInterface( l
);
1580 //------------------------------------------------------------------------------
1581 void FormController::removeModifyListener(const Reference
< XModifyListener
> & l
) throw( RuntimeException
)
1583 ::osl::MutexGuard
aGuard( m_aMutex
);
1584 impl_checkDisposed_throw();
1585 m_aModifyListeners
.removeInterface( l
);
1588 // XModificationListener
1589 //------------------------------------------------------------------------------
1590 void FormController::modified( const EventObject
& _rEvent
) throw( RuntimeException
)
1592 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1596 if ( _rEvent
.Source
!= m_xActiveControl
)
1597 { // let this control grab the focus
1598 // (this case may happen if somebody moves the scroll wheel of the mouse over a control
1599 // which does not have the focus)
1600 // 85511 - 29.05.2001 - frank.schoenheit@germany.sun.com
1602 // also, it happens when an image control gets a new image by double-clicking it
1603 // #i88458# / 2009-01-12 / frank.schoenheit@sun.com
1604 Reference
< XWindow
> xControlWindow( _rEvent
.Source
, UNO_QUERY_THROW
);
1605 xControlWindow
->setFocus();
1608 catch( const Exception
& )
1610 DBG_UNHANDLED_EXCEPTION();
1616 //------------------------------------------------------------------------------
1617 void FormController::impl_checkDisposed_throw() const
1619 if ( impl_isDisposed_nofail() )
1620 throw DisposedException( ::rtl::OUString(), *const_cast< FormController
* >( this ) );
1623 //------------------------------------------------------------------------------
1624 void FormController::impl_onModify()
1626 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1629 ::osl::MutexGuard
aGuard( m_aMutex
);
1631 m_bModified
= sal_True
;
1634 EventObject
aEvt(static_cast<cppu::OWeakObject
*>(this));
1635 m_aModifyListeners
.notifyEach( &XModifyListener::modified
, aEvt
);
1638 //------------------------------------------------------------------------------
1639 void FormController::impl_addFilterRow( const FmFilterRow
& _row
)
1641 m_aFilterRows
.push_back( _row
);
1643 if ( m_aFilterRows
.size() == 1 )
1644 { // that's the first row ever
1645 OSL_ENSURE( m_nCurrentFilterPosition
== -1, "FormController::impl_addFilterRow: inconsistency!" );
1646 m_nCurrentFilterPosition
= 0;
1650 //------------------------------------------------------------------------------
1651 void FormController::impl_appendEmptyFilterRow( ::osl::ClearableMutexGuard
& _rClearBeforeNotify
)
1654 impl_addFilterRow( FmFilterRow() );
1656 // notify the listeners
1658 aEvent
.Source
= *this;
1659 aEvent
.DisjunctiveTerm
= (sal_Int32
)m_aFilterRows
.size() - 1;
1660 _rClearBeforeNotify
.clear();
1662 m_aFilterListeners
.notifyEach( &XFilterControllerListener::disjunctiveTermAdded
, aEvent
);
1665 //------------------------------------------------------------------------------
1666 sal_Bool
FormController::determineLockState() const
1668 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1669 // a.) in filter mode we are always locked
1670 // b.) if we have no valid model or our model (a result set) is not alive -> we're locked
1671 // c.) if we are inserting everything is OK and we are not locked
1672 // d.) if are not updatable or on invalid position
1673 Reference
< XResultSet
> xResultSet(m_xModelAsIndex
, UNO_QUERY
);
1674 if (m_bFiltering
|| !xResultSet
.is() || !isRowSetAlive(xResultSet
))
1677 return (m_bCanInsert
&& m_bCurrentRecordNew
) ? sal_False
1678 : xResultSet
->isBeforeFirst() || xResultSet
->isAfterLast() || xResultSet
->rowDeleted() || !m_bCanUpdate
;
1682 //------------------------------------------------------------------------------
1683 void FormController::focusGained(const FocusEvent
& e
) throw( RuntimeException
)
1686 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1687 impl_checkDisposed_throw();
1689 m_pControlBorderManager
->focusGained( e
.Source
);
1691 Reference
< XControl
> xControl(e
.Source
, UNO_QUERY
);
1692 if (m_bDBConnection
)
1694 // do we need to keep the locking of the commit
1695 // we hold the lock as long as the control differs from the current
1696 // otherwhise we disabled the lock
1697 m_bCommitLock
= m_bCommitLock
&& (XControl
*)xControl
.get() != (XControl
*)m_xCurrentControl
.get();
1701 // when do we have to commit a value to form or a filter
1702 // a.) if the current value is modified
1703 // b.) there must be a current control
1704 // c.) and it must be different from the new focus owning control or
1705 // d.) the focus is moving around (so we have only one control)
1707 if ( ( m_bModified
|| m_bFiltering
)
1708 && m_xCurrentControl
.is()
1709 && ( ( xControl
.get() != m_xCurrentControl
.get() )
1710 || ( ( e
.FocusFlags
& FocusChangeReason::AROUND
)
1711 && ( m_bCycle
|| m_bFiltering
)
1716 // check the old control if the content is ok
1717 #if OSL_DEBUG_LEVEL > 1
1718 Reference
< XBoundControl
> xLockingTest(m_xCurrentControl
, UNO_QUERY
);
1719 sal_Bool bControlIsLocked
= xLockingTest
.is() && xLockingTest
->getLock();
1720 OSL_ENSURE(!bControlIsLocked
, "FormController::Gained: I'm modified and the current control is locked ? How this ?");
1721 // normalerweise sollte ein gelocktes Control nicht modified sein, also muss wohl mein bModified aus einem anderen Kontext
1722 // gesetzt worden sein, was ich nicht verstehen wuerde ...
1724 DBG_ASSERT(m_xCurrentControl
.is(), "kein CurrentControl gesetzt");
1725 // zunaechst das Control fragen ob es das IFace unterstuetzt
1726 Reference
< XBoundComponent
> xBound(m_xCurrentControl
, UNO_QUERY
);
1727 if (!xBound
.is() && m_xCurrentControl
.is())
1728 xBound
= Reference
< XBoundComponent
> (m_xCurrentControl
->getModel(), UNO_QUERY
);
1730 // lock if we lose the focus during commit
1731 m_bCommitLock
= sal_True
;
1733 // Commit nicht erfolgreich, Focus zuruecksetzen
1734 if (xBound
.is() && !xBound
->commit())
1736 // the commit failed and we don't commit again until the current control
1737 // which couldn't be commit gains the focus again
1738 Reference
< XWindow
> xWindow(m_xCurrentControl
, UNO_QUERY
);
1740 xWindow
->setFocus();
1745 m_bModified
= sal_False
;
1746 m_bCommitLock
= sal_False
;
1750 if (!m_bFiltering
&& m_bCycle
&& (e
.FocusFlags
& FocusChangeReason::AROUND
) && m_xCurrentControl
.is())
1752 SQLErrorEvent aErrorEvent
;
1753 OSL_ENSURE( m_xFormOperations
.is(), "FormController::focusGained: hmm?" );
1754 // should have been created in setModel
1757 if ( e
.FocusFlags
& FocusChangeReason::FORWARD
)
1759 if ( m_xFormOperations
.is() && m_xFormOperations
->isEnabled( FormFeature::MoveToNext
) )
1760 m_xFormOperations
->execute( FormFeature::MoveToNext
);
1764 if ( m_xFormOperations
.is() && m_xFormOperations
->isEnabled( FormFeature::MoveToPrevious
) )
1765 m_xFormOperations
->execute( FormFeature::MoveToPrevious
);
1768 catch ( const Exception
& )
1770 // don't handle this any further. That's an ... admissible error.
1771 DBG_UNHANDLED_EXCEPTION();
1776 // Immer noch ein und dasselbe Control
1777 if ( ( m_xActiveControl
== xControl
)
1778 && ( xControl
== m_xCurrentControl
)
1781 DBG_ASSERT(m_xCurrentControl
.is(), "Kein CurrentControl selektiert");
1785 sal_Bool bActivated
= !m_xActiveControl
.is() && xControl
.is();
1787 m_xActiveControl
= xControl
;
1789 implSetCurrentControl( xControl
);
1790 OSL_POSTCOND( m_xCurrentControl
.is(), "implSetCurrentControl did nonsense!" );
1794 // (asynchronously) call activation handlers
1795 m_aActivationEvent
.Call();
1797 // call modify listeners
1799 m_aModifyListeners
.notifyEach( &XModifyListener::modified
, EventObject( *this ) );
1802 // invalidate all features which depend on the currently focused control
1803 if ( m_bDBConnection
&& !m_bFiltering
)
1804 implInvalidateCurrentControlDependentFeatures();
1806 if ( !m_xCurrentControl
.is() )
1809 // Control erhaelt Focus, dann eventuell in den sichtbaren Bereich
1810 Reference
< XFormControllerContext
> xContext( m_xContext
);
1811 Reference
< XControl
> xCurrentControl( m_xCurrentControl
);
1815 if ( xContext
.is() )
1816 xContext
->makeVisible( xCurrentControl
);
1819 //------------------------------------------------------------------------------
1820 IMPL_LINK( FormController
, OnActivated
, void*, /**/ )
1823 aEvent
.Source
= *this;
1824 m_aActivateListeners
.notifyEach( &XFormControllerListener::formActivated
, aEvent
);
1829 //------------------------------------------------------------------------------
1830 IMPL_LINK( FormController
, OnDeactivated
, void*, /**/ )
1833 aEvent
.Source
= *this;
1834 m_aActivateListeners
.notifyEach( &XFormControllerListener::formDeactivated
, aEvent
);
1839 //------------------------------------------------------------------------------
1840 void FormController::focusLost(const FocusEvent
& e
) throw( RuntimeException
)
1842 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
1844 m_pControlBorderManager
->focusLost( e
.Source
);
1846 Reference
< XControl
> xControl(e
.Source
, UNO_QUERY
);
1847 Reference
< XWindowPeer
> xNext(e
.NextFocus
, UNO_QUERY
);
1848 Reference
< XControl
> xNextControl
= isInList(xNext
);
1849 if (!xNextControl
.is())
1851 m_xActiveControl
= NULL
;
1852 m_aDeactivationEvent
.Call();
1856 //--------------------------------------------------------------------
1857 void SAL_CALL
FormController::mousePressed( const awt::MouseEvent
& /*_rEvent*/ ) throw (RuntimeException
)
1859 // not interested in
1862 //--------------------------------------------------------------------
1863 void SAL_CALL
FormController::mouseReleased( const awt::MouseEvent
& /*_rEvent*/ ) throw (RuntimeException
)
1865 // not interested in
1868 //--------------------------------------------------------------------
1869 void SAL_CALL
FormController::mouseEntered( const awt::MouseEvent
& _rEvent
) throw (RuntimeException
)
1871 m_pControlBorderManager
->mouseEntered( _rEvent
.Source
);
1874 //--------------------------------------------------------------------
1875 void SAL_CALL
FormController::mouseExited( const awt::MouseEvent
& _rEvent
) throw (RuntimeException
)
1877 m_pControlBorderManager
->mouseExited( _rEvent
.Source
);
1880 //--------------------------------------------------------------------
1881 void SAL_CALL
FormController::componentValidityChanged( const EventObject
& _rSource
) throw (RuntimeException
)
1883 Reference
< XControl
> xControl( findControl( m_aControls
, Reference
< XControlModel
>( _rSource
.Source
, UNO_QUERY
), sal_False
, sal_False
) );
1884 Reference
< XValidatableFormComponent
> xValidatable( _rSource
.Source
, UNO_QUERY
);
1886 OSL_ENSURE( xControl
.is() && xValidatable
.is(), "FormController::componentValidityChanged: huh?" );
1888 if ( xControl
.is() && xValidatable
.is() )
1889 m_pControlBorderManager
->validityChanged( xControl
, xValidatable
);
1892 //--------------------------------------------------------------------
1893 void FormController::setModel(const Reference
< XTabControllerModel
> & Model
) throw( RuntimeException
)
1895 ::osl::MutexGuard
aGuard( m_aMutex
);
1896 impl_checkDisposed_throw();
1898 DBG_ASSERT(m_xTabController
.is(), "FormController::setModel : invalid aggregate !");
1902 // disconnect from the old model
1903 if (m_xModelAsIndex
.is())
1905 if (m_bDBConnection
)
1907 // we are currently working on the model
1908 EventObject
aEvt(m_xModelAsIndex
);
1912 Reference
< XLoadable
> xForm(m_xModelAsIndex
, UNO_QUERY
);
1914 xForm
->removeLoadListener(this);
1916 Reference
< XSQLErrorBroadcaster
> xBroadcaster(m_xModelAsIndex
, UNO_QUERY
);
1917 if (xBroadcaster
.is())
1918 xBroadcaster
->removeSQLErrorListener(this);
1920 Reference
< XDatabaseParameterBroadcaster
> xParamBroadcaster(m_xModelAsIndex
, UNO_QUERY
);
1921 if (xParamBroadcaster
.is())
1922 xParamBroadcaster
->removeParameterListener(this);
1926 disposeAllFeaturesAndDispatchers();
1928 if ( m_xFormOperations
.is() )
1929 m_xFormOperations
->dispose();
1930 m_xFormOperations
.clear();
1932 // set the new model wait for the load event
1933 if (m_xTabController
.is())
1934 m_xTabController
->setModel(Model
);
1935 m_xModelAsIndex
= Reference
< XIndexAccess
> (Model
, UNO_QUERY
);
1936 m_xModelAsManager
= Reference
< XEventAttacherManager
> (Model
, UNO_QUERY
);
1938 // only if both ifaces exit, the controller will work successful
1939 if (!m_xModelAsIndex
.is() || !m_xModelAsManager
.is())
1941 m_xModelAsManager
= NULL
;
1942 m_xModelAsIndex
= NULL
;
1945 if (m_xModelAsIndex
.is())
1947 // re-create m_xFormOperations
1948 m_xFormOperations
.set( FormOperations::createWithFormController( m_aContext
.getUNOContext(), this ), UNO_SET_THROW
);
1949 m_xFormOperations
->setFeatureInvalidation( this );
1951 // adding load and ui interaction listeners
1952 Reference
< XLoadable
> xForm(Model
, UNO_QUERY
);
1954 xForm
->addLoadListener(this);
1956 Reference
< XSQLErrorBroadcaster
> xBroadcaster(Model
, UNO_QUERY
);
1957 if (xBroadcaster
.is())
1958 xBroadcaster
->addSQLErrorListener(this);
1960 Reference
< XDatabaseParameterBroadcaster
> xParamBroadcaster(Model
, UNO_QUERY
);
1961 if (xParamBroadcaster
.is())
1962 xParamBroadcaster
->addParameterListener(this);
1964 // well, is the database already loaded?
1965 // then we have to simulate a load event
1966 Reference
< XLoadable
> xCursor(m_xModelAsIndex
, UNO_QUERY
);
1967 if (xCursor
.is() && xCursor
->isLoaded())
1969 EventObject
aEvt(xCursor
);
1973 Reference
< XPropertySet
> xModelProps( m_xModelAsIndex
, UNO_QUERY
);
1974 Reference
< XPropertySetInfo
> xPropInfo( xModelProps
->getPropertySetInfo() );
1976 && xPropInfo
->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER
)
1977 && xPropInfo
->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_FOCUS
)
1978 && xPropInfo
->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_MOUSE
)
1979 && xPropInfo
->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_INVALID
)
1982 bool bEnableDynamicControlBorder
= lcl_shouldUseDynamicControlBorder(
1983 xModelProps
.get(), xModelProps
->getPropertyValue( FM_PROP_DYNAMIC_CONTROL_BORDER
) );
1984 if ( bEnableDynamicControlBorder
)
1985 m_pControlBorderManager
->enableDynamicBorderColor();
1987 m_pControlBorderManager
->disableDynamicBorderColor();
1989 sal_Int32 nColor
= 0;
1990 if ( xModelProps
->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_FOCUS
) >>= nColor
)
1991 m_pControlBorderManager
->setStatusColor( CONTROL_STATUS_FOCUSED
, nColor
);
1992 if ( xModelProps
->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_MOUSE
) >>= nColor
)
1993 m_pControlBorderManager
->setStatusColor( CONTROL_STATUS_MOUSE_HOVER
, nColor
);
1994 if ( xModelProps
->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_INVALID
) >>= nColor
)
1995 m_pControlBorderManager
->setStatusColor( CONTROL_STATUS_INVALID
, nColor
);
1999 catch( const Exception
& )
2001 DBG_UNHANDLED_EXCEPTION();
2005 //------------------------------------------------------------------------------
2006 Reference
< XTabControllerModel
> FormController::getModel() throw( RuntimeException
)
2008 ::osl::MutexGuard
aGuard( m_aMutex
);
2009 impl_checkDisposed_throw();
2011 DBG_ASSERT(m_xTabController
.is(), "FormController::getModel : invalid aggregate !");
2012 if (!m_xTabController
.is())
2013 return Reference
< XTabControllerModel
> ();
2014 return m_xTabController
->getModel();
2017 //------------------------------------------------------------------------------
2018 void FormController::addToEventAttacher(const Reference
< XControl
> & xControl
)
2020 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2021 OSL_ENSURE( xControl
.is(), "FormController::addToEventAttacher: invalid control - how did you reach this?" );
2022 if ( !xControl
.is() )
2023 return; /* throw IllegalArgumentException(); */
2025 // anmelden beim Eventattacher
2026 Reference
< XFormComponent
> xComp(xControl
->getModel(), UNO_QUERY
);
2027 if (xComp
.is() && m_xModelAsIndex
.is())
2029 // Und die Position des ControlModel darin suchen
2030 sal_uInt32 nPos
= m_xModelAsIndex
->getCount();
2031 Reference
< XFormComponent
> xTemp
;
2034 m_xModelAsIndex
->getByIndex(--nPos
) >>= xTemp
;
2035 if ((XFormComponent
*)xComp
.get() == (XFormComponent
*)xTemp
.get())
2037 Reference
< XInterface
> xIfc(xControl
, UNO_QUERY
);
2038 m_xModelAsManager
->attach( nPos
, xIfc
, makeAny(xControl
) );
2045 //------------------------------------------------------------------------------
2046 void FormController::removeFromEventAttacher(const Reference
< XControl
> & xControl
)
2048 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2049 OSL_ENSURE( xControl
.is(), "FormController::removeFromEventAttacher: invalid control - how did you reach this?" );
2050 if ( !xControl
.is() )
2051 return; /* throw IllegalArgumentException(); */
2053 // abmelden beim Eventattacher
2054 Reference
< XFormComponent
> xComp(xControl
->getModel(), UNO_QUERY
);
2055 if ( xComp
.is() && m_xModelAsIndex
.is() )
2057 // Und die Position des ControlModel darin suchen
2058 sal_uInt32 nPos
= m_xModelAsIndex
->getCount();
2059 Reference
< XFormComponent
> xTemp
;
2062 m_xModelAsIndex
->getByIndex(--nPos
) >>= xTemp
;
2063 if ((XFormComponent
*)xComp
.get() == (XFormComponent
*)xTemp
.get())
2065 Reference
< XInterface
> xIfc(xControl
, UNO_QUERY
);
2066 m_xModelAsManager
->detach( nPos
, xIfc
);
2073 //------------------------------------------------------------------------------
2074 void FormController::setContainer(const Reference
< XControlContainer
> & xContainer
) throw( RuntimeException
)
2076 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2077 Reference
< XTabControllerModel
> xTabModel(getModel());
2078 DBG_ASSERT(xTabModel
.is() || !xContainer
.is(), "No Model defined");
2079 // if we have a new container we need a model
2080 DBG_ASSERT(m_xTabController
.is(), "FormController::setContainer : invalid aggregate !");
2082 ::osl::MutexGuard
aGuard( m_aMutex
);
2083 Reference
< XContainer
> xCurrentContainer
;
2084 if (m_xTabController
.is())
2085 xCurrentContainer
= Reference
< XContainer
> (m_xTabController
->getContainer(), UNO_QUERY
);
2086 if (xCurrentContainer
.is())
2088 xCurrentContainer
->removeContainerListener(this);
2090 if ( m_aTabActivationTimer
.IsActive() )
2091 m_aTabActivationTimer
.Stop();
2093 // clear the filter map
2094 ::std::for_each( m_aFilterComponents
.begin(), m_aFilterComponents
.end(), RemoveComponentTextListener( this ) );
2095 m_aFilterComponents
.clear();
2097 // einsammeln der Controls
2098 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2099 const Reference
< XControl
>* pControlsEnd
= pControls
+ m_aControls
.getLength();
2100 while ( pControls
!= pControlsEnd
)
2101 implControlRemoved( *pControls
++, true );
2103 // Datenbank spezifische Dinge vornehmen
2104 if (m_bDBConnection
&& isListeningForChanges())
2107 m_aControls
.realloc( 0 );
2110 if (m_xTabController
.is())
2111 m_xTabController
->setContainer(xContainer
);
2113 // Welche Controls gehoeren zum Container ?
2114 if (xContainer
.is() && xTabModel
.is())
2116 Sequence
< Reference
< XControlModel
> > aModels
= xTabModel
->getControlModels();
2117 const Reference
< XControlModel
> * pModels
= aModels
.getConstArray();
2118 Sequence
< Reference
< XControl
> > aAllControls
= xContainer
->getControls();
2120 sal_Int32 nCount
= aModels
.getLength();
2121 m_aControls
= Sequence
< Reference
< XControl
> >( nCount
);
2122 Reference
< XControl
> * pControls
= m_aControls
.getArray();
2124 // einsammeln der Controls
2126 for (i
= 0, j
= 0; i
< nCount
; ++i
, ++pModels
)
2128 Reference
< XControl
> xControl
= findControl( aAllControls
, *pModels
, sal_False
, sal_True
);
2129 if ( xControl
.is() )
2131 pControls
[j
++] = xControl
;
2132 implControlInserted( xControl
, true );
2136 // not every model had an associated control
2138 m_aControls
.realloc(j
);
2140 // am Container horchen
2141 Reference
< XContainer
> xNewContainer(xContainer
, UNO_QUERY
);
2142 if (xNewContainer
.is())
2143 xNewContainer
->addContainerListener(this);
2145 // Datenbank spezifische Dinge vornehmen
2146 if (m_bDBConnection
)
2148 m_bLocked
= determineLockState();
2154 // befinden sich die Controls in der richtigen Reihenfolge
2155 m_bControlsSorted
= sal_True
;
2158 //------------------------------------------------------------------------------
2159 Reference
< XControlContainer
> FormController::getContainer() throw( RuntimeException
)
2161 ::osl::MutexGuard
aGuard( m_aMutex
);
2162 impl_checkDisposed_throw();
2164 DBG_ASSERT(m_xTabController
.is(), "FormController::getContainer : invalid aggregate !");
2165 if (!m_xTabController
.is())
2166 return Reference
< XControlContainer
> ();
2167 return m_xTabController
->getContainer();
2170 //------------------------------------------------------------------------------
2171 Sequence
< Reference
< XControl
> > FormController::getControls(void) throw( RuntimeException
)
2173 ::osl::MutexGuard
aGuard( m_aMutex
);
2174 impl_checkDisposed_throw();
2176 if (!m_bControlsSorted
)
2178 Reference
< XTabControllerModel
> xModel
= getModel();
2182 Sequence
< Reference
< XControlModel
> > aControlModels
= xModel
->getControlModels();
2183 const Reference
< XControlModel
> * pModels
= aControlModels
.getConstArray();
2184 sal_Int32 nModels
= aControlModels
.getLength();
2186 Sequence
< Reference
< XControl
> > aNewControls(nModels
);
2188 Reference
< XControl
> * pControls
= aNewControls
.getArray();
2189 Reference
< XControl
> xControl
;
2191 // Umsortieren der Controls entsprechend der TabReihenfolge
2193 for (sal_Int32 i
= 0; i
< nModels
; ++i
, ++pModels
)
2195 xControl
= findControl( m_aControls
, *pModels
, sal_True
, sal_True
);
2196 if ( xControl
.is() )
2197 pControls
[j
++] = xControl
;
2200 // not every model had an associated control
2202 aNewControls
.realloc( j
);
2204 m_aControls
= aNewControls
;
2205 m_bControlsSorted
= sal_True
;
2210 //------------------------------------------------------------------------------
2211 void FormController::autoTabOrder() throw( RuntimeException
)
2213 ::osl::MutexGuard
aGuard( m_aMutex
);
2214 impl_checkDisposed_throw();
2216 DBG_ASSERT(m_xTabController
.is(), "FormController::autoTabOrder : invalid aggregate !");
2217 if (m_xTabController
.is())
2218 m_xTabController
->autoTabOrder();
2221 //------------------------------------------------------------------------------
2222 void FormController::activateTabOrder() throw( RuntimeException
)
2224 ::osl::MutexGuard
aGuard( m_aMutex
);
2225 impl_checkDisposed_throw();
2227 DBG_ASSERT(m_xTabController
.is(), "FormController::activateTabOrder : invalid aggregate !");
2228 if (m_xTabController
.is())
2229 m_xTabController
->activateTabOrder();
2232 //------------------------------------------------------------------------------
2233 void FormController::setControlLock(const Reference
< XControl
> & xControl
)
2235 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2236 sal_Bool bLocked
= isLocked();
2239 // a.) wenn der ganze Datensatz gesperrt ist
2240 // b.) wenn das zugehoerige Feld gespeert ist
2241 Reference
< XBoundControl
> xBound(xControl
, UNO_QUERY
);
2242 if (xBound
.is() && (( (bLocked
&& bLocked
!= xBound
->getLock()) ||
2243 !bLocked
))) // beim entlocken immer einzelne Felder ueberpr�fen
2245 // gibt es eine Datenquelle
2246 Reference
< XPropertySet
> xSet(xControl
->getModel(), UNO_QUERY
);
2247 if (xSet
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
2249 // wie sieht mit den Properties ReadOnly und Enable aus
2250 sal_Bool bTouch
= sal_True
;
2251 if (::comphelper::hasProperty(FM_PROP_ENABLED
, xSet
))
2252 bTouch
= ::comphelper::getBOOL(xSet
->getPropertyValue(FM_PROP_ENABLED
));
2253 if (::comphelper::hasProperty(FM_PROP_READONLY
, xSet
))
2254 bTouch
= !::comphelper::getBOOL(xSet
->getPropertyValue(FM_PROP_READONLY
));
2258 Reference
< XPropertySet
> xField
;
2259 xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
2263 xBound
->setLock(bLocked
);
2268 Any aVal
= xField
->getPropertyValue(FM_PROP_ISREADONLY
);
2269 if (aVal
.hasValue() && ::comphelper::getBOOL(aVal
))
2270 xBound
->setLock(sal_True
);
2272 xBound
->setLock(bLocked
);
2274 catch( const Exception
& )
2276 DBG_UNHANDLED_EXCEPTION();
2286 //------------------------------------------------------------------------------
2287 void FormController::setLocks()
2289 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2290 // alle Controls, die mit einer Datenquelle verbunden sind locken/unlocken
2291 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2292 const Reference
< XControl
>* pControlsEnd
= pControls
+ m_aControls
.getLength();
2293 while ( pControls
!= pControlsEnd
)
2294 setControlLock( *pControls
++ );
2297 //------------------------------------------------------------------------------
2300 bool lcl_shouldListenForModifications( const Reference
< XControl
>& _rxControl
, const Reference
< XPropertyChangeListener
>& _rxBoundFieldListener
)
2302 bool bShould
= false;
2304 Reference
< XBoundComponent
> xBound( _rxControl
, UNO_QUERY
);
2309 else if ( _rxControl
.is() )
2311 Reference
< XPropertySet
> xModelProps( _rxControl
->getModel(), UNO_QUERY
);
2312 if ( xModelProps
.is() && ::comphelper::hasProperty( FM_PROP_BOUNDFIELD
, xModelProps
) )
2314 Reference
< XPropertySet
> xField
;
2315 xModelProps
->getPropertyValue( FM_PROP_BOUNDFIELD
) >>= xField
;
2316 bShould
= xField
.is();
2318 if ( !bShould
&& _rxBoundFieldListener
.is() )
2319 xModelProps
->addPropertyChangeListener( FM_PROP_BOUNDFIELD
, _rxBoundFieldListener
);
2327 //------------------------------------------------------------------------------
2328 void FormController::startControlModifyListening(const Reference
< XControl
> & xControl
)
2330 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2332 bool bModifyListening
= lcl_shouldListenForModifications( xControl
, this );
2335 while ( bModifyListening
)
2337 Reference
< XModifyBroadcaster
> xMod(xControl
, UNO_QUERY
);
2340 xMod
->addModifyListener(this);
2344 // alle die Text um vorzeitig ein modified zu erkennen
2345 Reference
< XTextComponent
> xText(xControl
, UNO_QUERY
);
2348 xText
->addTextListener(this);
2352 Reference
< XCheckBox
> xBox(xControl
, UNO_QUERY
);
2355 xBox
->addItemListener(this);
2359 Reference
< XComboBox
> xCbBox(xControl
, UNO_QUERY
);
2362 xCbBox
->addItemListener(this);
2366 Reference
< XListBox
> xListBox(xControl
, UNO_QUERY
);
2369 xListBox
->addItemListener(this);
2376 //------------------------------------------------------------------------------
2377 void FormController::stopControlModifyListening(const Reference
< XControl
> & xControl
)
2379 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2381 bool bModifyListening
= lcl_shouldListenForModifications( xControl
, NULL
);
2383 // kuenstliches while
2384 while (bModifyListening
)
2386 Reference
< XModifyBroadcaster
> xMod(xControl
, UNO_QUERY
);
2389 xMod
->removeModifyListener(this);
2392 // alle die Text um vorzeitig ein modified zu erkennen
2393 Reference
< XTextComponent
> xText(xControl
, UNO_QUERY
);
2396 xText
->removeTextListener(this);
2400 Reference
< XCheckBox
> xBox(xControl
, UNO_QUERY
);
2403 xBox
->removeItemListener(this);
2407 Reference
< XComboBox
> xCbBox(xControl
, UNO_QUERY
);
2410 xCbBox
->removeItemListener(this);
2414 Reference
< XListBox
> xListBox(xControl
, UNO_QUERY
);
2417 xListBox
->removeItemListener(this);
2424 //------------------------------------------------------------------------------
2425 void FormController::startListening()
2427 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2428 m_bModified
= sal_False
;
2430 // jetzt anmelden bei gebundenen feldern
2431 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2432 const Reference
< XControl
>* pControlsEnd
= pControls
+ m_aControls
.getLength();
2433 while ( pControls
!= pControlsEnd
)
2434 startControlModifyListening( *pControls
++ );
2437 //------------------------------------------------------------------------------
2438 void FormController::stopListening()
2440 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2441 m_bModified
= sal_False
;
2443 // jetzt anmelden bei gebundenen feldern
2444 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2445 const Reference
< XControl
>* pControlsEnd
= pControls
+ m_aControls
.getLength();
2446 while ( pControls
!= pControlsEnd
)
2447 stopControlModifyListening( *pControls
++ );
2451 //------------------------------------------------------------------------------
2452 Reference
< XControl
> FormController::findControl(Sequence
< Reference
< XControl
> >& _rControls
, const Reference
< XControlModel
> & xCtrlModel
,sal_Bool _bRemove
,sal_Bool _bOverWrite
) const
2454 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2455 DBG_ASSERT( xCtrlModel
.is(), "findControl - welches ?!" );
2457 Reference
< XControl
>* pControls
= _rControls
.getArray();
2458 Reference
< XControlModel
> xModel
;
2459 for ( sal_Int32 i
= 0, nCount
= _rControls
.getLength(); i
< nCount
; ++i
, ++pControls
)
2461 if ( pControls
->is() )
2463 xModel
= (*pControls
)->getModel();
2464 if ( xModel
.get() == xCtrlModel
.get() )
2466 Reference
< XControl
> xControl( *pControls
);
2468 ::comphelper::removeElementAt( _rControls
, i
);
2469 else if ( _bOverWrite
)
2470 *pControls
= Reference
< XControl
>();
2475 return Reference
< XControl
> ();
2478 //------------------------------------------------------------------------------
2479 void FormController::implControlInserted( const Reference
< XControl
>& _rxControl
, bool _bAddToEventAttacher
)
2481 Reference
< XWindow
> xWindow( _rxControl
, UNO_QUERY
);
2484 xWindow
->addFocusListener( this );
2485 xWindow
->addMouseListener( this );
2487 if ( _bAddToEventAttacher
)
2488 addToEventAttacher( _rxControl
);
2491 // add a dispatch interceptor to the control (if supported)
2492 Reference
< XDispatchProviderInterception
> xInterception( _rxControl
, UNO_QUERY
);
2493 if ( xInterception
.is() )
2494 createInterceptor( xInterception
);
2496 if ( _rxControl
.is() )
2498 Reference
< XControlModel
> xModel( _rxControl
->getModel() );
2500 // we want to know about the reset of the the model of our controls
2501 // (for correctly resetting m_bModified)
2502 Reference
< XReset
> xReset( xModel
, UNO_QUERY
);
2504 xReset
->addResetListener( this );
2506 // and we want to know about the validity, to visually indicate it
2507 Reference
< XValidatableFormComponent
> xValidatable( xModel
, UNO_QUERY
);
2508 if ( xValidatable
.is() )
2510 xValidatable
->addFormComponentValidityListener( this );
2511 m_pControlBorderManager
->validityChanged( _rxControl
, xValidatable
);
2517 //------------------------------------------------------------------------------
2518 void FormController::implControlRemoved( const Reference
< XControl
>& _rxControl
, bool _bRemoveFromEventAttacher
)
2520 Reference
< XWindow
> xWindow( _rxControl
, UNO_QUERY
);
2523 xWindow
->removeFocusListener( this );
2524 xWindow
->removeMouseListener( this );
2526 if ( _bRemoveFromEventAttacher
)
2527 removeFromEventAttacher( _rxControl
);
2530 Reference
< XDispatchProviderInterception
> xInterception( _rxControl
, UNO_QUERY
);
2531 if ( xInterception
.is() )
2532 deleteInterceptor( xInterception
);
2534 if ( _rxControl
.is() )
2536 Reference
< XControlModel
> xModel( _rxControl
->getModel() );
2538 Reference
< XReset
> xReset( xModel
, UNO_QUERY
);
2540 xReset
->removeResetListener( this );
2542 Reference
< XValidatableFormComponent
> xValidatable( xModel
, UNO_QUERY
);
2543 if ( xValidatable
.is() )
2544 xValidatable
->removeFormComponentValidityListener( this );
2548 //------------------------------------------------------------------------------
2549 void FormController::implSetCurrentControl( const Reference
< XControl
>& _rxControl
)
2551 if ( m_xCurrentControl
.get() == _rxControl
.get() )
2554 Reference
< XGridControl
> xGridControl( m_xCurrentControl
, UNO_QUERY
);
2555 if ( xGridControl
.is() )
2556 xGridControl
->removeGridControlListener( this );
2558 m_xCurrentControl
= _rxControl
;
2560 xGridControl
.set( m_xCurrentControl
, UNO_QUERY
);
2561 if ( xGridControl
.is() )
2562 xGridControl
->addGridControlListener( this );
2565 //------------------------------------------------------------------------------
2566 void FormController::insertControl(const Reference
< XControl
> & xControl
)
2568 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2569 m_bControlsSorted
= sal_False
;
2570 m_aControls
.realloc(m_aControls
.getLength() + 1);
2571 m_aControls
.getArray()[m_aControls
.getLength() - 1] = xControl
;
2573 if ( m_pColumnInfoCache
.get() )
2574 m_pColumnInfoCache
->deinitializeControls();
2576 implControlInserted( xControl
, m_bAttachEvents
);
2578 if (m_bDBConnection
&& !m_bFiltering
)
2579 setControlLock(xControl
);
2581 if (isListeningForChanges() && m_bAttachEvents
)
2582 startControlModifyListening( xControl
);
2585 //------------------------------------------------------------------------------
2586 void FormController::removeControl(const Reference
< XControl
> & xControl
)
2588 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2589 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2590 const Reference
< XControl
>* pControlsEnd
= pControls
+ m_aControls
.getLength();
2591 while ( pControls
!= pControlsEnd
)
2593 if ( xControl
.get() == (*pControls
++).get() )
2595 ::comphelper::removeElementAt( m_aControls
, pControls
- m_aControls
.getConstArray() - 1 );
2600 FilterComponents::iterator componentPos
= ::std::find( m_aFilterComponents
.begin(), m_aFilterComponents
.end(), xControl
);
2601 if ( componentPos
!= m_aFilterComponents
.end() )
2602 m_aFilterComponents
.erase( componentPos
);
2604 implControlRemoved( xControl
, m_bDetachEvents
);
2606 if ( isListeningForChanges() && m_bDetachEvents
)
2607 stopControlModifyListening( xControl
);
2611 //------------------------------------------------------------------------------
2612 void FormController::loaded(const EventObject
& rEvent
) throw( RuntimeException
)
2614 OSL_ENSURE( rEvent
.Source
== m_xModelAsIndex
, "FormController::loaded: where did this come from?" );
2616 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2617 ::osl::MutexGuard
aGuard( m_aMutex
);
2618 Reference
< XRowSet
> xForm(rEvent
.Source
, UNO_QUERY
);
2619 // do we have a connected data source
2620 OStaticDataAccessTools aStaticTools
;
2621 if (xForm
.is() && aStaticTools
.getRowSetConnection(xForm
).is())
2623 Reference
< XPropertySet
> xSet(xForm
, UNO_QUERY
);
2626 Any aVal
= xSet
->getPropertyValue(FM_PROP_CYCLE
);
2627 sal_Int32 aVal2
= 0;
2628 ::cppu::enum2int(aVal2
,aVal
);
2629 m_bCycle
= !aVal
.hasValue() || aVal2
== TabulatorCycle_RECORDS
;
2630 m_bCanUpdate
= aStaticTools
.canUpdate(xSet
);
2631 m_bCanInsert
= aStaticTools
.canInsert(xSet
);
2632 m_bCurrentRecordModified
= ::comphelper::getBOOL(xSet
->getPropertyValue(FM_PROP_ISMODIFIED
));
2633 m_bCurrentRecordNew
= ::comphelper::getBOOL(xSet
->getPropertyValue(FM_PROP_ISNEW
));
2635 startFormListening( xSet
, sal_False
);
2637 // set the locks for the current controls
2638 if (getContainer().is())
2640 m_aLoadEvent
.Call();
2645 m_bCanInsert
= m_bCanUpdate
= m_bCycle
= sal_False
;
2646 m_bCurrentRecordModified
= sal_False
;
2647 m_bCurrentRecordNew
= sal_False
;
2648 m_bLocked
= sal_False
;
2650 m_bDBConnection
= sal_True
;
2654 m_bDBConnection
= sal_False
;
2655 m_bCanInsert
= m_bCanUpdate
= m_bCycle
= sal_False
;
2656 m_bCurrentRecordModified
= sal_False
;
2657 m_bCurrentRecordNew
= sal_False
;
2658 m_bLocked
= sal_False
;
2661 Reference
< XColumnsSupplier
> xFormColumns( xForm
, UNO_QUERY
);
2662 m_pColumnInfoCache
.reset( xFormColumns
.is() ? new ColumnInfoCache( xFormColumns
) : NULL
);
2664 updateAllDispatchers();
2667 //------------------------------------------------------------------------------
2668 void FormController::updateAllDispatchers() const
2671 m_aFeatureDispatchers
.begin(),
2672 m_aFeatureDispatchers
.end(),
2674 UpdateAllListeners(),
2675 ::o3tl::select2nd
< DispatcherContainer::value_type
>()
2680 //------------------------------------------------------------------------------
2681 IMPL_LINK_NOARG(FormController
, OnLoad
)
2683 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2684 m_bLocked
= determineLockState();
2691 // just one exception toggle the auto values
2692 if (m_bCurrentRecordNew
)
2693 toggleAutoFields(sal_True
);
2698 //------------------------------------------------------------------------------
2699 void FormController::unloaded(const EventObject
& /*rEvent*/) throw( RuntimeException
)
2701 ::osl::MutexGuard
aGuard( m_aMutex
);
2702 impl_checkDisposed_throw();
2704 updateAllDispatchers();
2707 //------------------------------------------------------------------------------
2708 void FormController::reloading(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2710 ::osl::MutexGuard
aGuard( m_aMutex
);
2711 impl_checkDisposed_throw();
2713 // do the same like in unloading
2714 // just one exception toggle the auto values
2715 m_aToggleEvent
.CancelPendingCall();
2719 //------------------------------------------------------------------------------
2720 void FormController::reloaded(const EventObject
& aEvent
) throw( RuntimeException
)
2722 ::osl::MutexGuard
aGuard( m_aMutex
);
2723 impl_checkDisposed_throw();
2728 //------------------------------------------------------------------------------
2729 void FormController::unloading(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2731 ::osl::MutexGuard
aGuard( m_aMutex
);
2732 impl_checkDisposed_throw();
2737 //------------------------------------------------------------------------------
2738 void FormController::unload() throw( RuntimeException
)
2740 ::osl::MutexGuard
aGuard( m_aMutex
);
2741 impl_checkDisposed_throw();
2743 m_aLoadEvent
.CancelPendingCall();
2745 // be sure not to have autofields
2746 if (m_bCurrentRecordNew
)
2747 toggleAutoFields(sal_False
);
2749 // remove bound field listing again
2750 removeBoundFieldListener();
2752 if (m_bDBConnection
&& isListeningForChanges())
2755 Reference
< XPropertySet
> xSet( m_xModelAsIndex
, UNO_QUERY
);
2756 if ( m_bDBConnection
&& xSet
.is() )
2757 stopFormListening( xSet
, sal_False
);
2759 m_bDBConnection
= sal_False
;
2760 m_bCanInsert
= m_bCanUpdate
= m_bCycle
= sal_False
;
2761 m_bCurrentRecordModified
= m_bCurrentRecordNew
= m_bLocked
= sal_False
;
2763 m_pColumnInfoCache
.reset( NULL
);
2766 // -----------------------------------------------------------------------------
2767 void FormController::removeBoundFieldListener()
2769 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2770 const Reference
< XControl
>* pControlsEnd
= pControls
+ m_aControls
.getLength();
2771 while ( pControls
!= pControlsEnd
)
2773 Reference
< XPropertySet
> xProp( *pControls
++, UNO_QUERY
);
2775 xProp
->removePropertyChangeListener( FM_PROP_BOUNDFIELD
, this );
2779 //------------------------------------------------------------------------------
2780 void FormController::startFormListening( const Reference
< XPropertySet
>& _rxForm
, sal_Bool _bPropertiesOnly
)
2784 if ( m_bCanInsert
|| m_bCanUpdate
) // form can be modified
2786 _rxForm
->addPropertyChangeListener( FM_PROP_ISNEW
, this );
2787 _rxForm
->addPropertyChangeListener( FM_PROP_ISMODIFIED
, this );
2789 if ( !_bPropertiesOnly
)
2791 // set the Listener for UI interaction
2792 Reference
< XRowSetApproveBroadcaster
> xApprove( _rxForm
, UNO_QUERY
);
2793 if ( xApprove
.is() )
2794 xApprove
->addRowSetApproveListener( this );
2796 // listener for row set changes
2797 Reference
< XRowSet
> xRowSet( _rxForm
, UNO_QUERY
);
2799 xRowSet
->addRowSetListener( this );
2803 Reference
< XPropertySetInfo
> xInfo
= _rxForm
->getPropertySetInfo();
2804 if ( xInfo
.is() && xInfo
->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER
) )
2805 _rxForm
->addPropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER
, this );
2807 catch( const Exception
& )
2809 DBG_UNHANDLED_EXCEPTION();
2813 //------------------------------------------------------------------------------
2814 void FormController::stopFormListening( const Reference
< XPropertySet
>& _rxForm
, sal_Bool _bPropertiesOnly
)
2818 if ( m_bCanInsert
|| m_bCanUpdate
)
2820 _rxForm
->removePropertyChangeListener( FM_PROP_ISNEW
, this );
2821 _rxForm
->removePropertyChangeListener( FM_PROP_ISMODIFIED
, this );
2823 if ( !_bPropertiesOnly
)
2825 Reference
< XRowSetApproveBroadcaster
> xApprove( _rxForm
, UNO_QUERY
);
2827 xApprove
->removeRowSetApproveListener(this);
2829 Reference
< XRowSet
> xRowSet( _rxForm
, UNO_QUERY
);
2831 xRowSet
->removeRowSetListener( this );
2835 Reference
< XPropertySetInfo
> xInfo
= _rxForm
->getPropertySetInfo();
2836 if ( xInfo
.is() && xInfo
->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER
) )
2837 _rxForm
->removePropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER
, this );
2839 catch( const Exception
& )
2841 DBG_UNHANDLED_EXCEPTION();
2845 // com::sun::star::sdbc::XRowSetListener
2846 //------------------------------------------------------------------------------
2847 void FormController::cursorMoved(const EventObject
& /*event*/) throw( RuntimeException
)
2849 ::osl::MutexGuard
aGuard( m_aMutex
);
2850 impl_checkDisposed_throw();
2852 // toggle the locking ?
2853 if (m_bLocked
!= determineLockState())
2855 m_bLocked
= !m_bLocked
;
2857 if (isListeningForChanges())
2863 // neither the current control nor the current record are modified anymore
2864 m_bCurrentRecordModified
= m_bModified
= sal_False
;
2867 //------------------------------------------------------------------------------
2868 void FormController::rowChanged(const EventObject
& /*event*/) throw( RuntimeException
)
2870 // not interested in ...
2872 //------------------------------------------------------------------------------
2873 void FormController::rowSetChanged(const EventObject
& /*event*/) throw( RuntimeException
)
2875 // not interested in ...
2879 // XContainerListener
2880 //------------------------------------------------------------------------------
2881 void SAL_CALL
FormController::elementInserted(const ContainerEvent
& evt
) throw( RuntimeException
)
2883 ::osl::MutexGuard
aGuard( m_aMutex
);
2884 impl_checkDisposed_throw();
2886 Reference
< XControl
> xControl( evt
.Element
, UNO_QUERY
);
2887 if ( !xControl
.is() )
2890 Reference
< XFormComponent
> xModel(xControl
->getModel(), UNO_QUERY
);
2891 if (xModel
.is() && m_xModelAsIndex
== xModel
->getParent())
2893 insertControl(xControl
);
2895 if ( m_aTabActivationTimer
.IsActive() )
2896 m_aTabActivationTimer
.Stop();
2898 m_aTabActivationTimer
.Start();
2900 // are we in filtermode and a XModeSelector has inserted an element
2901 else if (m_bFiltering
&& Reference
< XModeSelector
> (evt
.Source
, UNO_QUERY
).is())
2903 xModel
= Reference
< XFormComponent
> (evt
.Source
, UNO_QUERY
);
2904 if (xModel
.is() && m_xModelAsIndex
== xModel
->getParent())
2906 Reference
< XPropertySet
> xSet(xControl
->getModel(), UNO_QUERY
);
2907 if (xSet
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
2909 // does the model use a bound field ?
2910 Reference
< XPropertySet
> xField
;
2911 xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
2913 Reference
< XTextComponent
> xText(xControl
, UNO_QUERY
);
2914 // may we filter the field?
2915 if (xText
.is() && xField
.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE
, xField
) &&
2916 ::comphelper::getBOOL(xField
->getPropertyValue(FM_PROP_SEARCHABLE
)))
2918 m_aFilterComponents
.push_back( xText
);
2919 xText
->addTextListener( this );
2926 //------------------------------------------------------------------------------
2927 void SAL_CALL
FormController::elementReplaced(const ContainerEvent
& evt
) throw( RuntimeException
)
2929 // simulate an elementRemoved
2930 ContainerEvent
aRemoveEvent( evt
);
2931 aRemoveEvent
.Element
= evt
.ReplacedElement
;
2932 aRemoveEvent
.ReplacedElement
= Any();
2933 elementRemoved( aRemoveEvent
);
2935 // simulate an elementInserted
2936 ContainerEvent
aInsertEvent( evt
);
2937 aInsertEvent
.ReplacedElement
= Any();
2938 elementInserted( aInsertEvent
);
2941 //------------------------------------------------------------------------------
2942 void SAL_CALL
FormController::elementRemoved(const ContainerEvent
& evt
) throw( RuntimeException
)
2944 ::osl::MutexGuard
aGuard( m_aMutex
);
2945 impl_checkDisposed_throw();
2947 Reference
< XControl
> xControl
;
2948 evt
.Element
>>= xControl
;
2952 Reference
< XFormComponent
> xModel(xControl
->getModel(), UNO_QUERY
);
2953 if (xModel
.is() && m_xModelAsIndex
== xModel
->getParent())
2955 removeControl(xControl
);
2956 // TabOrder nicht neu berechnen, da das intern schon funktionieren mu�!
2958 // are we in filtermode and a XModeSelector has inserted an element
2959 else if (m_bFiltering
&& Reference
< XModeSelector
> (evt
.Source
, UNO_QUERY
).is())
2961 FilterComponents::iterator componentPos
= ::std::find(
2962 m_aFilterComponents
.begin(), m_aFilterComponents
.end(), xControl
);
2963 if ( componentPos
!= m_aFilterComponents
.end() )
2964 m_aFilterComponents
.erase( componentPos
);
2968 //------------------------------------------------------------------------------
2969 Reference
< XControl
> FormController::isInList(const Reference
< XWindowPeer
> & xPeer
) const
2971 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
2972 const Reference
< XControl
>* pControls
= m_aControls
.getConstArray();
2974 sal_uInt32 nCtrls
= m_aControls
.getLength();
2975 for ( sal_uInt32 n
= 0; n
< nCtrls
&& xPeer
.is(); ++n
, ++pControls
)
2977 if ( pControls
->is() )
2979 Reference
< XVclWindowPeer
> xCtrlPeer( (*pControls
)->getPeer(), UNO_QUERY
);
2980 if ( ( xCtrlPeer
.get() == xPeer
.get() ) || xCtrlPeer
->isChild( xPeer
) )
2984 return Reference
< XControl
> ();
2987 //------------------------------------------------------------------------------
2988 void FormController::activateFirst() throw( RuntimeException
)
2990 ::osl::MutexGuard
aGuard( m_aMutex
);
2991 impl_checkDisposed_throw();
2993 DBG_ASSERT(m_xTabController
.is(), "FormController::activateFirst : invalid aggregate !");
2994 if (m_xTabController
.is())
2995 m_xTabController
->activateFirst();
2998 //------------------------------------------------------------------------------
2999 void FormController::activateLast() throw( RuntimeException
)
3001 ::osl::MutexGuard
aGuard( m_aMutex
);
3002 impl_checkDisposed_throw();
3004 DBG_ASSERT(m_xTabController
.is(), "FormController::activateLast : invalid aggregate !");
3005 if (m_xTabController
.is())
3006 m_xTabController
->activateLast();
3010 //------------------------------------------------------------------------------
3011 Reference
< XFormOperations
> SAL_CALL
FormController::getFormOperations() throw (RuntimeException
)
3013 ::osl::MutexGuard
aGuard( m_aMutex
);
3014 impl_checkDisposed_throw();
3016 return m_xFormOperations
;
3019 //------------------------------------------------------------------------------
3020 Reference
< XControl
> SAL_CALL
FormController::getCurrentControl(void) throw( RuntimeException
)
3022 ::osl::MutexGuard
aGuard( m_aMutex
);
3023 impl_checkDisposed_throw();
3024 return m_xCurrentControl
;
3027 //------------------------------------------------------------------------------
3028 void SAL_CALL
FormController::addActivateListener(const Reference
< XFormControllerListener
> & l
) throw( RuntimeException
)
3030 ::osl::MutexGuard
aGuard( m_aMutex
);
3031 impl_checkDisposed_throw();
3032 m_aActivateListeners
.addInterface(l
);
3034 //------------------------------------------------------------------------------
3035 void SAL_CALL
FormController::removeActivateListener(const Reference
< XFormControllerListener
> & l
) throw( RuntimeException
)
3037 ::osl::MutexGuard
aGuard( m_aMutex
);
3038 impl_checkDisposed_throw();
3039 m_aActivateListeners
.removeInterface(l
);
3042 //------------------------------------------------------------------------------
3043 void SAL_CALL
FormController::addChildController( const Reference
< XFormController
>& _ChildController
) throw( RuntimeException
, IllegalArgumentException
)
3045 ::osl::MutexGuard
aGuard( m_aMutex
);
3046 impl_checkDisposed_throw();
3048 if ( !_ChildController
.is() )
3049 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
3050 // TODO: (localized) error message
3052 // the parent of our (to-be-)child must be our own model
3053 Reference
< XFormComponent
> xFormOfChild( _ChildController
->getModel(), UNO_QUERY
);
3054 if ( !xFormOfChild
.is() )
3055 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
3056 // TODO: (localized) error message
3058 if ( xFormOfChild
->getParent() != m_xModelAsIndex
)
3059 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
3060 // TODO: (localized) error message
3062 m_aChildren
.push_back( _ChildController
);
3063 _ChildController
->setParent( *this );
3065 // search the position of the model within the form
3066 sal_uInt32 nPos
= m_xModelAsIndex
->getCount();
3067 Reference
< XFormComponent
> xTemp
;
3070 m_xModelAsIndex
->getByIndex(--nPos
) >>= xTemp
;
3071 if ( xFormOfChild
== xTemp
)
3073 Reference
< XInterface
> xIfc( _ChildController
, UNO_QUERY
);
3074 m_xModelAsManager
->attach( nPos
, xIfc
, makeAny( _ChildController
) );
3080 //------------------------------------------------------------------------------
3081 Reference
< XFormControllerContext
> SAL_CALL
FormController::getContext() throw (RuntimeException
)
3083 ::osl::MutexGuard
aGuard( m_aMutex
);
3084 impl_checkDisposed_throw();
3088 //------------------------------------------------------------------------------
3089 void SAL_CALL
FormController::setContext( const Reference
< XFormControllerContext
>& _context
) throw (RuntimeException
)
3091 ::osl::MutexGuard
aGuard( m_aMutex
);
3092 impl_checkDisposed_throw();
3093 m_xContext
= _context
;
3096 //------------------------------------------------------------------------------
3097 Reference
< XInteractionHandler
> SAL_CALL
FormController::getInteractionHandler() throw (RuntimeException
)
3099 ::osl::MutexGuard
aGuard( m_aMutex
);
3100 impl_checkDisposed_throw();
3101 return m_xInteractionHandler
;
3104 //------------------------------------------------------------------------------
3105 void SAL_CALL
FormController::setInteractionHandler( const Reference
< XInteractionHandler
>& _interactionHandler
) throw (RuntimeException
)
3107 ::osl::MutexGuard
aGuard( m_aMutex
);
3108 impl_checkDisposed_throw();
3109 m_xInteractionHandler
= _interactionHandler
;
3112 //------------------------------------------------------------------------------
3113 void FormController::setFilter(::std::vector
<FmFieldInfo
>& rFieldInfos
)
3115 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3116 // create the composer
3117 Reference
< XRowSet
> xForm(m_xModelAsIndex
, UNO_QUERY
);
3118 Reference
< XConnection
> xConnection(OStaticDataAccessTools().getRowSetConnection(xForm
));
3123 Reference
< XMultiServiceFactory
> xFactory( xConnection
, UNO_QUERY_THROW
);
3125 xFactory
->createInstance( ::rtl::OUString( "com.sun.star.sdb.SingleSelectQueryComposer" ) ),
3128 Reference
< XPropertySet
> xSet( xForm
, UNO_QUERY
);
3129 ::rtl::OUString sStatement
= ::comphelper::getString( xSet
->getPropertyValue( FM_PROP_ACTIVECOMMAND
) );
3130 ::rtl::OUString sFilter
= ::comphelper::getString( xSet
->getPropertyValue( FM_PROP_FILTER
) );
3131 m_xComposer
->setElementaryQuery( sStatement
);
3132 m_xComposer
->setFilter( sFilter
);
3134 catch( const Exception
& )
3136 DBG_UNHANDLED_EXCEPTION();
3140 if (m_xComposer
.is())
3142 Sequence
< PropertyValue
> aLevel
;
3143 Sequence
< Sequence
< PropertyValue
> > aFilterRows
= m_xComposer
->getStructuredFilter();
3145 // ok, we recieve the list of filters as sequence of fieldnames, value
3146 // now we have to transform the fieldname into UI names, that could be a label of the field or
3147 // a aliasname or the fieldname itself
3149 // first adjust the field names if necessary
3150 Reference
< XNameAccess
> xQueryColumns
=
3151 Reference
< XColumnsSupplier
>( m_xComposer
, UNO_QUERY_THROW
)->getColumns();
3153 for (::std::vector
<FmFieldInfo
>::iterator iter
= rFieldInfos
.begin();
3154 iter
!= rFieldInfos
.end(); ++iter
)
3156 if ( xQueryColumns
->hasByName((*iter
).aFieldName
) )
3158 if ( (xQueryColumns
->getByName((*iter
).aFieldName
) >>= (*iter
).xField
) && (*iter
).xField
.is() )
3159 (*iter
).xField
->getPropertyValue(FM_PROP_REALNAME
) >>= (*iter
).aFieldName
;
3163 Reference
< XDatabaseMetaData
> xMetaData(xConnection
->getMetaData());
3164 // now transfer the filters into Value/TextComponent pairs
3165 ::comphelper::UStringMixEqual
aCompare(xMetaData
->storesMixedCaseQuotedIdentifiers());
3167 // need to parse criteria localized
3168 OStaticDataAccessTools aStaticTools
;
3169 Reference
< XNumberFormatsSupplier
> xFormatSupplier( aStaticTools
.getNumberFormats(xConnection
, sal_True
));
3170 Reference
< XNumberFormatter
> xFormatter( m_aContext
.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY
);
3171 xFormatter
->attachNumberFormatsSupplier(xFormatSupplier
);
3172 Locale aAppLocale
= Application::GetSettings().GetUILocale();
3173 LocaleDataWrapper
aLocaleWrapper( m_aContext
.getLegacyServiceFactory(), aAppLocale
);
3175 // retrieving the filter
3176 const Sequence
< PropertyValue
>* pRow
= aFilterRows
.getConstArray();
3177 for (sal_Int32 i
= 0, nLen
= aFilterRows
.getLength(); i
< nLen
; ++i
)
3181 // search a field for the given name
3182 const PropertyValue
* pRefValues
= pRow
[i
].getConstArray();
3183 for (sal_Int32 j
= 0, nLen1
= pRow
[i
].getLength(); j
< nLen1
; j
++)
3185 // look for the text component
3186 Reference
< XPropertySet
> xField
;
3189 Reference
< XPropertySet
> xSet
;
3190 ::rtl::OUString aRealName
;
3192 // first look with the given name
3193 if (xQueryColumns
->hasByName(pRefValues
[j
].Name
))
3195 xQueryColumns
->getByName(pRefValues
[j
].Name
) >>= xSet
;
3198 xSet
->getPropertyValue(::rtl::OUString("RealName")) >>= aRealName
;
3200 // compare the condition field name and the RealName
3201 if (aCompare(aRealName
, pRefValues
[j
].Name
))
3206 // no we have to check every column to find the realname
3207 Reference
< XIndexAccess
> xColumnsByIndex(xQueryColumns
, UNO_QUERY
);
3208 for (sal_Int32 n
= 0, nCount
= xColumnsByIndex
->getCount(); n
< nCount
; n
++)
3210 xColumnsByIndex
->getByIndex(n
) >>= xSet
;
3211 xSet
->getPropertyValue(::rtl::OUString("RealName")) >>= aRealName
;
3212 if (aCompare(aRealName
, pRefValues
[j
].Name
))
3214 // get the column by its alias
3223 catch (const Exception
&)
3228 // find the text component
3229 for (::std::vector
<FmFieldInfo
>::iterator iter
= rFieldInfos
.begin();
3230 iter
!= rFieldInfos
.end(); ++iter
)
3232 // we found the field so insert a new entry to the filter row
3233 if ((*iter
).xField
== xField
)
3235 // do we already have the control ?
3236 if (aRow
.find((*iter
).xText
) != aRow
.end())
3238 ::rtl::OUString aCompText
= aRow
[(*iter
).xText
];
3239 aCompText
+= ::rtl::OUString(" ");
3240 ::rtl::OString aVal
= m_xParser
->getContext().getIntlKeywordAscii(OParseContext::KEY_AND
);
3241 aCompText
+= ::rtl::OUString(aVal
.getStr(),aVal
.getLength(),RTL_TEXTENCODING_ASCII_US
);
3242 aCompText
+= ::rtl::OUString(" ");
3243 aCompText
+= ::comphelper::getString(pRefValues
[j
].Value
);
3244 aRow
[(*iter
).xText
] = aCompText
;
3248 ::rtl::OUString sPredicate
,sErrorMsg
;
3249 pRefValues
[j
].Value
>>= sPredicate
;
3250 ::rtl::Reference
< ISQLParseNode
> xParseNode
= predicateTree(sErrorMsg
, sPredicate
, xFormatter
, xField
);
3251 if ( xParseNode
.is() )
3253 ::rtl::OUString sCriteria
;
3254 xParseNode
->parseNodeToPredicateStr( sCriteria
3259 ,(sal_Char
)aLocaleWrapper
.getNumDecimalSep().GetChar(0)
3260 ,getParseContext());
3261 aRow
[(*iter
).xText
] = sCriteria
;
3271 impl_addFilterRow( aRow
);
3275 // now set the filter controls
3276 for ( ::std::vector
<FmFieldInfo
>::iterator field
= rFieldInfos
.begin();
3277 field
!= rFieldInfos
.end();
3281 m_aFilterComponents
.push_back( field
->xText
);
3285 //------------------------------------------------------------------------------
3286 void FormController::startFiltering()
3288 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3290 OStaticDataAccessTools aStaticTools
;
3291 Reference
< XConnection
> xConnection( aStaticTools
.getRowSetConnection( Reference
< XRowSet
>( m_xModelAsIndex
, UNO_QUERY
) ) );
3292 if ( !xConnection
.is() )
3293 // nothing to do - can't filter a form which is not connected
3296 // stop listening for controls
3297 if (isListeningForChanges())
3300 m_bFiltering
= sal_True
;
3302 // as we don't want new controls to be attached to the scripting environment
3303 // we change attach flags
3304 m_bAttachEvents
= sal_False
;
3306 // Austauschen der Kontrols fuer das aktuelle Formular
3307 Sequence
< Reference
< XControl
> > aControlsCopy( m_aControls
);
3308 const Reference
< XControl
>* pControls
= aControlsCopy
.getConstArray();
3309 sal_Int32 nControlCount
= aControlsCopy
.getLength();
3311 // the control we have to activate after replacement
3312 Reference
< XDatabaseMetaData
> xMetaData(xConnection
->getMetaData());
3313 Reference
< XNumberFormatsSupplier
> xFormatSupplier
= aStaticTools
.getNumberFormats(xConnection
, sal_True
);
3314 Reference
< XNumberFormatter
> xFormatter( m_aContext
.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY
);
3315 xFormatter
->attachNumberFormatsSupplier(xFormatSupplier
);
3317 // structure for storing the field info
3318 ::std::vector
<FmFieldInfo
> aFieldInfos
;
3320 for (sal_Int32 i
= nControlCount
; i
> 0;)
3322 Reference
< XControl
> xControl
= pControls
[--i
];
3325 // no events for the control anymore
3326 removeFromEventAttacher(xControl
);
3328 // do we have a mode selector
3329 Reference
< XModeSelector
> xSelector(xControl
, UNO_QUERY
);
3332 xSelector
->setMode( ::rtl::OUString( "FilterMode" ) );
3334 // listening for new controls of the selector
3335 Reference
< XContainer
> xContainer(xSelector
, UNO_QUERY
);
3336 if (xContainer
.is())
3337 xContainer
->addContainerListener(this);
3339 Reference
< XEnumerationAccess
> xElementAccess(xSelector
, UNO_QUERY
);
3340 if (xElementAccess
.is())
3342 Reference
< XEnumeration
> xEnumeration(xElementAccess
->createEnumeration());
3343 Reference
< XControl
> xSubControl
;
3344 while (xEnumeration
->hasMoreElements())
3346 xEnumeration
->nextElement() >>= xSubControl
;
3347 if (xSubControl
.is())
3349 Reference
< XPropertySet
> xSet(xSubControl
->getModel(), UNO_QUERY
);
3350 if (xSet
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
3352 // does the model use a bound field ?
3353 Reference
< XPropertySet
> xField
;
3354 xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
3356 Reference
< XTextComponent
> xText(xSubControl
, UNO_QUERY
);
3357 // may we filter the field?
3358 if (xText
.is() && xField
.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE
, xField
) &&
3359 ::comphelper::getBOOL(xField
->getPropertyValue(FM_PROP_SEARCHABLE
)))
3361 aFieldInfos
.push_back(FmFieldInfo(xField
, xText
));
3362 xText
->addTextListener(this);
3371 Reference
< XPropertySet
> xModel( xControl
->getModel(), UNO_QUERY
);
3372 if (xModel
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xModel
))
3374 // does the model use a bound field ?
3375 Any aVal
= xModel
->getPropertyValue(FM_PROP_BOUNDFIELD
);
3376 Reference
< XPropertySet
> xField
;
3379 // may we filter the field?
3382 && ::comphelper::hasProperty( FM_PROP_SEARCHABLE
, xField
)
3383 && ::comphelper::getBOOL( xField
->getPropertyValue( FM_PROP_SEARCHABLE
) )
3386 // create a filter control
3387 Sequence
< Any
> aCreationArgs( 3 );
3388 aCreationArgs
[ 0 ] <<= NamedValue( ::rtl::OUString("MessageParent"), makeAny( VCLUnoHelper::GetInterface( getDialogParentWindow() ) ) );
3389 aCreationArgs
[ 1 ] <<= NamedValue( ::rtl::OUString("NumberFormatter"), makeAny( xFormatter
) );
3390 aCreationArgs
[ 2 ] <<= NamedValue( ::rtl::OUString("ControlModel"), makeAny( xModel
) );
3391 Reference
< XControl
> xFilterControl(
3392 m_aContext
.createComponentWithArguments( "com.sun.star.form.control.FilterControl", aCreationArgs
),
3395 DBG_ASSERT( xFilterControl
.is(), "FormController::startFiltering: could not create a filter control!" );
3397 if ( replaceControl( xControl
, xFilterControl
) )
3399 Reference
< XTextComponent
> xFilterText( xFilterControl
, UNO_QUERY
);
3400 aFieldInfos
.push_back( FmFieldInfo( xField
, xFilterText
) );
3401 xFilterText
->addTextListener(this);
3407 // abmelden vom EventManager
3412 // we have all filter controls now, so the next step is to read the filters from the form
3413 // resolve all aliases and set the current filter to the according structure
3414 setFilter(aFieldInfos
);
3416 Reference
< XPropertySet
> xSet( m_xModelAsIndex
, UNO_QUERY
);
3418 stopFormListening( xSet
, sal_True
);
3420 impl_setTextOnAllFilter_throw();
3422 // lock all controls which are not used for filtering
3423 m_bLocked
= determineLockState();
3425 m_bAttachEvents
= sal_True
;
3428 //------------------------------------------------------------------------------
3429 void FormController::stopFiltering()
3431 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3432 if ( !m_bFiltering
) // #104693# OJ
3437 m_bFiltering
= sal_False
;
3438 m_bDetachEvents
= sal_False
;
3440 ::comphelper::disposeComponent(m_xComposer
);
3442 // Austauschen der Kontrols fuer das aktuelle Formular
3443 Sequence
< Reference
< XControl
> > aControlsCopy( m_aControls
);
3444 const Reference
< XControl
> * pControls
= aControlsCopy
.getConstArray();
3445 sal_Int32 nControlCount
= aControlsCopy
.getLength();
3447 // clear the filter control map
3448 ::std::for_each( m_aFilterComponents
.begin(), m_aFilterComponents
.end(), RemoveComponentTextListener( this ) );
3449 m_aFilterComponents
.clear();
3451 for ( sal_Int32 i
= nControlCount
; i
> 0; )
3453 Reference
< XControl
> xControl
= pControls
[--i
];
3456 // now enable eventhandling again
3457 addToEventAttacher(xControl
);
3459 Reference
< XModeSelector
> xSelector(xControl
, UNO_QUERY
);
3462 xSelector
->setMode( ::rtl::OUString( "DataMode" ) );
3464 // listening for new controls of the selector
3465 Reference
< XContainer
> xContainer(xSelector
, UNO_QUERY
);
3466 if (xContainer
.is())
3467 xContainer
->removeContainerListener(this);
3471 Reference
< XPropertySet
> xSet(xControl
->getModel(), UNO_QUERY
);
3472 if (xSet
.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
3474 // does the model use a bound field ?
3475 Reference
< XPropertySet
> xField
;
3476 xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
3478 // may we filter the field?
3480 && ::comphelper::hasProperty( FM_PROP_SEARCHABLE
, xField
)
3481 && ::comphelper::getBOOL( xField
->getPropertyValue( FM_PROP_SEARCHABLE
) )
3484 ::rtl::OUString sServiceName
;
3485 OSL_VERIFY( xSet
->getPropertyValue( FM_PROP_DEFAULTCONTROL
) >>= sServiceName
);
3486 Reference
< XControl
> xNewControl( m_aContext
.createComponent( sServiceName
), UNO_QUERY
);
3487 replaceControl( xControl
, xNewControl
);
3493 Reference
< XPropertySet
> xSet( m_xModelAsIndex
, UNO_QUERY
);
3495 startFormListening( xSet
, sal_True
);
3497 m_bDetachEvents
= sal_True
;
3499 m_aFilterRows
.clear();
3500 m_nCurrentFilterPosition
= -1;
3502 // release the locks if possible
3503 // lock all controls which are not used for filtering
3504 m_bLocked
= determineLockState();
3507 // restart listening for control modifications
3508 if (isListeningForChanges())
3513 //------------------------------------------------------------------------------
3514 void FormController::setMode(const ::rtl::OUString
& Mode
) throw( NoSupportException
, RuntimeException
)
3516 ::osl::MutexGuard
aGuard( m_aMutex
);
3517 impl_checkDisposed_throw();
3519 if (!supportsMode(Mode
))
3520 throw NoSupportException();
3522 if (Mode
== m_aMode
)
3527 if ( Mode
== "FilterMode" )
3532 for (FmFormControllers::const_iterator i
= m_aChildren
.begin();
3533 i
!= m_aChildren
.end(); ++i
)
3535 Reference
< XModeSelector
> xMode(*i
, UNO_QUERY
);
3537 xMode
->setMode(Mode
);
3541 //------------------------------------------------------------------------------
3542 ::rtl::OUString SAL_CALL
FormController::getMode(void) throw( RuntimeException
)
3544 ::osl::MutexGuard
aGuard( m_aMutex
);
3545 impl_checkDisposed_throw();
3550 //------------------------------------------------------------------------------
3551 Sequence
< ::rtl::OUString
> SAL_CALL
FormController::getSupportedModes(void) throw( RuntimeException
)
3553 ::osl::MutexGuard
aGuard( m_aMutex
);
3554 impl_checkDisposed_throw();
3556 static Sequence
< ::rtl::OUString
> aModes
;
3557 if (!aModes
.getLength())
3560 ::rtl::OUString
* pModes
= aModes
.getArray();
3561 pModes
[0] = ::rtl::OUString( "DataMode" );
3562 pModes
[1] = ::rtl::OUString( "FilterMode" );
3567 //------------------------------------------------------------------------------
3568 sal_Bool SAL_CALL
FormController::supportsMode(const ::rtl::OUString
& Mode
) throw( RuntimeException
)
3570 ::osl::MutexGuard
aGuard( m_aMutex
);
3571 impl_checkDisposed_throw();
3573 Sequence
< ::rtl::OUString
> aModes(getSupportedModes());
3574 const ::rtl::OUString
* pModes
= aModes
.getConstArray();
3575 for (sal_Int32 i
= aModes
.getLength(); i
> 0; )
3577 if (pModes
[--i
] == Mode
)
3583 //------------------------------------------------------------------------------
3584 Window
* FormController::getDialogParentWindow()
3586 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
3587 Window
* pParentWindow
= NULL
;
3590 Reference
< XControl
> xContainerControl( getContainer(), UNO_QUERY_THROW
);
3591 Reference
< XWindowPeer
> xContainerPeer( xContainerControl
->getPeer(), UNO_QUERY_THROW
);
3592 pParentWindow
= VCLUnoHelper::GetWindow( xContainerPeer
);
3594 catch( const Exception
& )
3596 DBG_UNHANDLED_EXCEPTION();
3598 return pParentWindow
;
3600 //------------------------------------------------------------------------------
3601 bool FormController::checkFormComponentValidity( ::rtl::OUString
& /* [out] */ _rFirstInvalidityExplanation
, Reference
< XControlModel
>& /* [out] */ _rxFirstInvalidModel
) SAL_THROW(())
3605 Reference
< XEnumerationAccess
> xControlEnumAcc( getModel(), UNO_QUERY
);
3606 Reference
< XEnumeration
> xControlEnumeration
;
3607 if ( xControlEnumAcc
.is() )
3608 xControlEnumeration
= xControlEnumAcc
->createEnumeration();
3609 OSL_ENSURE( xControlEnumeration
.is(), "FormController::checkFormComponentValidity: cannot enumerate the controls!" );
3610 if ( !xControlEnumeration
.is() )
3614 Reference
< XValidatableFormComponent
> xValidatable
;
3615 while ( xControlEnumeration
->hasMoreElements() )
3617 if ( !( xControlEnumeration
->nextElement() >>= xValidatable
) )
3618 // control does not support validation
3621 if ( xValidatable
->isValid() )
3624 Reference
< XValidator
> xValidator( xValidatable
->getValidator() );
3625 OSL_ENSURE( xValidator
.is(), "FormController::checkFormComponentValidity: invalid, but no validator?" );
3626 if ( !xValidator
.is() )
3627 // this violates the interface definition of css.form.validation.XValidatableFormComponent ...
3630 _rFirstInvalidityExplanation
= xValidator
->explainInvalid( xValidatable
->getCurrentValue() );
3631 _rxFirstInvalidModel
= _rxFirstInvalidModel
.query( xValidatable
);
3635 catch( const Exception
& )
3637 DBG_UNHANDLED_EXCEPTION();
3642 //------------------------------------------------------------------------------
3643 Reference
< XControl
> FormController::locateControl( const Reference
< XControlModel
>& _rxModel
) SAL_THROW(())
3647 Sequence
< Reference
< XControl
> > aControls( getControls() );
3648 const Reference
< XControl
>* pControls
= aControls
.getConstArray();
3649 const Reference
< XControl
>* pControlsEnd
= aControls
.getConstArray() + aControls
.getLength();
3651 for ( ; pControls
!= pControlsEnd
; ++pControls
)
3653 OSL_ENSURE( pControls
->is(), "FormController::locateControl: NULL-control?" );
3654 if ( pControls
->is() )
3656 if ( ( *pControls
)->getModel() == _rxModel
)
3660 OSL_FAIL( "FormController::locateControl: did not find a control for this model!" );
3662 catch( const Exception
& )
3664 DBG_UNHANDLED_EXCEPTION();
3669 //------------------------------------------------------------------------------
3672 void displayErrorSetFocus( const String
& _rMessage
, const Reference
< XControl
>& _rxFocusControl
, Window
* _pDialogParent
)
3675 aError
.Message
= String( SVX_RES( RID_STR_WRITEERROR
) );
3676 aError
.Details
= _rMessage
;
3677 displayException( aError
, _pDialogParent
);
3679 if ( _rxFocusControl
.is() )
3681 Reference
< XWindow
> xControlWindow( _rxFocusControl
, UNO_QUERY
);
3682 OSL_ENSURE( xControlWindow
.is(), "displayErrorSetFocus: invalid control!" );
3683 if ( xControlWindow
.is() )
3684 xControlWindow
->setFocus();
3688 sal_Bool
lcl_shouldValidateRequiredFields_nothrow( const Reference
< XInterface
>& _rxForm
)
3692 static ::rtl::OUString
s_sFormsCheckRequiredFields( "FormsCheckRequiredFields" );
3694 // first, check whether the form has a property telling us the answer
3695 // this allows people to use the XPropertyContainer interface of a form to control
3696 // the behaviour on a per-form basis.
3697 Reference
< XPropertySet
> xFormProps( _rxForm
, UNO_QUERY_THROW
);
3698 Reference
< XPropertySetInfo
> xPSI( xFormProps
->getPropertySetInfo() );
3699 if ( xPSI
->hasPropertyByName( s_sFormsCheckRequiredFields
) )
3701 sal_Bool bShouldValidate
= true;
3702 OSL_VERIFY( xFormProps
->getPropertyValue( s_sFormsCheckRequiredFields
) >>= bShouldValidate
);
3703 return bShouldValidate
;
3706 // next, check the data source which created the connection
3707 Reference
< XChild
> xConnectionAsChild( xFormProps
->getPropertyValue( FM_PROP_ACTIVE_CONNECTION
), UNO_QUERY_THROW
);
3708 Reference
< XPropertySet
> xDataSource( xConnectionAsChild
->getParent(), UNO_QUERY
);
3709 if ( !xDataSource
.is() )
3710 // seldom (but possible): this is not a connection created by a data source
3713 Reference
< XPropertySet
> xDataSourceSettings(
3714 xDataSource
->getPropertyValue( ::rtl::OUString( "Settings" ) ),
3717 sal_Bool bShouldValidate
= true;
3718 OSL_VERIFY( xDataSourceSettings
->getPropertyValue( s_sFormsCheckRequiredFields
) >>= bShouldValidate
);
3719 return bShouldValidate
;
3721 catch( const Exception
& )
3723 DBG_UNHANDLED_EXCEPTION();
3730 // XRowSetApproveListener
3731 //------------------------------------------------------------------------------
3732 sal_Bool SAL_CALL
FormController::approveRowChange(const RowChangeEvent
& _rEvent
) throw( RuntimeException
)
3734 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3735 impl_checkDisposed_throw();
3737 ::cppu::OInterfaceIteratorHelper
aIter(m_aRowSetApproveListeners
);
3738 sal_Bool bValid
= sal_True
;
3739 if (aIter
.hasMoreElements())
3741 RowChangeEvent
aEvt( _rEvent
);
3742 aEvt
.Source
= *this;
3743 bValid
= ((XRowSetApproveListener
*)aIter
.next())->approveRowChange(aEvt
);
3749 if ( ( _rEvent
.Action
!= RowChangeAction::INSERT
)
3750 && ( _rEvent
.Action
!= RowChangeAction::UPDATE
)
3754 // if some of the control models are bound to validators, check them
3755 ::rtl::OUString sInvalidityExplanation
;
3756 Reference
< XControlModel
> xInvalidModel
;
3757 if ( !checkFormComponentValidity( sInvalidityExplanation
, xInvalidModel
) )
3759 Reference
< XControl
> xControl( locateControl( xInvalidModel
) );
3761 displayErrorSetFocus( sInvalidityExplanation
, xControl
, getDialogParentWindow() );
3765 // check values on NULL and required flag
3766 if ( !lcl_shouldValidateRequiredFields_nothrow( _rEvent
.Source
) )
3769 OSL_ENSURE( m_pColumnInfoCache
.get(), "FormController::approveRowChange: no column infos!" );
3770 if ( !m_pColumnInfoCache
.get() )
3775 if ( !m_pColumnInfoCache
->controlsInitialized() )
3776 m_pColumnInfoCache
->initializeControls( getControls() );
3778 size_t colCount
= m_pColumnInfoCache
->getColumnCount();
3779 for ( size_t col
= 0; col
< colCount
; ++col
)
3781 const ColumnInfo
& rColInfo
= m_pColumnInfoCache
->getColumnInfo( col
);
3782 if ( rColInfo
.nNullable
!= ColumnValue::NO_NULLS
)
3785 if ( rColInfo
.bAutoIncrement
)
3788 if ( rColInfo
.bReadOnly
)
3791 if ( !rColInfo
.xFirstControlWithInputRequired
.is() && !rColInfo
.xFirstGridWithInputRequiredColumn
.is() )
3794 // TODO: in case of binary fields, this "getString" below is extremely expensive
3795 if ( !rColInfo
.xColumn
->getString().isEmpty() || !rColInfo
.xColumn
->wasNull() )
3798 String
sMessage( SVX_RES( RID_ERR_FIELDREQUIRED
) );
3799 sMessage
.SearchAndReplace( '#', rColInfo
.sName
);
3801 // the control to focus
3802 Reference
< XControl
> xControl( rColInfo
.xFirstControlWithInputRequired
);
3803 if ( !xControl
.is() )
3804 xControl
.set( rColInfo
.xFirstGridWithInputRequiredColumn
, UNO_QUERY
);
3807 displayErrorSetFocus( sMessage
, rColInfo
.xFirstControlWithInputRequired
, getDialogParentWindow() );
3811 catch( const Exception
& )
3813 DBG_UNHANDLED_EXCEPTION();
3819 //------------------------------------------------------------------------------
3820 sal_Bool SAL_CALL
FormController::approveCursorMove(const EventObject
& event
) throw( RuntimeException
)
3822 ::osl::MutexGuard
aGuard( m_aMutex
);
3823 impl_checkDisposed_throw();
3825 ::cppu::OInterfaceIteratorHelper
aIter(m_aRowSetApproveListeners
);
3826 if (aIter
.hasMoreElements())
3828 EventObject
aEvt(event
);
3829 aEvt
.Source
= *this;
3830 return ((XRowSetApproveListener
*)aIter
.next())->approveCursorMove(aEvt
);
3836 //------------------------------------------------------------------------------
3837 sal_Bool SAL_CALL
FormController::approveRowSetChange(const EventObject
& event
) throw( RuntimeException
)
3839 ::osl::MutexGuard
aGuard( m_aMutex
);
3840 impl_checkDisposed_throw();
3842 ::cppu::OInterfaceIteratorHelper
aIter(m_aRowSetApproveListeners
);
3843 if (aIter
.hasMoreElements())
3845 EventObject
aEvt(event
);
3846 aEvt
.Source
= *this;
3847 return ((XRowSetApproveListener
*)aIter
.next())->approveRowSetChange(aEvt
);
3853 // XRowSetApproveBroadcaster
3854 //------------------------------------------------------------------------------
3855 void SAL_CALL
FormController::addRowSetApproveListener(const Reference
< XRowSetApproveListener
> & _rxListener
) throw( RuntimeException
)
3857 ::osl::MutexGuard
aGuard( m_aMutex
);
3858 impl_checkDisposed_throw();
3860 m_aRowSetApproveListeners
.addInterface(_rxListener
);
3863 //------------------------------------------------------------------------------
3864 void SAL_CALL
FormController::removeRowSetApproveListener(const Reference
< XRowSetApproveListener
> & _rxListener
) throw( RuntimeException
)
3866 ::osl::MutexGuard
aGuard( m_aMutex
);
3867 impl_checkDisposed_throw();
3869 m_aRowSetApproveListeners
.removeInterface(_rxListener
);
3873 //------------------------------------------------------------------------------
3874 void SAL_CALL
FormController::errorOccured(const SQLErrorEvent
& aEvent
) throw( RuntimeException
)
3876 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3877 impl_checkDisposed_throw();
3879 ::cppu::OInterfaceIteratorHelper
aIter(m_aErrorListeners
);
3880 if (aIter
.hasMoreElements())
3882 SQLErrorEvent
aEvt(aEvent
);
3883 aEvt
.Source
= *this;
3884 ((XSQLErrorListener
*)aIter
.next())->errorOccured(aEvt
);
3889 displayException( aEvent
);
3893 // XErrorBroadcaster
3894 //------------------------------------------------------------------------------
3895 void SAL_CALL
FormController::addSQLErrorListener(const Reference
< XSQLErrorListener
> & aListener
) throw( RuntimeException
)
3897 ::osl::MutexGuard
aGuard( m_aMutex
);
3898 impl_checkDisposed_throw();
3900 m_aErrorListeners
.addInterface(aListener
);
3903 //------------------------------------------------------------------------------
3904 void SAL_CALL
FormController::removeSQLErrorListener(const Reference
< XSQLErrorListener
> & aListener
) throw( RuntimeException
)
3906 ::osl::MutexGuard
aGuard( m_aMutex
);
3907 impl_checkDisposed_throw();
3909 m_aErrorListeners
.removeInterface(aListener
);
3912 // XDatabaseParameterBroadcaster2
3913 //------------------------------------------------------------------------------
3914 void SAL_CALL
FormController::addDatabaseParameterListener(const Reference
< XDatabaseParameterListener
> & aListener
) throw( RuntimeException
)
3916 ::osl::MutexGuard
aGuard( m_aMutex
);
3917 impl_checkDisposed_throw();
3919 m_aParameterListeners
.addInterface(aListener
);
3922 //------------------------------------------------------------------------------
3923 void SAL_CALL
FormController::removeDatabaseParameterListener(const Reference
< XDatabaseParameterListener
> & aListener
) throw( RuntimeException
)
3925 ::osl::MutexGuard
aGuard( m_aMutex
);
3926 impl_checkDisposed_throw();
3928 m_aParameterListeners
.removeInterface(aListener
);
3931 // XDatabaseParameterBroadcaster
3932 //------------------------------------------------------------------------------
3933 void SAL_CALL
FormController::addParameterListener(const Reference
< XDatabaseParameterListener
> & aListener
) throw( RuntimeException
)
3935 FormController::addDatabaseParameterListener( aListener
);
3938 //------------------------------------------------------------------------------
3939 void SAL_CALL
FormController::removeParameterListener(const Reference
< XDatabaseParameterListener
> & aListener
) throw( RuntimeException
)
3941 FormController::removeDatabaseParameterListener( aListener
);
3944 // XDatabaseParameterListener
3945 //------------------------------------------------------------------------------
3946 sal_Bool SAL_CALL
FormController::approveParameter(const DatabaseParameterEvent
& aEvent
) throw( RuntimeException
)
3948 SolarMutexGuard aSolarGuard
;
3949 ::osl::MutexGuard
aGuard( m_aMutex
);
3950 impl_checkDisposed_throw();
3952 ::cppu::OInterfaceIteratorHelper
aIter(m_aParameterListeners
);
3953 if (aIter
.hasMoreElements())
3955 DatabaseParameterEvent
aEvt(aEvent
);
3956 aEvt
.Source
= *this;
3957 return ((XDatabaseParameterListener
*)aIter
.next())->approveParameter(aEvt
);
3961 // default handling: instantiate an interaction handler and let it handle the parameter request
3964 if ( !ensureInteractionHandler() )
3967 // two continuations allowed: OK and Cancel
3968 OParameterContinuation
* pParamValues
= new OParameterContinuation
;
3969 OInteractionAbort
* pAbort
= new OInteractionAbort
;
3971 ParametersRequest aRequest
;
3972 aRequest
.Parameters
= aEvent
.Parameters
;
3973 aRequest
.Connection
= OStaticDataAccessTools().getRowSetConnection(Reference
< XRowSet
>(aEvent
.Source
, UNO_QUERY
));
3974 OInteractionRequest
* pParamRequest
= new OInteractionRequest(makeAny(aRequest
));
3975 Reference
< XInteractionRequest
> xParamRequest(pParamRequest
);
3977 pParamRequest
->addContinuation(pParamValues
);
3978 pParamRequest
->addContinuation(pAbort
);
3980 // handle the request
3981 m_xInteractionHandler
->handle(xParamRequest
);
3983 if (!pParamValues
->wasSelected())
3987 // transfer the values into the parameter supplier
3988 Sequence
< PropertyValue
> aFinalValues
= pParamValues
->getValues();
3989 if (aFinalValues
.getLength() != aRequest
.Parameters
->getCount())
3991 OSL_FAIL("FormController::approveParameter: the InteractionHandler returned nonsense!");
3994 const PropertyValue
* pFinalValues
= aFinalValues
.getConstArray();
3995 for (sal_Int32 i
=0; i
<aFinalValues
.getLength(); ++i
, ++pFinalValues
)
3997 Reference
< XPropertySet
> xParam
;
3998 ::cppu::extractInterface(xParam
, aRequest
.Parameters
->getByIndex(i
));
4002 ::rtl::OUString sName
;
4003 xParam
->getPropertyValue(FM_PROP_NAME
) >>= sName
;
4004 DBG_ASSERT(sName
.equals(pFinalValues
->Name
), "FormController::approveParameter: suspicious value names!");
4006 try { xParam
->setPropertyValue(FM_PROP_VALUE
, pFinalValues
->Value
); }
4009 OSL_FAIL("FormController::approveParameter: setting one of the properties failed!");
4016 DBG_UNHANDLED_EXCEPTION();
4022 // XConfirmDeleteBroadcaster
4023 //------------------------------------------------------------------------------
4024 void SAL_CALL
FormController::addConfirmDeleteListener(const Reference
< XConfirmDeleteListener
> & aListener
) throw( RuntimeException
)
4026 ::osl::MutexGuard
aGuard( m_aMutex
);
4027 impl_checkDisposed_throw();
4029 m_aDeleteListeners
.addInterface(aListener
);
4032 //------------------------------------------------------------------------------
4033 void SAL_CALL
FormController::removeConfirmDeleteListener(const Reference
< XConfirmDeleteListener
> & aListener
) throw( RuntimeException
)
4035 ::osl::MutexGuard
aGuard( m_aMutex
);
4036 impl_checkDisposed_throw();
4038 m_aDeleteListeners
.removeInterface(aListener
);
4041 // XConfirmDeleteListener
4042 //------------------------------------------------------------------------------
4043 sal_Bool SAL_CALL
FormController::confirmDelete(const RowChangeEvent
& aEvent
) throw( RuntimeException
)
4045 ::osl::MutexGuard
aGuard( m_aMutex
);
4046 impl_checkDisposed_throw();
4048 ::cppu::OInterfaceIteratorHelper
aIter(m_aDeleteListeners
);
4049 if (aIter
.hasMoreElements())
4051 RowChangeEvent
aEvt(aEvent
);
4052 aEvt
.Source
= *this;
4053 return ((XConfirmDeleteListener
*)aIter
.next())->confirmDelete(aEvt
);
4055 // default handling: instantiate an interaction handler and let it handle the request
4058 sal_Int32 nLength
= aEvent
.Rows
;
4061 sTitle
= SVX_RESSTR( RID_STR_DELETECONFIRM_RECORDS
);
4062 sTitle
.SearchAndReplace( '#', String::CreateFromInt32( nLength
) );
4065 sTitle
= SVX_RESSTR( RID_STR_DELETECONFIRM_RECORD
);
4069 if ( !ensureInteractionHandler() )
4072 // two continuations allowed: Yes and No
4073 OInteractionApprove
* pApprove
= new OInteractionApprove
;
4074 OInteractionDisapprove
* pDisapprove
= new OInteractionDisapprove
;
4077 SQLWarning aWarning
;
4078 aWarning
.Message
= sTitle
;
4079 SQLWarning aDetails
;
4080 aDetails
.Message
= String( SVX_RES( RID_STR_DELETECONFIRM
) );
4081 aWarning
.NextException
<<= aDetails
;
4083 OInteractionRequest
* pRequest
= new OInteractionRequest( makeAny( aWarning
) );
4084 Reference
< XInteractionRequest
> xRequest( pRequest
);
4087 pRequest
->addContinuation( pApprove
);
4088 pRequest
->addContinuation( pDisapprove
);
4090 // handle the request
4091 m_xInteractionHandler
->handle( xRequest
);
4093 if ( pApprove
->wasSelected() )
4096 catch( const Exception
& )
4098 DBG_UNHANDLED_EXCEPTION();
4104 //------------------------------------------------------------------------------
4105 void SAL_CALL
FormController::invalidateFeatures( const Sequence
< ::sal_Int16
>& _Features
) throw (RuntimeException
)
4107 ::osl::MutexGuard
aGuard( m_aMutex
);
4108 // for now, just copy the ids of the features, because ....
4109 ::std::copy( _Features
.getConstArray(), _Features
.getConstArray() + _Features
.getLength(),
4110 ::std::insert_iterator
< ::std::set
< sal_Int16
> >( m_aInvalidFeatures
, m_aInvalidFeatures
.begin() )
4113 // ... we will do the real invalidation asynchronously
4114 if ( !m_aFeatureInvalidationTimer
.IsActive() )
4115 m_aFeatureInvalidationTimer
.Start();
4118 //------------------------------------------------------------------------------
4119 void SAL_CALL
FormController::invalidateAllFeatures( ) throw (RuntimeException
)
4121 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
4123 Sequence
< sal_Int16
> aInterceptedFeatures( m_aFeatureDispatchers
.size() );
4125 m_aFeatureDispatchers
.begin(),
4126 m_aFeatureDispatchers
.end(),
4127 aInterceptedFeatures
.getArray(),
4128 ::o3tl::select1st
< DispatcherContainer::value_type
>()
4132 if ( aInterceptedFeatures
.getLength() )
4133 invalidateFeatures( aInterceptedFeatures
);
4136 //------------------------------------------------------------------------------
4137 Reference
< XDispatch
>
4138 FormController::interceptedQueryDispatch( const URL
& aURL
,
4139 const ::rtl::OUString
& /*aTargetFrameName*/, sal_Int32
/*nSearchFlags*/)
4140 throw( RuntimeException
)
4142 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
4143 Reference
< XDispatch
> xReturn
;
4144 // dispatches handled by ourself
4145 if ( ( aURL
.Complete
== FMURL_CONFIRM_DELETION
)
4146 || ( ( aURL
.Complete
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:/InteractionHandler" ) ) )
4147 && ensureInteractionHandler()
4150 xReturn
= static_cast< XDispatch
* >( this );
4152 // dispatches of FormSlot-URLs we have to translate
4153 if ( !xReturn
.is() && m_xFormOperations
.is() )
4155 // find the slot id which corresponds to the URL
4156 sal_Int32 nFeatureSlotId
= ::svx::FeatureSlotTranslation::getControllerFeatureSlotIdForURL( aURL
.Main
);
4157 sal_Int16 nFormFeature
= ( nFeatureSlotId
!= -1 ) ? ::svx::FeatureSlotTranslation::getFormFeatureForSlotId( nFeatureSlotId
) : -1;
4158 if ( nFormFeature
> 0 )
4160 // get the dispatcher for this feature, create if necessary
4161 DispatcherContainer::const_iterator aDispatcherPos
= m_aFeatureDispatchers
.find( nFormFeature
);
4162 if ( aDispatcherPos
== m_aFeatureDispatchers
.end() )
4164 aDispatcherPos
= m_aFeatureDispatchers
.insert(
4165 DispatcherContainer::value_type( nFormFeature
, new ::svx::OSingleFeatureDispatcher( aURL
, nFormFeature
, m_xFormOperations
, m_aMutex
) )
4169 OSL_ENSURE( aDispatcherPos
->second
.is(), "FormController::interceptedQueryDispatch: should have a dispatcher by now!" );
4170 return aDispatcherPos
->second
;
4178 //------------------------------------------------------------------------------
4179 void SAL_CALL
FormController::dispatch( const URL
& _rURL
, const Sequence
< PropertyValue
>& _rArgs
) throw (RuntimeException
)
4181 if ( _rArgs
.getLength() != 1 )
4183 OSL_FAIL( "FormController::dispatch: no arguments -> no dispatch!" );
4187 if ( _rURL
.Complete
== "private:/InteractionHandler" )
4189 Reference
< XInteractionRequest
> xRequest
;
4190 OSL_VERIFY( _rArgs
[0].Value
>>= xRequest
);
4191 if ( xRequest
.is() )
4196 if ( _rURL
.Complete
== FMURL_CONFIRM_DELETION
)
4198 OSL_FAIL( "FormController::dispatch: How do you expect me to return something via this call?" );
4199 // confirmDelete has a return value - dispatch hasn't
4203 OSL_FAIL( "FormController::dispatch: unknown URL!" );
4206 //------------------------------------------------------------------------------
4207 void SAL_CALL
FormController::addStatusListener( const Reference
< XStatusListener
>& _rxListener
, const URL
& _rURL
) throw (RuntimeException
)
4209 if (_rURL
.Complete
== FMURL_CONFIRM_DELETION
)
4211 if (_rxListener
.is())
4212 { // send an initial statusChanged event
4213 FeatureStateEvent aEvent
;
4214 aEvent
.FeatureURL
= _rURL
;
4215 aEvent
.IsEnabled
= sal_True
;
4216 _rxListener
->statusChanged(aEvent
);
4217 // and don't add the listener at all (the status will never change)
4221 OSL_FAIL("FormController::addStatusListener: invalid (unsupported) URL!");
4224 //------------------------------------------------------------------------------
4225 Reference
< XInterface
> SAL_CALL
FormController::getParent() throw( RuntimeException
)
4230 //------------------------------------------------------------------------------
4231 void SAL_CALL
FormController::setParent( const Reference
< XInterface
>& Parent
) throw( NoSupportException
, RuntimeException
)
4236 //------------------------------------------------------------------------------
4237 void SAL_CALL
FormController::removeStatusListener( const Reference
< XStatusListener
>& /*_rxListener*/, const URL
& _rURL
) throw (RuntimeException
)
4240 OSL_ENSURE(_rURL
.Complete
== FMURL_CONFIRM_DELETION
, "FormController::removeStatusListener: invalid (unsupported) URL!");
4241 // we never really added the listener, so we don't need to remove it
4244 //------------------------------------------------------------------------------
4245 Reference
< XDispatchProviderInterceptor
> FormController::createInterceptor(const Reference
< XDispatchProviderInterception
> & _xInterception
)
4247 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
4249 // check if we already have a interceptor for the given object
4250 for ( ConstInterceptorsIterator aIter
= m_aControlDispatchInterceptors
.begin();
4251 aIter
!= m_aControlDispatchInterceptors
.end();
4255 if ((*aIter
)->getIntercepted() == _xInterception
)
4256 OSL_FAIL("FormController::createInterceptor : we already do intercept this objects dispatches !");
4260 DispatchInterceptionMultiplexer
* pInterceptor
= new DispatchInterceptionMultiplexer( _xInterception
, this );
4261 pInterceptor
->acquire();
4262 m_aControlDispatchInterceptors
.insert( m_aControlDispatchInterceptors
.end(), pInterceptor
);
4264 return pInterceptor
;
4267 //------------------------------------------------------------------------------
4268 bool FormController::ensureInteractionHandler()
4270 if ( m_xInteractionHandler
.is() )
4272 if ( m_bAttemptedHandlerCreation
)
4274 m_bAttemptedHandlerCreation
= true;
4276 m_xInteractionHandler
.set( m_aContext
.createComponent( ::rtl::OUString( "com.sun.star.task.InteractionHandler" ) ), UNO_QUERY
);
4277 OSL_ENSURE( m_xInteractionHandler
.is(), "FormController::ensureInteractionHandler: could not create an interaction handler!" );
4278 return m_xInteractionHandler
.is();
4281 //------------------------------------------------------------------------------
4282 void SAL_CALL
FormController::handle( const Reference
< XInteractionRequest
>& _rRequest
) throw (RuntimeException
)
4284 if ( !ensureInteractionHandler() )
4286 m_xInteractionHandler
->handle( _rRequest
);
4289 //------------------------------------------------------------------------------
4290 void FormController::deleteInterceptor(const Reference
< XDispatchProviderInterception
> & _xInterception
)
4292 OSL_ENSURE( !impl_isDisposed_nofail(), "FormController: already disposed!" );
4293 // search the interceptor responsible for the given object
4294 InterceptorsIterator aIter
;
4295 for ( aIter
= m_aControlDispatchInterceptors
.begin();
4296 aIter
!= m_aControlDispatchInterceptors
.end();
4300 if ((*aIter
)->getIntercepted() == _xInterception
)
4303 if (aIter
== m_aControlDispatchInterceptors
.end())
4308 // log off the interception from it's interception object
4309 DispatchInterceptionMultiplexer
* pInterceptorImpl
= *aIter
;
4310 pInterceptorImpl
->dispose();
4311 pInterceptorImpl
->release();
4313 // remove the interceptor from our array
4314 m_aControlDispatchInterceptors
.erase(aIter
);
4317 //--------------------------------------------------------------------
4318 void FormController::implInvalidateCurrentControlDependentFeatures()
4320 Sequence
< sal_Int16
> aCurrentControlDependentFeatures(4);
4322 aCurrentControlDependentFeatures
[0] = FormFeature::SortAscending
;
4323 aCurrentControlDependentFeatures
[1] = FormFeature::SortDescending
;
4324 aCurrentControlDependentFeatures
[2] = FormFeature::AutoFilter
;
4325 aCurrentControlDependentFeatures
[3] = FormFeature::RefreshCurrentControl
;
4327 invalidateFeatures( aCurrentControlDependentFeatures
);
4330 //--------------------------------------------------------------------
4331 void SAL_CALL
FormController::columnChanged( const EventObject
& /*_event*/ ) throw (RuntimeException
)
4333 implInvalidateCurrentControlDependentFeatures();
4336 } // namespace svxform
4338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */