update dev300-m58
[ooovba.git] / svx / source / form / fmctrler.cxx
blob4aeec29b63debd300ccc8d86b5249acc12f9ec14
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmctrler.cxx,v $
10 * $Revision: 1.71 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "confirmdelete.hxx"
35 #include "fmcontrolbordermanager.hxx"
36 #include "fmcontrollayout.hxx"
37 #include "fmctrler.hxx"
38 #include "fmdispatch.hxx"
39 #include "fmdocumentclassification.hxx"
40 #include "fmprop.hrc"
41 #include "fmresids.hrc"
42 #include "fmservs.hxx"
43 #include "fmshimp.hxx"
44 #include "fmtools.hxx"
45 #include "fmurl.hxx"
46 #include "svx/dialmgr.hxx"
47 #include "svx/fmshell.hxx"
48 #include "svx/fmview.hxx"
49 #include "svx/sdrpagewindow.hxx"
50 #include "svx/svdpagv.hxx"
51 #include "trace.hxx"
53 /** === begin UNO includes === **/
54 #include <com/sun/star/awt/FocusChangeReason.hpp>
55 #include <com/sun/star/awt/XCheckBox.hpp>
56 #include <com/sun/star/awt/XComboBox.hpp>
57 #include <com/sun/star/awt/XListBox.hpp>
58 #include <com/sun/star/awt/XVclWindowPeer.hpp>
59 #include <com/sun/star/beans/NamedValue.hpp>
60 #include <com/sun/star/beans/PropertyAttribute.hpp>
61 #include <com/sun/star/container/XIdentifierReplace.hpp>
62 #include <com/sun/star/form/TabulatorCycle.hpp>
63 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
64 #include <com/sun/star/form/XBoundComponent.hpp>
65 #include <com/sun/star/form/XBoundControl.hpp>
66 #include <com/sun/star/form/XGridControl.hpp>
67 #include <com/sun/star/form/XLoadable.hpp>
68 #include <com/sun/star/form/XReset.hpp>
69 #include <com/sun/star/frame/XController.hpp>
70 #include <com/sun/star/sdb/ParametersRequest.hpp>
71 #include <com/sun/star/sdb/RowChangeAction.hpp>
72 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
73 #include <com/sun/star/sdbc/ColumnValue.hpp>
74 #include <com/sun/star/util/XURLTransformer.hpp>
75 /** === end UNO includes === **/
77 #include <comphelper/enumhelper.hxx>
78 #include <comphelper/extract.hxx>
79 #include <comphelper/interaction.hxx>
80 #include <comphelper/namedvaluecollection.hxx>
81 #include <comphelper/propagg.hxx>
82 #include <comphelper/property.hxx>
83 #include <comphelper/sequence.hxx>
84 #include <comphelper/uno3.hxx>
85 #include <cppuhelper/queryinterface.hxx>
86 #include <cppuhelper/typeprovider.hxx>
87 #include <sfx2/bindings.hxx>
88 #include <sfx2/viewfrm.hxx>
89 #include <sfx2/viewsh.hxx>
90 #include <toolkit/controls/unocontrol.hxx>
91 #include <toolkit/helper/vclunohelper.hxx>
92 #include <tools/debug.hxx>
93 #include <tools/diagnose_ex.h>
94 #include <tools/shl.hxx>
95 #include <vcl/msgbox.hxx>
96 #include <vcl/svapp.hxx>
97 #include <rtl/logfile.hxx>
99 #include <algorithm>
100 #include <functional>
102 using namespace ::com::sun::star;
103 using namespace ::com::sun::star::uno;
104 using namespace ::com::sun::star::awt;
105 using namespace ::com::sun::star::sdb;
106 using namespace ::com::sun::star::sdbc;
107 using namespace ::com::sun::star::sdbcx;
108 using namespace ::com::sun::star::task;
109 using namespace ::com::sun::star::lang;
110 using namespace ::com::sun::star::util;
111 using namespace ::com::sun::star::form;
112 using namespace ::com::sun::star::form::validation;
113 using namespace ::com::sun::star::form::runtime;
114 using namespace ::com::sun::star::frame;
115 using namespace ::com::sun::star::beans;
116 using namespace ::com::sun::star::script;
117 using namespace ::com::sun::star::container;
118 using namespace ::comphelper;
119 using namespace ::connectivity;
120 using namespace ::svxform;
121 using namespace ::connectivity::simple;
123 //==============================================================================
124 // ColumnInfo
125 //==============================================================================
126 struct ColumnInfo
128 // information about the column itself
129 Reference< XColumn > xColumn;
130 sal_Int32 nNullable;
131 sal_Bool bAutoIncrement;
132 ::rtl::OUString sName;
134 // information about the control(s) bound to this column
136 /// the first control which is bound to the given column, and which requires input
137 Reference< XControl > xFirstControlWithInputRequired;
138 /** the first grid control which contains a column which is bound to the given database column, and requires
139 input
141 Reference< XGrid > xFirstGridWithInputRequiredColumn;
142 /** if xFirstControlWithInputRequired is a grid control, then nRequiredGridColumn specifies the position
143 of the grid column which is actually bound
145 sal_Int32 nRequiredGridColumn;
147 ColumnInfo()
148 :xColumn()
149 ,nNullable( ColumnValue::NULLABLE_UNKNOWN )
150 ,bAutoIncrement( sal_False )
151 ,sName()
152 ,xFirstControlWithInputRequired()
153 ,xFirstGridWithInputRequiredColumn()
154 ,nRequiredGridColumn( -1 )
159 //==============================================================================
160 //= ColumnInfoCache
161 //==============================================================================
162 class ColumnInfoCache
164 public:
165 ColumnInfoCache( const Reference< XColumnsSupplier >& _rxColSupplier );
167 size_t getColumnCount() const { return m_aColumns.size(); }
168 const ColumnInfo& getColumnInfo( size_t _pos );
170 bool controlsInitialized() const { return m_bControlsInitialized; }
171 void initializeControls( const Sequence< Reference< XControl > >& _rControls );
172 void deinitializeControls();
174 private:
175 typedef ::std::vector< ColumnInfo > ColumnInfos;
176 ColumnInfos m_aColumns;
177 bool m_bControlsInitialized;
180 //------------------------------------------------------------------------------
181 ColumnInfoCache::ColumnInfoCache( const Reference< XColumnsSupplier >& _rxColSupplier )
182 :m_aColumns()
183 ,m_bControlsInitialized( false )
185 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::ColumnInfoCache" );
188 m_aColumns.clear();
190 Reference< XColumnsSupplier > xSupplyCols( _rxColSupplier, UNO_SET_THROW );
191 Reference< XIndexAccess > xColumns( xSupplyCols->getColumns(), UNO_QUERY_THROW );
192 sal_Int32 nColumnCount = xColumns->getCount();
193 m_aColumns.reserve( nColumnCount );
195 Reference< XPropertySet > xColumnProps;
196 for ( sal_Int32 i = 0; i < nColumnCount; ++i )
198 ColumnInfo aColInfo;
199 aColInfo.xColumn.set( xColumns->getByIndex(i), UNO_QUERY_THROW );
201 xColumnProps.set( aColInfo.xColumn, UNO_QUERY_THROW );
202 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_ISNULLABLE ) >>= aColInfo.nNullable );
203 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_AUTOINCREMENT ) >>= aColInfo.bAutoIncrement );
204 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_NAME ) >>= aColInfo.sName );
206 m_aColumns.push_back( aColInfo );
209 catch( const Exception& )
211 DBG_UNHANDLED_EXCEPTION();
215 //------------------------------------------------------------------------------
216 namespace
218 bool lcl_isBoundTo( const Reference< XPropertySet >& _rxControlModel, const Reference< XInterface >& _rxNormDBField )
220 Reference< XInterface > xNormBoundField( _rxControlModel->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY );
221 return ( xNormBoundField.get() == _rxNormDBField.get() );
224 bool lcl_isInputRequired( const Reference< XPropertySet >& _rxControlModel )
226 sal_Bool bInputRequired = sal_True;
227 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_INPUT_REQUIRED ) >>= bInputRequired );
228 return ( bInputRequired != sal_False );
230 void lcl_resetColumnControlInfo( ColumnInfo& _rColInfo )
232 _rColInfo.xFirstControlWithInputRequired.clear();
233 _rColInfo.xFirstGridWithInputRequiredColumn.clear();
234 _rColInfo.nRequiredGridColumn = -1;
238 //------------------------------------------------------------------------------
239 void ColumnInfoCache::deinitializeControls()
241 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::deinitializeControls" );
242 for ( ColumnInfos::iterator col = m_aColumns.begin();
243 col != m_aColumns.end();
244 ++col
247 lcl_resetColumnControlInfo( *col );
251 //------------------------------------------------------------------------------
252 void ColumnInfoCache::initializeControls( const Sequence< Reference< XControl > >& _rControls )
254 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::initializeControls" );
257 // for every of our known columns, find the controls which are bound to this column
258 for ( ColumnInfos::iterator col = m_aColumns.begin();
259 col != m_aColumns.end();
260 ++col
263 OSL_ENSURE( !col->xFirstControlWithInputRequired.is() && !col->xFirstGridWithInputRequiredColumn.is()
264 && ( col->nRequiredGridColumn == -1 ), "ColumnInfoCache::initializeControls: called me twice?" );
266 lcl_resetColumnControlInfo( *col );
268 Reference< XInterface > xNormColumn( col->xColumn, UNO_QUERY_THROW );
270 const Reference< XControl >* pControl( _rControls.getConstArray() );
271 const Reference< XControl >* pControlEnd( pControl + _rControls.getLength() );
272 for ( ; pControl != pControlEnd; ++pControl )
274 if ( !pControl->is() )
275 continue;
277 Reference< XPropertySet > xModel( (*pControl)->getModel(), UNO_QUERY_THROW );
278 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
280 // special handling for grid controls
281 Reference< XGrid > xGrid( *pControl, UNO_QUERY );
282 if ( xGrid.is() )
284 Reference< XIndexAccess > xGridColAccess( xModel, UNO_QUERY_THROW );
285 sal_Int32 gridColCount = xGridColAccess->getCount();
286 sal_Int32 gridCol = 0;
287 for ( gridCol = 0; gridCol < gridColCount; ++gridCol )
289 Reference< XPropertySet > xGridColumnModel( xGridColAccess->getByIndex( gridCol ), UNO_QUERY_THROW );
291 if ( !lcl_isBoundTo( xGridColumnModel, xNormColumn )
292 || !lcl_isInputRequired( xGridColumnModel )
294 continue; // with next grid column
296 break;
299 if ( gridCol < gridColCount )
301 // found a grid column which is bound to the given
302 col->xFirstGridWithInputRequiredColumn = xGrid;
303 col->nRequiredGridColumn = gridCol;
304 break;
307 continue; // with next control
310 if ( !xModelPSI->hasPropertyByName( FM_PROP_BOUNDFIELD )
311 || !lcl_isBoundTo( xModel, xNormColumn )
312 || !lcl_isInputRequired( xModel )
314 continue; // with next control
316 break;
319 if ( pControl == pControlEnd )
320 // did not find a control which is bound to this particular column, and for which the input is required
321 continue; // with next DB column
323 col->xFirstControlWithInputRequired = *pControl;
326 catch( const Exception& )
328 DBG_UNHANDLED_EXCEPTION();
331 m_bControlsInitialized = true;
334 //------------------------------------------------------------------------------
335 const ColumnInfo& ColumnInfoCache::getColumnInfo( size_t _pos )
337 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::getColumnInfo" );
338 if ( _pos >= m_aColumns.size() )
339 throw IndexOutOfBoundsException();
341 return m_aColumns[ _pos ];
344 //==================================================================
345 // OParameterContinuation
346 //==================================================================
347 class OParameterContinuation : public OInteraction< XInteractionSupplyParameters >
349 Sequence< PropertyValue > m_aValues;
351 public:
352 OParameterContinuation() { }
354 Sequence< PropertyValue > getValues() const { return m_aValues; }
356 // XInteractionSupplyParameters
357 virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException);
360 //------------------------------------------------------------------
361 void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException)
363 m_aValues = _rValues;
366 //==================================================================
367 // FmXAutoControl
368 //==================================================================
369 struct FmFieldInfo
371 rtl::OUString aFieldName;
372 Reference< XPropertySet > xField;
373 Reference< XTextComponent > xText;
375 FmFieldInfo(const Reference< XPropertySet >& _xField, const Reference< XTextComponent >& _xText)
376 :xField(_xField)
377 ,xText(_xText)
378 {xField->getPropertyValue(FM_PROP_NAME) >>= aFieldName;}
381 //==================================================================
382 // FmXAutoControl
383 //==================================================================
384 class FmXAutoControl: public UnoControl
387 friend Reference< XInterface > SAL_CALL FmXAutoControl_NewInstance_Impl();
389 public:
390 FmXAutoControl(){}
392 virtual ::rtl::OUString GetComponentServiceName() {return ::rtl::OUString::createFromAscii("Edit");}
393 virtual void SAL_CALL createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw( RuntimeException );
395 protected:
396 virtual void ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal );
399 //------------------------------------------------------------------------------
400 void FmXAutoControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw( RuntimeException )
402 UnoControl::createPeer( rxToolkit, rParentPeer );
404 Reference< XTextComponent > xText(getPeer() , UNO_QUERY);
405 if (xText.is())
407 xText->setText(::rtl::OUString(String(SVX_RES(RID_STR_AUTOFIELD))));
408 xText->setEditable(sal_False);
412 //------------------------------------------------------------------------------
413 void FmXAutoControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal )
415 // these properties are ignored
416 if (rPropName == FM_PROP_TEXT)
417 return;
419 UnoControl::ImplSetPeerProperty( rPropName, rVal );
422 //------------------------------------------------------------------------------
423 IMPL_LINK( FmXFormController, OnActivateTabOrder, void*, /*EMPTYTAG*/ )
425 activateTabOrder();
426 return 1;
429 //------------------------------------------------------------------------------
430 struct UpdateAllListeners : public ::std::unary_function< Reference< XDispatch >, bool >
432 bool operator()( const Reference< XDispatch >& _rxDispatcher ) const
434 static_cast< ::svx::OSingleFeatureDispatcher* >( _rxDispatcher.get() )->updateAllListeners();
435 // the return is a dummy only so we can use this struct in a std::compose1 call
436 return true;
439 //..............................................................................
440 IMPL_LINK( FmXFormController, OnInvalidateFeatures, void*, /*_pNotInterestedInThisParam*/ )
442 ::osl::MutexGuard aGuard( m_aMutex );
443 for ( ::std::set< sal_Int32 >::const_iterator aLoop = m_aInvalidFeatures.begin();
444 aLoop != m_aInvalidFeatures.end();
445 ++aLoop
448 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( *aLoop );
449 if ( aDispatcherPos != m_aFeatureDispatchers.end() )
451 // TODO: for the real and actual listener notifications, we should release
452 // our mutex
453 UpdateAllListeners( )( aDispatcherPos->second );
456 return 1;
459 /*************************************************************************/
461 //------------------------------------------------------------------
462 Reference< XInterface > SAL_CALL
463 FmXFormController_NewInstance_Impl(const Reference< XMultiServiceFactory > & _rxORB)
465 return *(new FmXFormController(_rxORB));
468 //------------------------------------------------------------------
469 namespace fmctrlr
471 const ::rtl::OUString& getDataModeIdentifier()
473 static ::rtl::OUString s_sDataModeIdentifier = DATA_MODE;
474 return s_sDataModeIdentifier;
477 using namespace fmctrlr;
479 DBG_NAME( FmXFormController )
480 //------------------------------------------------------------------
481 FmXFormController::FmXFormController(const Reference< XMultiServiceFactory > & _rxORB,
482 FmFormView* _pView, Window* _pWindow )
483 :FmXFormController_BASE( m_aMutex )
484 ,OPropertySetHelper( FmXFormController_BASE::rBHelper )
485 ,OSQLParserClient(_rxORB)
486 ,m_xORB(_rxORB)
487 ,m_aActivateListeners(m_aMutex)
488 ,m_aModifyListeners(m_aMutex)
489 ,m_aErrorListeners(m_aMutex)
490 ,m_aDeleteListeners(m_aMutex)
491 ,m_aRowSetApproveListeners(m_aMutex)
492 ,m_aParameterListeners(m_aMutex)
493 ,m_pView(_pView)
494 ,m_pWindow(_pWindow)
495 ,m_pControlBorderManager( new ::svxform::ControlBorderManager )
496 ,m_aControllerFeatures( _rxORB, this )
497 ,m_aMode(getDataModeIdentifier())
498 ,m_aLoadEvent( LINK( this, FmXFormController, OnLoad ) )
499 ,m_aToggleEvent( LINK( this, FmXFormController, OnToggleAutoFields ) )
500 ,m_aActivationEvent( LINK( this, FmXFormController, OnActivated ) )
501 ,m_aDeactivationEvent( LINK( this, FmXFormController, OnDeactivated ) )
502 ,m_nCurrentFilterPosition(0)
503 ,m_bCurrentRecordModified(sal_False)
504 ,m_bCurrentRecordNew(sal_False)
505 ,m_bLocked(sal_False)
506 ,m_bDBConnection(sal_False)
507 ,m_bCycle(sal_False)
508 ,m_bCanInsert(sal_False)
509 ,m_bCanUpdate(sal_False)
510 ,m_bCommitLock(sal_False)
511 ,m_bModified(sal_False)
512 ,m_bControlsSorted(sal_False)
513 ,m_bFiltering(sal_False)
514 ,m_bAttachEvents(sal_True)
515 ,m_bDetachEvents(sal_True)
516 ,m_bAttemptedHandlerCreation( false )
518 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::FmXFormController" );
519 DBG_CTOR( FmXFormController, NULL );
521 ::comphelper::increment(m_refCount);
524 m_xAggregate = Reference< XAggregation >(
525 m_xORB->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.awt.TabController" ) ),
526 UNO_QUERY
528 DBG_ASSERT( m_xAggregate.is(), "FmXFormController::FmXFormController : could not create my aggregate !" );
529 m_xTabController = Reference< XTabController >( m_xAggregate, UNO_QUERY );
532 if ( m_xAggregate.is() )
533 m_xAggregate->setDelegator( *this );
535 ::comphelper::decrement(m_refCount);
537 m_aTabActivationTimer.SetTimeout( 500 );
538 m_aTabActivationTimer.SetTimeoutHdl( LINK( this, FmXFormController, OnActivateTabOrder ) );
540 m_aFeatureInvalidationTimer.SetTimeout( 200 );
541 m_aFeatureInvalidationTimer.SetTimeoutHdl( LINK( this, FmXFormController, OnInvalidateFeatures ) );
544 //------------------------------------------------------------------
545 FmXFormController::~FmXFormController()
548 ::osl::MutexGuard aGuard( m_aMutex );
550 m_aLoadEvent.CancelPendingCall();
551 m_aToggleEvent.CancelPendingCall();
552 m_aActivationEvent.CancelPendingCall();
553 m_aDeactivationEvent.CancelPendingCall();
555 if ( m_aTabActivationTimer.IsActive() )
556 m_aTabActivationTimer.Stop();
559 if ( m_aFeatureInvalidationTimer.IsActive() )
560 m_aFeatureInvalidationTimer.Stop();
562 disposeAllFeaturesAndDispatchers();
564 // Freigeben der Aggregation
565 if ( m_xAggregate.is() )
567 m_xAggregate->setDelegator( NULL );
568 m_xAggregate.clear();
571 DELETEZ( m_pControlBorderManager );
573 DBG_DTOR( FmXFormController, NULL );
576 // -----------------------------------------------------------------------------
577 void SAL_CALL FmXFormController::acquire() throw ()
579 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::acquire" );
580 FmXFormController_BASE::acquire();
583 // -----------------------------------------------------------------------------
584 void SAL_CALL FmXFormController::release() throw ()
586 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::release" );
587 FmXFormController_BASE::release();
590 //------------------------------------------------------------------
591 Any SAL_CALL FmXFormController::queryInterface( const Type& _rType ) throw(RuntimeException)
593 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::queryInterface" );
594 Any aRet = FmXFormController_BASE::queryInterface( _rType );
595 if ( !aRet.hasValue() )
596 aRet = OPropertySetHelper::queryInterface( _rType );
597 if ( !aRet.hasValue() )
598 aRet = m_xAggregate->queryAggregation( _rType );
599 return aRet;
602 //------------------------------------------------------------------------------
603 Sequence< sal_Int8 > SAL_CALL FmXFormController::getImplementationId() throw( RuntimeException )
605 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getImplementationId" );
606 static ::cppu::OImplementationId* pId = NULL;
607 if ( !pId )
609 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
610 if ( !pId )
612 static ::cppu::OImplementationId aId;
613 pId = &aId;
616 return pId->getImplementationId();
619 //------------------------------------------------------------------------------
620 Sequence< Type > SAL_CALL FmXFormController::getTypes( ) throw(RuntimeException)
622 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getTypes" );
623 return comphelper::concatSequences(
624 FmXFormController_BASE::getTypes(),
625 ::cppu::OPropertySetHelper::getTypes()
629 // -----------------------------------------------------------------------------
630 // XUnoTunnel
631 Sequence< sal_Int8 > FmXFormController::getUnoTunnelImplementationId()
633 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getUnoTunnelImplementationId" );
634 static ::cppu::OImplementationId * pId = NULL;
635 if ( !pId )
637 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
638 if ( !pId )
640 static ::cppu::OImplementationId aId;
641 pId = &aId;
644 return pId->getImplementationId();
646 //------------------------------------------------------------------------------
647 FmXFormController* FmXFormController::getImplementation( const Reference< XInterface >& _rxComponent )
649 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getImplementation" );
650 Reference< XUnoTunnel > xTunnel( _rxComponent, UNO_QUERY );
651 if ( xTunnel.is() )
652 return reinterpret_cast< FmXFormController* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
653 return NULL;
655 //------------------------------------------------------------------------------
656 sal_Int64 SAL_CALL FmXFormController::getSomething(Sequence<sal_Int8> const& rId)throw( RuntimeException )
658 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSomething" );
659 if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
660 return reinterpret_cast< sal_Int64 >( this );
662 return sal_Int64();
665 // XServiceInfo
666 //------------------------------------------------------------------------------
667 sal_Bool SAL_CALL FmXFormController::supportsService(const ::rtl::OUString& ServiceName) throw( RuntimeException )
669 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::supportsService" );
670 Sequence< ::rtl::OUString> aSNL(getSupportedServiceNames());
671 const ::rtl::OUString * pArray = aSNL.getConstArray();
672 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
673 if( pArray[i] == ServiceName )
674 return sal_True;
675 return sal_False;
678 //------------------------------------------------------------------------------
679 ::rtl::OUString SAL_CALL FmXFormController::getImplementationName() throw( RuntimeException )
681 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getImplementationName" );
682 return ::rtl::OUString::createFromAscii("com.sun.star.form.FmXFormController");
685 //------------------------------------------------------------------------------
686 Sequence< ::rtl::OUString> SAL_CALL FmXFormController::getSupportedServiceNames(void) throw( RuntimeException )
688 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSupportedServiceNames" );
689 // service names which are supported only, but cannot be used to created an
690 // instance at a service factory
691 Sequence< ::rtl::OUString > aNonCreatableServiceNames( 1 );
692 aNonCreatableServiceNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.FormControllerDispatcher" ) );
694 // services which can be used to created an instance at a service factory
695 Sequence< ::rtl::OUString > aCreatableServiceNames( getSupportedServiceNames_Static() );
696 return ::comphelper::concatSequences( aCreatableServiceNames, aNonCreatableServiceNames );
699 //------------------------------------------------------------------------------
700 sal_Bool SAL_CALL FmXFormController::approveReset(const EventObject& /*rEvent*/) throw( RuntimeException )
702 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveReset" );
703 return sal_True;
706 //------------------------------------------------------------------------------
707 void SAL_CALL FmXFormController::resetted(const EventObject& rEvent) throw( RuntimeException )
709 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::resetted" );
710 ::osl::MutexGuard aGuard(m_aMutex);
711 if (getCurrentControl().is() && (getCurrentControl()->getModel() == rEvent.Source))
712 m_bModified = sal_False;
715 //------------------------------------------------------------------------------
716 Sequence< ::rtl::OUString> FmXFormController::getSupportedServiceNames_Static(void)
718 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSupportedServiceNames_Static" );
719 static Sequence< ::rtl::OUString> aServices;
720 if (!aServices.getLength())
722 aServices.realloc(2);
723 aServices.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.form.FormController");
724 aServices.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.awt.control.TabController");
726 return aServices;
729 //------------------------------------------------------------------------------
730 void FmXFormController::setCurrentFilterPosition( sal_Int32 nPos )
732 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setCurrentFilterPosition" );
733 DBG_ASSERT(nPos < (sal_Int32)m_aFilters.size(), "Invalid Position");
735 if (nPos != m_nCurrentFilterPosition)
737 m_nCurrentFilterPosition = nPos;
739 // reset the text for all controls
740 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
741 iter != m_aFilterControls.end(); iter++)
742 (*iter).first->setText(rtl::OUString());
744 if ( nPos != -1 )
746 impl_setTextOnAllFilter_throw();
750 // -----------------------------------------------------------------------------
751 void FmXFormController::impl_setTextOnAllFilter_throw()
753 // set the text for all filters
754 OSL_ENSURE( ( m_aFilters.size() > (size_t)m_nCurrentFilterPosition ) && ( m_nCurrentFilterPosition >= 0 ),
755 "FmXFormController::setCurrentFilterPosition: m_nCurrentFilterPosition too big" );
757 if ( ( m_nCurrentFilterPosition >= 0 ) && ( (size_t)m_nCurrentFilterPosition < m_aFilters.size() ) )
759 FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
760 for (FmFilterRow::const_iterator iter2 = rRow.begin();
761 iter2 != rRow.end(); iter2++)
763 (*iter2).first->setText((*iter2).second);
765 } // if ( ( m_nCurrentFilterPosition >= 0 ) && ( (size_t)m_nCurrentFilterPosition < m_aFilters.size() ) )
767 // OPropertySetHelper
768 //------------------------------------------------------------------------------
769 sal_Bool FmXFormController::convertFastPropertyValue( Any & /*rConvertedValue*/, Any & /*rOldValue*/,
770 sal_Int32 /*nHandle*/, const Any& /*rValue*/ )
771 throw( IllegalArgumentException )
773 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::convertFastPropertyValue" );
774 return sal_False;
777 //------------------------------------------------------------------------------
778 void FmXFormController::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/, const Any& /*rValue*/ )
779 throw( Exception )
781 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setFastPropertyValue_NoBroadcast" );
784 //------------------------------------------------------------------------------
785 void FmXFormController::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
787 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getFastPropertyValue" );
788 switch (nHandle)
790 case FM_ATTR_FILTER:
792 ::rtl::OUStringBuffer aFilter;
793 OStaticDataAccessTools aStaticTools;
794 Reference<XConnection> xConnection(aStaticTools.getRowSetConnection(Reference< XRowSet>(m_xModelAsIndex, UNO_QUERY)));
795 if (xConnection.is())
797 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
798 Reference< XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
799 Reference< XNumberFormatter> xFormatter(m_xORB
800 ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
801 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
803 Reference< XColumnsSupplier> xSupplyCols(m_xModelAsIndex, UNO_QUERY);
804 Reference< XNameAccess> xFields(xSupplyCols->getColumns(), UNO_QUERY);
806 ::rtl::OUString aQuote( xMetaData->getIdentifierQuoteString() );
808 // now add the filter rows
809 for ( FmFilterRows::const_iterator row = m_aFilters.begin(); row != m_aFilters.end(); ++row )
811 const FmFilterRow& rRow = *row;
813 if ( rRow.empty() )
814 continue;
816 if ( aFilter.getLength() )
817 aFilter.appendAscii( " OR " );
819 aFilter.appendAscii( "( " );
820 for ( FmFilterRow::const_iterator condition = rRow.begin(); condition != rRow.end(); ++condition )
822 // get the field of the controls map
823 Reference< XTextComponent > xText = condition->first;
824 Reference< XPropertySet > xField = m_aFilterControls.find( xText )->second;
825 DBG_ASSERT( xField.is(), "FmXFormController::getFastPropertyValue: no field found!" );
826 if ( condition != rRow.begin() )
827 aFilter.appendAscii( " AND " );
829 ::rtl::OUString sFilterValue( condition->second );
831 ::rtl::OUString sErrorMsg, sCriteria;
832 ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree( sErrorMsg, sFilterValue, xFormatter, xField );
833 OSL_ENSURE( xParseNode.is(), "FmXFormController::getFastPropertyValue: could not parse the field value predicate!" );
834 if ( xParseNode.is() )
836 // don't use a parse context here, we need it unlocalized
837 xParseNode->parseNodeToStr( sCriteria, xConnection, NULL );
838 aFilter.append( sCriteria );
841 aFilter.appendAscii( " )" );
844 rValue <<= aFilter.makeStringAndClear();
846 break;
848 case FM_ATTR_FORM_OPERATIONS:
849 rValue <<= m_aControllerFeatures->getFormOperations();
850 break;
854 //------------------------------------------------------------------------------
855 Reference< XPropertySetInfo > FmXFormController::getPropertySetInfo() throw( RuntimeException )
857 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getPropertySetInfo" );
858 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
859 return xInfo;
862 //------------------------------------------------------------------------------
863 #define DECL_PROP_CORE(varname, type) \
864 pDesc[nPos++] = Property(FM_PROP_##varname, FM_ATTR_##varname, ::getCppuType((const type*)0),
867 #define DECL_PROP1(varname, type, attrib1) \
868 DECL_PROP_CORE(varname, type) PropertyAttribute::attrib1)
870 //------------------------------------------------------------------------------
871 void FmXFormController::fillProperties(
872 Sequence< Property >& /* [out] */ _rProps,
873 Sequence< Property >& /* [out] */ /*_rAggregateProps*/
874 ) const
876 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::fillProperties" );
877 _rProps.realloc(2);
878 sal_Int32 nPos = 0;
879 Property* pDesc = _rProps.getArray();
880 DECL_PROP1(FILTER, rtl::OUString, READONLY);
881 DECL_PROP1(FORM_OPERATIONS, Reference< XFormOperations >, READONLY);
884 //------------------------------------------------------------------------------
885 ::cppu::IPropertyArrayHelper& FmXFormController::getInfoHelper()
887 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getInfoHelper" );
888 return *getArrayHelper();
891 // XElementAccess
892 //------------------------------------------------------------------------------
893 sal_Bool SAL_CALL FmXFormController::hasElements(void) throw( RuntimeException )
895 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::hasElements" );
896 ::osl::MutexGuard aGuard( m_aMutex );
897 return !m_aChilds.empty();
900 //------------------------------------------------------------------------------
901 Type SAL_CALL FmXFormController::getElementType(void) throw( RuntimeException )
903 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getElementType" );
904 return ::getCppuType((const Reference< XFormController>*)0);
908 // XEnumerationAccess
909 //------------------------------------------------------------------------------
910 Reference< XEnumeration > SAL_CALL FmXFormController::createEnumeration(void) throw( RuntimeException )
912 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::createEnumeration" );
913 ::osl::MutexGuard aGuard( m_aMutex );
914 return new ::comphelper::OEnumerationByIndex(this);
917 // XIndexAccess
918 //------------------------------------------------------------------------------
919 sal_Int32 SAL_CALL FmXFormController::getCount(void) throw( RuntimeException )
921 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getCount" );
922 ::osl::MutexGuard aGuard( m_aMutex );
923 return m_aChilds.size();
926 //------------------------------------------------------------------------------
927 Any SAL_CALL FmXFormController::getByIndex(sal_Int32 Index) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
929 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getByIndex" );
930 ::osl::MutexGuard aGuard( m_aMutex );
931 if (Index < 0 ||
932 Index >= (sal_Int32)m_aChilds.size())
933 throw IndexOutOfBoundsException();
935 return makeAny(m_aChilds[Index]);
936 // , ::getCppuType((const XFormController*)0));
939 //-----------------------------------------------------------------------------
940 void FmXFormController::addChild(FmXFormController* pChild)
942 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addChild" );
943 Reference< XFormController > xController(pChild);
944 m_aChilds.push_back(xController);
945 pChild->setParent(static_cast< XFormController* >(this));
947 Reference< XFormComponent > xForm(pChild->getModel(), UNO_QUERY);
949 // search the position of the model within the form
950 sal_uInt32 nPos = m_xModelAsIndex->getCount();
951 Reference< XFormComponent > xTemp;
952 for( ; nPos; )
954 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
955 if ((XFormComponent*)xForm.get() == (XFormComponent*)xTemp.get())
957 Reference< XInterface > xIfc(xController, UNO_QUERY);
958 m_xModelAsManager->attach( nPos, xIfc, makeAny( xController) );
959 break;
964 // EventListener
965 //------------------------------------------------------------------------------
966 void SAL_CALL FmXFormController::disposing(const EventObject& e) throw( RuntimeException )
968 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::disposing" );
969 // Ist der Container disposed worden
970 ::osl::MutexGuard aGuard( m_aMutex );
971 Reference< XControlContainer > xContainer(e.Source, UNO_QUERY);
972 if (xContainer.is())
974 setContainer(Reference< XControlContainer > ());
976 else
978 // ist ein Control disposed worden
979 Reference< XControl > xControl(e.Source, UNO_QUERY);
980 if (xControl.is())
982 if (getContainer().is())
983 removeControl(xControl);
988 // OComponentHelper
989 //-----------------------------------------------------------------------------
990 void FmXFormController::disposeAllFeaturesAndDispatchers() SAL_THROW(())
992 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::disposeAllFeaturesAndDispatchers" );
993 for ( DispatcherContainer::iterator aDispatcher = m_aFeatureDispatchers.begin();
994 aDispatcher != m_aFeatureDispatchers.end();
995 ++aDispatcher
1000 ::comphelper::disposeComponent( aDispatcher->second );
1002 catch( const Exception& )
1004 OSL_ENSURE( sal_False, "FmXFormController::disposeAllFeaturesAndDispatchers: caught an exception while disposing a dispatcher!" );
1007 m_aFeatureDispatchers.clear();
1008 m_aControllerFeatures.dispose();
1011 //-----------------------------------------------------------------------------
1012 void FmXFormController::disposing(void)
1014 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::disposing" );
1015 EventObject aEvt(static_cast< XFormController* >(this));
1017 // if we're still active, simulate a "deactivated" event
1018 if ( m_xActiveControl.is() )
1019 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvt );
1021 // notify all our listeners
1022 m_aActivateListeners.disposeAndClear(aEvt);
1023 m_aModifyListeners.disposeAndClear(aEvt);
1024 m_aErrorListeners.disposeAndClear(aEvt);
1025 m_aDeleteListeners.disposeAndClear(aEvt);
1026 m_aRowSetApproveListeners.disposeAndClear(aEvt);
1027 m_aParameterListeners.disposeAndClear(aEvt);
1029 removeBoundFieldListener();
1030 stopFiltering();
1032 m_pControlBorderManager->restoreAll();
1034 m_aFilters.clear();
1036 ::osl::MutexGuard aGuard( m_aMutex );
1037 m_xActiveControl = NULL;
1038 implSetCurrentControl( NULL );
1040 // clean up our children
1041 for (FmFormControllers::const_iterator i = m_aChilds.begin();
1042 i != m_aChilds.end(); i++)
1044 // search the position of the model within the form
1045 Reference< XFormComponent > xForm((*i)->getModel(), UNO_QUERY);
1046 sal_uInt32 nPos = m_xModelAsIndex->getCount();
1047 Reference< XFormComponent > xTemp;
1048 for( ; nPos; )
1051 m_xModelAsIndex->getByIndex( --nPos ) >>= xTemp;
1052 if ( xForm.get() == xTemp.get() )
1054 Reference< XInterface > xIfc( *i, UNO_QUERY );
1055 m_xModelAsManager->detach( nPos, xIfc );
1056 break;
1060 Reference< XComponent > (*i, UNO_QUERY)->dispose();
1062 m_aChilds.clear();
1064 disposeAllFeaturesAndDispatchers();
1066 if (m_bDBConnection)
1067 unload();
1069 setContainer( NULL );
1070 setModel( NULL );
1071 setParent( NULL );
1073 ::comphelper::disposeComponent( m_xComposer );
1075 m_xORB = NULL;
1076 m_bDBConnection = sal_False;
1079 //------------------------------------------------------------------------------
1080 namespace
1082 static bool lcl_shouldUseDynamicControlBorder( const Reference< XInterface >& _rxForm, const Any& _rDynamicColorProp )
1084 bool bDoUse = false;
1085 if ( !( _rDynamicColorProp >>= bDoUse ) )
1087 DocumentType eDocType = DocumentClassification::classifyHostDocument( _rxForm );
1088 return ControlLayouter::useDynamicBorderColor( eDocType );
1090 return bDoUse;
1094 //------------------------------------------------------------------------------
1095 void SAL_CALL FmXFormController::propertyChange(const PropertyChangeEvent& evt) throw( RuntimeException )
1097 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::propertyChange" );
1098 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1099 if ( evt.PropertyName == FM_PROP_BOUNDFIELD )
1101 Reference<XPropertySet> xOldBound;
1102 evt.OldValue >>= xOldBound;
1103 if ( !xOldBound.is() && evt.NewValue.hasValue() )
1105 Reference< XControlModel > xControlModel(evt.Source,UNO_QUERY);
1106 Reference< XControl > xControl = findControl(m_aControls,xControlModel,sal_False,sal_False);
1107 if ( xControl.is() )
1109 startControlModifyListening( xControl );
1110 Reference<XPropertySet> xProp(xControlModel,UNO_QUERY);
1111 if ( xProp.is() )
1112 xProp->removePropertyChangeListener(FM_PROP_BOUNDFIELD, this);
1116 else
1118 sal_Bool bModifiedChanged = (evt.PropertyName == FM_PROP_ISMODIFIED);
1119 sal_Bool bNewChanged = (evt.PropertyName == FM_PROP_ISNEW);
1120 if (bModifiedChanged || bNewChanged)
1122 ::osl::MutexGuard aGuard( m_aMutex );
1123 if (bModifiedChanged)
1124 m_bCurrentRecordModified = ::comphelper::getBOOL(evt.NewValue);
1125 else
1126 m_bCurrentRecordNew = ::comphelper::getBOOL(evt.NewValue);
1128 // toggle the locking
1129 if (m_bLocked != determineLockState())
1131 m_bLocked = !m_bLocked;
1132 setLocks();
1133 if (isListeningForChanges())
1134 startListening();
1135 else
1136 stopListening();
1139 if ( bNewChanged )
1140 m_aToggleEvent.Call();
1142 if (!m_bCurrentRecordModified)
1143 m_bModified = sal_False;
1145 else if ( evt.PropertyName == FM_PROP_DYNAMIC_CONTROL_BORDER )
1147 bool bEnable = lcl_shouldUseDynamicControlBorder( evt.Source, evt.NewValue );
1148 if ( bEnable )
1150 m_pControlBorderManager->enableDynamicBorderColor();
1151 if ( m_xActiveControl.is() )
1152 m_pControlBorderManager->focusGained( m_xActiveControl.get() );
1154 else
1156 m_pControlBorderManager->disableDynamicBorderColor();
1162 //------------------------------------------------------------------------------
1163 bool FmXFormController::replaceControl( const Reference< XControl >& _rxExistentControl, const Reference< XControl >& _rxNewControl )
1165 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::replaceControl" );
1166 bool bSuccess = false;
1169 Reference< XIdentifierReplace > xContainer( getContainer(), UNO_QUERY );
1170 DBG_ASSERT( xContainer.is(), "FmXFormController::replaceControl: yes, it's not required by the service description, but XItentifierReplaces would be nice!" );
1171 if ( xContainer.is() )
1173 // look up the ID of _rxExistentControl
1174 Sequence< sal_Int32 > aIdentifiers( xContainer->getIdentifiers() );
1175 const sal_Int32* pIdentifiers = aIdentifiers.getConstArray();
1176 const sal_Int32* pIdentifiersEnd = aIdentifiers.getConstArray() + aIdentifiers.getLength();
1177 for ( ; pIdentifiers != pIdentifiersEnd; ++pIdentifiers )
1179 Reference< XControl > xCheck( xContainer->getByIdentifier( *pIdentifiers ), UNO_QUERY );
1180 if ( xCheck == _rxExistentControl )
1181 break;
1183 DBG_ASSERT( pIdentifiers != pIdentifiersEnd, "FmXFormController::replaceControl: did not find the control in the container!" );
1184 if ( pIdentifiers != pIdentifiersEnd )
1186 bool bReplacedWasActive = ( m_xActiveControl.get() == _rxExistentControl.get() );
1187 bool bReplacedWasCurrent = ( m_xCurrentControl.get() == _rxExistentControl.get() );
1189 if ( bReplacedWasActive )
1191 m_xActiveControl = NULL;
1192 implSetCurrentControl( NULL );
1194 else if ( bReplacedWasCurrent )
1196 implSetCurrentControl( _rxNewControl );
1199 // carry over the model
1200 _rxNewControl->setModel( _rxExistentControl->getModel() );
1202 xContainer->replaceByIdentifer( *pIdentifiers, makeAny( _rxNewControl ) );
1203 bSuccess = true;
1205 if ( bReplacedWasActive )
1207 Reference< XWindow > xControlWindow( _rxNewControl, UNO_QUERY );
1208 if ( xControlWindow.is() )
1209 xControlWindow->setFocus();
1214 catch( const Exception& )
1216 OSL_ENSURE( sal_False, "FmXFormController::replaceControl: caught an exception!" );
1219 Reference< XControl > xDisposeIt( bSuccess ? _rxExistentControl : _rxNewControl );
1220 ::comphelper::disposeComponent( xDisposeIt );
1221 return bSuccess;
1224 //------------------------------------------------------------------------------
1225 void FmXFormController::toggleAutoFields(sal_Bool bAutoFields)
1227 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::toggleAutoFields" );
1228 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1231 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
1232 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
1233 sal_Int32 nControls = aControlsCopy.getLength();
1235 if (bAutoFields)
1237 // as we don't want new controls to be attached to the scripting environment
1238 // we change attach flags
1239 m_bAttachEvents = sal_False;
1240 for (sal_Int32 i = nControls; i > 0;)
1242 Reference< XControl > xControl = pControls[--i];
1243 if (xControl.is())
1245 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1246 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1248 // does the model use a bound field ?
1249 Reference< XPropertySet > xField;
1250 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1252 // is it a autofield?
1253 if ( xField.is()
1254 && ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT, xField )
1255 && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_AUTOINCREMENT ) )
1258 replaceControl( xControl, new FmXAutoControl );
1263 m_bAttachEvents = sal_True;
1265 else
1267 m_bDetachEvents = sal_False;
1268 for (sal_Int32 i = nControls; i > 0;)
1270 Reference< XControl > xControl = pControls[--i];
1271 if (xControl.is())
1273 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1274 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1276 // does the model use a bound field ?
1277 Reference< XPropertySet > xField;
1278 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1280 // is it a autofield?
1281 if ( xField.is()
1282 && ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT, xField )
1283 && ::comphelper::getBOOL( xField->getPropertyValue(FM_PROP_AUTOINCREMENT ) )
1286 ::rtl::OUString sServiceName;
1287 OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DEFAULTCONTROL ) >>= sServiceName );
1288 Reference< XControl > xNewControl( m_xORB->createInstance( sServiceName ), UNO_QUERY );
1289 replaceControl( xControl, xNewControl );
1294 m_bDetachEvents = sal_True;
1298 //------------------------------------------------------------------------------
1299 IMPL_LINK(FmXFormController, OnToggleAutoFields, void*, EMPTYARG)
1301 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1303 toggleAutoFields(m_bCurrentRecordNew);
1304 return 1L;
1307 // XTextListener
1308 //------------------------------------------------------------------------------
1309 void SAL_CALL FmXFormController::textChanged(const TextEvent& e) throw( RuntimeException )
1311 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::textChanged" );
1312 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1313 if (m_bFiltering)
1315 Reference< XTextComponent > xText(e.Source,UNO_QUERY);
1316 ::rtl::OUString aText = xText->getText();
1318 // Suchen der aktuellen Row
1319 OSL_ENSURE( ( m_aFilters.size() > (size_t)m_nCurrentFilterPosition ) && ( m_nCurrentFilterPosition >= 0 ),
1320 "FmXFormController::textChanged: m_nCurrentFilterPosition too big" );
1322 if ( ( m_nCurrentFilterPosition >= 0 ) && ( (size_t)m_nCurrentFilterPosition < m_aFilters.size() ) )
1324 FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
1326 // do we have a new filter
1327 if (aText.getLength())
1328 rRow[xText] = aText;
1329 else
1331 // do we have the control in the row
1332 FmFilterRow::iterator iter = rRow.find(xText);
1333 // erase the entry out of the row
1334 if (iter != rRow.end())
1335 rRow.erase(iter);
1339 else
1340 impl_onModify();
1343 // XItemListener
1344 //------------------------------------------------------------------------------
1345 void SAL_CALL FmXFormController::itemStateChanged(const ItemEvent& /*rEvent*/) throw( RuntimeException )
1347 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::itemStateChanged" );
1348 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1349 impl_onModify();
1352 // XModificationBroadcaster
1353 //------------------------------------------------------------------------------
1354 void SAL_CALL FmXFormController::addModifyListener(const Reference< XModifyListener > & l) throw( RuntimeException )
1356 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addModifyListener" );
1357 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1358 m_aModifyListeners.addInterface( l );
1361 //------------------------------------------------------------------------------
1362 void FmXFormController::removeModifyListener(const Reference< XModifyListener > & l) throw( RuntimeException )
1364 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeModifyListener" );
1365 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1366 m_aModifyListeners.removeInterface( l );
1369 // XModificationListener
1370 //------------------------------------------------------------------------------
1371 void FmXFormController::modified( const EventObject& _rEvent ) throw( RuntimeException )
1373 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::modified" );
1374 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1378 if ( _rEvent.Source != m_xActiveControl )
1379 { // let this control grab the focus
1380 // (this case may happen if somebody moves the scroll wheel of the mouse over a control
1381 // which does not have the focus)
1382 // 85511 - 29.05.2001 - frank.schoenheit@germany.sun.com
1384 // also, it happens when an image control gets a new image by double-clicking it
1385 // #i88458# / 2009-01-12 / frank.schoenheit@sun.com
1386 Reference< XWindow > xControlWindow( _rEvent.Source, UNO_QUERY_THROW );
1387 xControlWindow->setFocus();
1390 catch( const Exception& )
1392 DBG_UNHANDLED_EXCEPTION();
1395 impl_onModify();
1398 //------------------------------------------------------------------------------
1399 void FmXFormController::impl_onModify()
1401 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::onModify" );
1402 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1405 ::osl::MutexGuard aGuard( m_aMutex );
1406 if ( !m_bModified )
1407 m_bModified = sal_True;
1410 EventObject aEvt(static_cast<cppu::OWeakObject*>(this));
1411 m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
1414 //------------------------------------------------------------------------------
1415 sal_Bool FmXFormController::determineLockState() const
1417 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::determineLockState" );
1418 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1419 // a.) in filter mode we are always locked
1420 // b.) if we have no valid model or our model (a result set) is not alive -> we're locked
1421 // c.) if we are inserting everything is OK and we are not locked
1422 // d.) if are not updatable or on invalid position
1423 Reference< XResultSet > xResultSet(m_xModelAsIndex, UNO_QUERY);
1424 if (m_bFiltering || !xResultSet.is() || !isRowSetAlive(xResultSet))
1425 return sal_True;
1426 else
1427 return (m_bCanInsert && m_bCurrentRecordNew) ? sal_False
1428 : xResultSet->isBeforeFirst() || xResultSet->isAfterLast() || xResultSet->rowDeleted() || !m_bCanUpdate;
1431 // FocusListener
1432 //------------------------------------------------------------------------------
1433 void FmXFormController::focusGained(const FocusEvent& e) throw( RuntimeException )
1435 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::focusGained" );
1436 TRACE_RANGE( "FmXFormController::focusGained" );
1438 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1439 ::osl::MutexGuard aGuard( m_aMutex );
1440 Reference< XControl > xControl(e.Source, UNO_QUERY);
1442 m_pControlBorderManager->focusGained( e.Source );
1444 if (m_bDBConnection)
1446 // do we need to keep the locking of the commit
1447 // we hold the lock as long as the control differs from the current
1448 // otherwhise we disabled the lock
1449 m_bCommitLock = m_bCommitLock && (XControl*)xControl.get() != (XControl*)m_xCurrentControl.get();
1450 if (m_bCommitLock)
1451 return;
1453 // when do we have to commit a value to form or a filter
1454 // a.) if the current value is modified
1455 // b.) there must be a current control
1456 // c.) and it must be different from the new focus owning control or
1457 // d.) the focus is moving around (so we have only one control)
1459 if ( ( m_bModified || m_bFiltering )
1460 && m_xCurrentControl.is()
1461 && ( ( xControl.get() != m_xCurrentControl.get() )
1462 || ( ( e.FocusFlags & FocusChangeReason::AROUND )
1463 && ( m_bCycle || m_bFiltering )
1468 // check the old control if the content is ok
1469 #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
1470 Reference< XBoundControl > xLockingTest(m_xCurrentControl, UNO_QUERY);
1471 sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
1472 OSL_ENSURE(!bControlIsLocked, "FmXFormController::Gained: I'm modified and the current control is locked ? How this ?");
1473 // normalerweise sollte ein gelocktes Control nicht modified sein, also muss wohl mein bModified aus einem anderen Kontext
1474 // gesetzt worden sein, was ich nicht verstehen wuerde ...
1475 #endif
1476 DBG_ASSERT(m_xCurrentControl.is(), "kein CurrentControl gesetzt");
1477 // zunaechst das Control fragen ob es das IFace unterstuetzt
1478 Reference< XBoundComponent > xBound(m_xCurrentControl, UNO_QUERY);
1479 if (!xBound.is() && m_xCurrentControl.is())
1480 xBound = Reference< XBoundComponent > (m_xCurrentControl->getModel(), UNO_QUERY);
1482 // lock if we lose the focus during commit
1483 m_bCommitLock = sal_True;
1485 // Commit nicht erfolgreich, Focus zuruecksetzen
1486 if (xBound.is() && !xBound->commit())
1488 // the commit failed and we don't commit again until the current control
1489 // which couldn't be commit gains the focus again
1490 Reference< XWindow > xWindow(m_xCurrentControl, UNO_QUERY);
1491 if (xWindow.is())
1492 xWindow->setFocus();
1493 return;
1495 else
1497 m_bModified = sal_False;
1498 m_bCommitLock = sal_False;
1502 if (!m_bFiltering && m_bCycle && (e.FocusFlags & FocusChangeReason::AROUND) && m_xCurrentControl.is())
1504 if ( e.FocusFlags & FocusChangeReason::FORWARD )
1506 if ( m_aControllerFeatures->isEnabled( SID_FM_RECORD_NEXT ) )
1507 m_aControllerFeatures->moveRight();
1509 else // backward
1511 if ( m_aControllerFeatures->isEnabled( SID_FM_RECORD_PREV ) )
1512 m_aControllerFeatures->moveLeft();
1517 // Immer noch ein und dasselbe Control
1518 if ( (m_xActiveControl.get() == xControl.get())
1519 && (xControl.get() == m_xCurrentControl.get())
1522 DBG_ASSERT(m_xCurrentControl.is(), "Kein CurrentControl selektiert");
1523 return;
1526 sal_Bool bActivated = !m_xActiveControl.is() && xControl.is();
1528 m_xActiveControl = xControl;
1530 implSetCurrentControl( xControl );
1531 OSL_POSTCOND( m_xCurrentControl.is(), "implSetCurrentControl did nonsense!" );
1533 if ( bActivated )
1535 // (asynchronously) call activation handlers
1536 m_aActivationEvent.Call();
1538 // call modify listeners
1539 if ( m_bModified )
1540 m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *this ) );
1543 // invalidate all features which depend on the currently focused control
1544 if ( m_bDBConnection && !m_bFiltering && m_pView )
1545 implInvalidateCurrentControlDependentFeatures();
1547 if (m_xCurrentControl.is())
1549 // Control erhaelt Focus, dann eventuell in den sichtbaren Bereich
1550 Reference< XWindow > xWindow(xControl, UNO_QUERY);
1551 if (xWindow.is() && m_pView && m_pWindow)
1553 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
1554 ::Rectangle aNewRect(aRect.X,aRect.Y,aRect.X+aRect.Width,aRect.Y+aRect.Height);
1555 aNewRect = m_pWindow->PixelToLogic(aNewRect);
1556 m_pView->MakeVisible( aNewRect, *const_cast< Window* >( m_pWindow ) );
1561 //------------------------------------------------------------------------------
1562 IMPL_LINK( FmXFormController, OnActivated, void*, /**/ )
1564 EventObject aEvent;
1565 aEvent.Source = *this;
1566 m_aActivateListeners.notifyEach( &XFormControllerListener::formActivated, aEvent );
1568 return 0L;
1571 //------------------------------------------------------------------------------
1572 IMPL_LINK( FmXFormController, OnDeactivated, void*, /**/ )
1574 EventObject aEvent;
1575 aEvent.Source = *this;
1576 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvent );
1578 return 0L;
1581 //------------------------------------------------------------------------------
1582 void FmXFormController::focusLost(const FocusEvent& e) throw( RuntimeException )
1584 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::focusLost" );
1585 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1587 m_pControlBorderManager->focusLost( e.Source );
1589 Reference< XControl > xControl(e.Source, UNO_QUERY);
1590 Reference< XWindowPeer > xNext(e.NextFocus, UNO_QUERY);
1591 Reference< XControl > xNextControl = isInList(xNext);
1592 if (!xNextControl.is())
1594 m_xActiveControl = NULL;
1595 m_aDeactivationEvent.Call();
1599 //--------------------------------------------------------------------
1600 void SAL_CALL FmXFormController::mousePressed( const awt::MouseEvent& /*_rEvent*/ ) throw (RuntimeException)
1602 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mousePressed" );
1603 // not interested in
1606 //--------------------------------------------------------------------
1607 void SAL_CALL FmXFormController::mouseReleased( const awt::MouseEvent& /*_rEvent*/ ) throw (RuntimeException)
1609 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mouseReleased" );
1610 // not interested in
1613 //--------------------------------------------------------------------
1614 void SAL_CALL FmXFormController::mouseEntered( const awt::MouseEvent& _rEvent ) throw (RuntimeException)
1616 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mouseEntered" );
1617 m_pControlBorderManager->mouseEntered( _rEvent.Source );
1620 //--------------------------------------------------------------------
1621 void SAL_CALL FmXFormController::mouseExited( const awt::MouseEvent& _rEvent ) throw (RuntimeException)
1623 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mouseExited" );
1624 m_pControlBorderManager->mouseExited( _rEvent.Source );
1627 //--------------------------------------------------------------------
1628 void SAL_CALL FmXFormController::componentValidityChanged( const EventObject& _rSource ) throw (RuntimeException)
1630 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::componentValidityChanged" );
1631 Reference< XControl > xControl( findControl( m_aControls, Reference< XControlModel >( _rSource.Source, UNO_QUERY ), sal_False, sal_False ) );
1632 Reference< XValidatableFormComponent > xValidatable( _rSource.Source, UNO_QUERY );
1634 OSL_ENSURE( xControl.is() && xValidatable.is(), "FmXFormController::componentValidityChanged: huh?" );
1636 if ( xControl.is() && xValidatable.is() )
1637 m_pControlBorderManager->validityChanged( xControl, xValidatable );
1640 //--------------------------------------------------------------------
1641 void FmXFormController::setModel(const Reference< XTabControllerModel > & Model) throw( RuntimeException )
1643 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setModel" );
1644 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1645 ::osl::MutexGuard aGuard( m_aMutex );
1646 DBG_ASSERT(m_xTabController.is(), "FmXFormController::setModel : invalid aggregate !");
1650 // disconnect from the old model
1651 if (m_xModelAsIndex.is())
1653 if (m_bDBConnection)
1655 // we are currently working on the model
1656 EventObject aEvt(m_xModelAsIndex);
1657 unloaded(aEvt);
1660 Reference< XLoadable > xForm(m_xModelAsIndex, UNO_QUERY);
1661 if (xForm.is())
1662 xForm->removeLoadListener(this);
1664 Reference< XSQLErrorBroadcaster > xBroadcaster(m_xModelAsIndex, UNO_QUERY);
1665 if (xBroadcaster.is())
1666 xBroadcaster->removeSQLErrorListener(this);
1668 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(m_xModelAsIndex, UNO_QUERY);
1669 if (xParamBroadcaster.is())
1670 xParamBroadcaster->removeParameterListener(this);
1673 disposeAllFeaturesAndDispatchers();
1675 // set the new model wait for the load event
1676 if (m_xTabController.is())
1677 m_xTabController->setModel(Model);
1678 m_xModelAsIndex = Reference< XIndexAccess > (Model, UNO_QUERY);
1679 m_xModelAsManager = Reference< XEventAttacherManager > (Model, UNO_QUERY);
1681 // only if both ifaces exit, the controller will work successful
1682 if (!m_xModelAsIndex.is() || !m_xModelAsManager.is())
1684 m_xModelAsManager = NULL;
1685 m_xModelAsIndex = NULL;
1688 if (m_xModelAsIndex.is())
1690 m_aControllerFeatures.assign( this );
1692 // adding load and ui interaction listeners
1693 Reference< XLoadable > xForm(Model, UNO_QUERY);
1694 if (xForm.is())
1695 xForm->addLoadListener(this);
1697 Reference< XSQLErrorBroadcaster > xBroadcaster(Model, UNO_QUERY);
1698 if (xBroadcaster.is())
1699 xBroadcaster->addSQLErrorListener(this);
1701 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(Model, UNO_QUERY);
1702 if (xParamBroadcaster.is())
1703 xParamBroadcaster->addParameterListener(this);
1705 // well, is the database already loaded?
1706 // then we have to simulate a load event
1707 Reference< XLoadable > xCursor(m_xModelAsIndex, UNO_QUERY);
1708 if (xCursor.is() && xCursor->isLoaded())
1710 EventObject aEvt(xCursor);
1711 loaded(aEvt);
1714 Reference< XPropertySet > xModelProps( m_xModelAsIndex, UNO_QUERY );
1715 Reference< XPropertySetInfo > xPropInfo( xModelProps->getPropertySetInfo() );
1716 if ( xPropInfo.is()
1717 && xPropInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER )
1718 && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_FOCUS )
1719 && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_MOUSE )
1720 && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_INVALID )
1723 bool bEnableDynamicControlBorder = lcl_shouldUseDynamicControlBorder(
1724 xModelProps.get(), xModelProps->getPropertyValue( FM_PROP_DYNAMIC_CONTROL_BORDER ) );
1725 if ( bEnableDynamicControlBorder )
1726 m_pControlBorderManager->enableDynamicBorderColor();
1727 else
1728 m_pControlBorderManager->disableDynamicBorderColor();
1730 sal_Int32 nColor = 0;
1731 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_FOCUS ) >>= nColor )
1732 m_pControlBorderManager->setStatusColor( CONTROL_STATUS_FOCUSED, nColor );
1733 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_MOUSE ) >>= nColor )
1734 m_pControlBorderManager->setStatusColor( CONTROL_STATUS_MOUSE_HOVER, nColor );
1735 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_INVALID ) >>= nColor )
1736 m_pControlBorderManager->setStatusColor( CONTROL_STATUS_INVALID, nColor );
1740 catch( const Exception& )
1742 OSL_ENSURE( sal_False, "FmXFormController::setModel: caught an exception!" );
1746 //------------------------------------------------------------------------------
1747 Reference< XTabControllerModel > FmXFormController::getModel() throw( RuntimeException )
1749 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getModel" );
1750 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1751 DBG_ASSERT(m_xTabController.is(), "FmXFormController::getModel : invalid aggregate !");
1752 if (!m_xTabController.is())
1753 return Reference< XTabControllerModel > ();
1754 return m_xTabController->getModel();
1757 //------------------------------------------------------------------------------
1758 void FmXFormController::addToEventAttacher(const Reference< XControl > & xControl)
1760 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addToEventAttacher" );
1761 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1762 OSL_ENSURE( xControl.is(), "FmXFormController::addToEventAttacher: invalid control - how did you reach this?" );
1763 if ( !xControl.is() )
1764 return; /* throw IllegalArgumentException(); */
1766 // anmelden beim Eventattacher
1767 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1768 if (xComp.is() && m_xModelAsIndex.is())
1770 // Und die Position des ControlModel darin suchen
1771 sal_uInt32 nPos = m_xModelAsIndex->getCount();
1772 Reference< XFormComponent > xTemp;
1773 for( ; nPos; )
1775 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
1776 if ((XFormComponent*)xComp.get() == (XFormComponent*)xTemp.get())
1778 Reference< XInterface > xIfc(xControl, UNO_QUERY);
1779 m_xModelAsManager->attach( nPos, xIfc, makeAny(xControl) );
1780 break;
1786 //------------------------------------------------------------------------------
1787 void FmXFormController::removeFromEventAttacher(const Reference< XControl > & xControl)
1789 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeFromEventAttacher" );
1790 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1791 OSL_ENSURE( xControl.is(), "FmXFormController::removeFromEventAttacher: invalid control - how did you reach this?" );
1792 if ( !xControl.is() )
1793 return; /* throw IllegalArgumentException(); */
1795 // abmelden beim Eventattacher
1796 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1797 if ( xComp.is() && m_xModelAsIndex.is() )
1799 // Und die Position des ControlModel darin suchen
1800 sal_uInt32 nPos = m_xModelAsIndex->getCount();
1801 Reference< XFormComponent > xTemp;
1802 for( ; nPos; )
1804 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
1805 if ((XFormComponent*)xComp.get() == (XFormComponent*)xTemp.get())
1807 Reference< XInterface > xIfc(xControl, UNO_QUERY);
1808 m_xModelAsManager->detach( nPos, xIfc );
1809 break;
1815 //------------------------------------------------------------------------------
1816 void FmXFormController::setContainer(const Reference< XControlContainer > & xContainer) throw( RuntimeException )
1818 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setContainer" );
1819 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1820 Reference< XTabControllerModel > xTabModel(getModel());
1821 DBG_ASSERT(xTabModel.is() || !xContainer.is(), "No Model defined");
1822 // if we have a new container we need a model
1823 DBG_ASSERT(m_xTabController.is(), "FmXFormController::setContainer : invalid aggregate !");
1825 ::osl::MutexGuard aGuard( m_aMutex );
1826 Reference< XContainer > xCurrentContainer;
1827 if (m_xTabController.is())
1828 xCurrentContainer = Reference< XContainer > (m_xTabController->getContainer(), UNO_QUERY);
1829 if (xCurrentContainer.is())
1831 xCurrentContainer->removeContainerListener(this);
1833 if ( m_aTabActivationTimer.IsActive() )
1834 m_aTabActivationTimer.Stop();
1836 // clear the filter map
1837 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
1838 iter != m_aFilterControls.end(); ++iter)
1839 (*iter).first->removeTextListener(this);
1841 m_aFilterControls.clear();
1843 // einsammeln der Controls
1844 const Reference< XControl >* pControls = m_aControls.getConstArray();
1845 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
1846 while ( pControls != pControlsEnd )
1847 implControlRemoved( *pControls++, true );
1849 // Datenbank spezifische Dinge vornehmen
1850 if (m_bDBConnection && isListeningForChanges())
1851 stopListening();
1853 m_aControls.realloc( 0 );
1856 if (m_xTabController.is())
1857 m_xTabController->setContainer(xContainer);
1859 // Welche Controls gehoeren zum Container ?
1860 if (xContainer.is() && xTabModel.is())
1862 Sequence< Reference< XControlModel > > aModels = xTabModel->getControlModels();
1863 const Reference< XControlModel > * pModels = aModels.getConstArray();
1864 Sequence< Reference< XControl > > aAllControls = xContainer->getControls();
1866 sal_Int32 nCount = aModels.getLength();
1867 m_aControls = Sequence< Reference< XControl > >( nCount );
1868 Reference< XControl > * pControls = m_aControls.getArray();
1870 // einsammeln der Controls
1871 sal_Int32 i, j;
1872 for (i = 0, j = 0; i < nCount; ++i, ++pModels )
1874 Reference< XControl > xControl = findControl( aAllControls, *pModels, sal_False, sal_True );
1875 if ( xControl.is() )
1877 pControls[j++] = xControl;
1878 implControlInserted( xControl, true );
1882 // not every model had an associated control
1883 if (j != i)
1884 m_aControls.realloc(j);
1886 // am Container horchen
1887 Reference< XContainer > xNewContainer(xContainer, UNO_QUERY);
1888 if (xNewContainer.is())
1889 xNewContainer->addContainerListener(this);
1891 // Datenbank spezifische Dinge vornehmen
1892 if (m_bDBConnection)
1894 m_bLocked = determineLockState();
1895 setLocks();
1896 if (!isLocked())
1897 startListening();
1900 // befinden sich die Controls in der richtigen Reihenfolge
1901 m_bControlsSorted = sal_True;
1904 //------------------------------------------------------------------------------
1905 Reference< XControlContainer > FmXFormController::getContainer() throw( RuntimeException )
1907 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getContainer" );
1908 ::osl::MutexGuard aGuard( m_aMutex );
1909 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1910 DBG_ASSERT(m_xTabController.is(), "FmXFormController::getContainer : invalid aggregate !");
1911 if (!m_xTabController.is())
1912 return Reference< XControlContainer > ();
1913 return m_xTabController->getContainer();
1916 //------------------------------------------------------------------------------
1917 Sequence< Reference< XControl > > FmXFormController::getControls(void) throw( RuntimeException )
1919 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getControls" );
1920 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1921 ::osl::MutexGuard aGuard( m_aMutex );
1922 if (!m_bControlsSorted)
1924 Reference< XTabControllerModel > xModel = getModel();
1925 if (!xModel.is())
1926 return m_aControls;
1928 Sequence< Reference< XControlModel > > aControlModels = xModel->getControlModels();
1929 const Reference< XControlModel > * pModels = aControlModels.getConstArray();
1930 sal_Int32 nModels = aControlModels.getLength();
1932 Sequence< Reference< XControl > > aNewControls(nModels);
1934 Reference< XControl > * pControls = aNewControls.getArray();
1935 Reference< XControl > xControl;
1937 // Umsortieren der Controls entsprechend der TabReihenfolge
1938 sal_Int32 j = 0;
1939 for (sal_Int32 i = 0; i < nModels; ++i, ++pModels )
1941 xControl = findControl( m_aControls, *pModels, sal_True, sal_True );
1942 if ( xControl.is() )
1943 pControls[j++] = xControl;
1946 // not every model had an associated control
1947 if ( j != nModels )
1948 aNewControls.realloc( j );
1950 m_aControls = aNewControls;
1951 m_bControlsSorted = sal_True;
1953 return m_aControls;
1956 //------------------------------------------------------------------------------
1957 void FmXFormController::autoTabOrder() throw( RuntimeException )
1959 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::autoTabOrder" );
1960 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1961 ::osl::MutexGuard aGuard( m_aMutex );
1962 DBG_ASSERT(m_xTabController.is(), "FmXFormController::autoTabOrder : invalid aggregate !");
1963 if (m_xTabController.is())
1964 m_xTabController->autoTabOrder();
1967 //------------------------------------------------------------------------------
1968 void FmXFormController::activateTabOrder() throw( RuntimeException )
1970 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::activateTabOrder" );
1971 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1972 ::osl::MutexGuard aGuard( m_aMutex );
1973 DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateTabOrder : invalid aggregate !");
1974 if (m_xTabController.is())
1975 m_xTabController->activateTabOrder();
1978 //------------------------------------------------------------------------------
1979 void FmXFormController::setControlLock(const Reference< XControl > & xControl)
1981 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setControlLock" );
1982 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1983 sal_Bool bLocked = isLocked();
1985 // es wird gelockt
1986 // a.) wenn der ganze Datensatz gesperrt ist
1987 // b.) wenn das zugehoerige Feld gespeert ist
1988 Reference< XBoundControl > xBound(xControl, UNO_QUERY);
1989 if (xBound.is() && (( (bLocked && bLocked != xBound->getLock()) ||
1990 !bLocked))) // beim entlocken immer einzelne Felder ueberprüfen
1992 // gibt es eine Datenquelle
1993 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1994 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1996 // wie sieht mit den Properties ReadOnly und Enable aus
1997 sal_Bool bTouch = sal_True;
1998 if (::comphelper::hasProperty(FM_PROP_ENABLED, xSet))
1999 bTouch = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ENABLED));
2000 if (::comphelper::hasProperty(FM_PROP_READONLY, xSet))
2001 bTouch = !::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_READONLY));
2003 if (bTouch)
2005 Reference< XPropertySet > xField;
2006 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2007 if (xField.is())
2009 if (bLocked)
2010 xBound->setLock(bLocked);
2011 else
2015 Any aVal = xField->getPropertyValue(FM_PROP_ISREADONLY);
2016 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2017 xBound->setLock(sal_True);
2018 else
2019 xBound->setLock(bLocked);
2021 catch(...)
2032 //------------------------------------------------------------------------------
2033 void FmXFormController::setLocks()
2035 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setLocks" );
2036 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2037 // alle Controls, die mit einer Datenquelle verbunden sind locken/unlocken
2038 const Reference< XControl >* pControls = m_aControls.getConstArray();
2039 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2040 while ( pControls != pControlsEnd )
2041 setControlLock( *pControls++ );
2044 //------------------------------------------------------------------------------
2045 namespace
2047 bool lcl_shouldListenForModifications( const Reference< XControl >& _rxControl, const Reference< XPropertyChangeListener >& _rxBoundFieldListener )
2049 bool bShould = false;
2051 Reference< XBoundComponent > xBound( _rxControl, UNO_QUERY );
2052 if ( xBound.is() )
2054 bShould = true;
2056 else if ( _rxControl.is() )
2058 Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
2059 if ( xModelProps.is() && ::comphelper::hasProperty( FM_PROP_BOUNDFIELD, xModelProps ) )
2061 Reference< XPropertySet > xField;
2062 xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
2063 bShould = xField.is();
2065 if ( !bShould && _rxBoundFieldListener.is() )
2066 xModelProps->addPropertyChangeListener( FM_PROP_BOUNDFIELD, _rxBoundFieldListener );
2070 return bShould;
2074 //------------------------------------------------------------------------------
2075 void FmXFormController::startControlModifyListening(const Reference< XControl > & xControl)
2077 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startControlModifyListening" );
2078 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2080 bool bModifyListening = lcl_shouldListenForModifications( xControl, this );
2082 // artificial while
2083 while ( bModifyListening )
2085 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2086 if (xMod.is())
2088 xMod->addModifyListener(this);
2089 break;
2092 // alle die Text um vorzeitig ein modified zu erkennen
2093 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2094 if (xText.is())
2096 xText->addTextListener(this);
2097 break;
2100 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2101 if (xBox.is())
2103 xBox->addItemListener(this);
2104 break;
2107 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2108 if (xCbBox.is())
2110 xCbBox->addItemListener(this);
2111 break;
2114 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2115 if (xListBox.is())
2117 xListBox->addItemListener(this);
2118 break;
2120 break;
2124 //------------------------------------------------------------------------------
2125 void FmXFormController::stopControlModifyListening(const Reference< XControl > & xControl)
2127 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopControlModifyListening" );
2128 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2130 bool bModifyListening = lcl_shouldListenForModifications( xControl, NULL );
2132 // kuenstliches while
2133 while (bModifyListening)
2135 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2136 if (xMod.is())
2138 xMod->removeModifyListener(this);
2139 break;
2141 // alle die Text um vorzeitig ein modified zu erkennen
2142 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2143 if (xText.is())
2145 xText->removeTextListener(this);
2146 break;
2149 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2150 if (xBox.is())
2152 xBox->removeItemListener(this);
2153 break;
2156 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2157 if (xCbBox.is())
2159 xCbBox->removeItemListener(this);
2160 break;
2163 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2164 if (xListBox.is())
2166 xListBox->removeItemListener(this);
2167 break;
2169 break;
2173 //------------------------------------------------------------------------------
2174 void FmXFormController::startListening()
2176 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startListening" );
2177 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2178 m_bModified = sal_False;
2180 // jetzt anmelden bei gebundenen feldern
2181 const Reference< XControl >* pControls = m_aControls.getConstArray();
2182 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2183 while ( pControls != pControlsEnd )
2184 startControlModifyListening( *pControls++ );
2187 //------------------------------------------------------------------------------
2188 void FmXFormController::stopListening()
2190 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopListening" );
2191 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2192 m_bModified = sal_False;
2194 // jetzt anmelden bei gebundenen feldern
2195 const Reference< XControl >* pControls = m_aControls.getConstArray();
2196 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2197 while ( pControls != pControlsEnd )
2198 stopControlModifyListening( *pControls++ );
2202 //------------------------------------------------------------------------------
2203 Reference< XControl > FmXFormController::findControl(Sequence< Reference< XControl > >& _rControls, const Reference< XControlModel > & xCtrlModel ,sal_Bool _bRemove,sal_Bool _bOverWrite) const
2205 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::findControl" );
2206 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2207 DBG_ASSERT( xCtrlModel.is(), "findControl - welches ?!" );
2209 Reference< XControl >* pControls = _rControls.getArray();
2210 Reference< XControlModel > xModel;
2211 for ( sal_Int32 i = 0, nCount = _rControls.getLength(); i < nCount; ++i, ++pControls )
2213 if ( pControls->is() )
2215 xModel = (*pControls)->getModel();
2216 if ( xModel.get() == xCtrlModel.get() )
2218 Reference< XControl > xControl( *pControls );
2219 if ( _bRemove )
2220 ::comphelper::removeElementAt( _rControls, i );
2221 else if ( _bOverWrite )
2222 *pControls = Reference< XControl >();
2223 return xControl;
2227 return Reference< XControl > ();
2230 //------------------------------------------------------------------------------
2231 void FmXFormController::implControlInserted( const Reference< XControl>& _rxControl, bool _bAddToEventAttacher )
2233 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implControlInserted" );
2234 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2235 if ( xWindow.is() )
2237 xWindow->addFocusListener( this );
2238 xWindow->addMouseListener( this );
2240 if ( _bAddToEventAttacher )
2241 addToEventAttacher( _rxControl );
2244 // add a dispatch interceptor to the control (if supported)
2245 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY );
2246 if ( xInterception.is() )
2247 createInterceptor( xInterception );
2249 if ( _rxControl.is() )
2251 Reference< XControlModel > xModel( _rxControl->getModel() );
2253 // we want to know about the reset of the the model of our controls
2254 // (for correctly resetting m_bModified)
2255 Reference< XReset > xReset( xModel, UNO_QUERY );
2256 if ( xReset.is() )
2257 xReset->addResetListener( this );
2259 // and we want to know about the validity, to visually indicate it
2260 Reference< XValidatableFormComponent > xValidatable( xModel, UNO_QUERY );
2261 if ( xValidatable.is() )
2263 xValidatable->addFormComponentValidityListener( this );
2264 m_pControlBorderManager->validityChanged( _rxControl, xValidatable );
2270 //------------------------------------------------------------------------------
2271 void FmXFormController::implControlRemoved( const Reference< XControl>& _rxControl, bool _bRemoveFromEventAttacher )
2273 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implControlRemoved" );
2274 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2275 if ( xWindow.is() )
2277 xWindow->removeFocusListener( this );
2278 xWindow->removeMouseListener( this );
2280 if ( _bRemoveFromEventAttacher )
2281 removeFromEventAttacher( _rxControl );
2284 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY);
2285 if ( xInterception.is() )
2286 deleteInterceptor( xInterception );
2288 if ( _rxControl.is() )
2290 Reference< XControlModel > xModel( _rxControl->getModel() );
2292 Reference< XReset > xReset( xModel, UNO_QUERY );
2293 if ( xReset.is() )
2294 xReset->removeResetListener( this );
2296 Reference< XValidatableFormComponent > xValidatable( xModel, UNO_QUERY );
2297 if ( xValidatable.is() )
2298 xValidatable->removeFormComponentValidityListener( this );
2302 //------------------------------------------------------------------------------
2303 void FmXFormController::implSetCurrentControl( const Reference< XControl >& _rxControl )
2305 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implSetCurrentControl" );
2306 if ( m_xCurrentControl.get() == _rxControl.get() )
2307 return;
2309 Reference< XGridControl > xGridControl( m_xCurrentControl, UNO_QUERY );
2310 if ( xGridControl.is() )
2311 xGridControl->removeGridControlListener( this );
2313 m_xCurrentControl = _rxControl;
2315 xGridControl.set( m_xCurrentControl, UNO_QUERY );
2316 if ( xGridControl.is() )
2317 xGridControl->addGridControlListener( this );
2320 //------------------------------------------------------------------------------
2321 void FmXFormController::insertControl(const Reference< XControl > & xControl)
2323 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::insertControl" );
2324 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2325 m_bControlsSorted = sal_False;
2326 m_aControls.realloc(m_aControls.getLength() + 1);
2327 m_aControls.getArray()[m_aControls.getLength() - 1] = xControl;
2329 if ( m_pColumnInfoCache.get() )
2330 m_pColumnInfoCache->deinitializeControls();
2332 implControlInserted( xControl, m_bAttachEvents );
2334 if (m_bDBConnection && !m_bFiltering)
2335 setControlLock(xControl);
2337 if (isListeningForChanges() && m_bAttachEvents)
2338 startControlModifyListening( xControl );
2341 //------------------------------------------------------------------------------
2342 void FmXFormController::removeControl(const Reference< XControl > & xControl)
2344 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeControl" );
2345 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2346 const Reference< XControl >* pControls = m_aControls.getConstArray();
2347 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2348 while ( pControls != pControlsEnd )
2350 if ( xControl.get() == (*pControls++).get() )
2352 ::comphelper::removeElementAt( m_aControls, pControls - m_aControls.getConstArray() - 1 );
2353 break;
2357 if (m_aFilterControls.size())
2359 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2360 FmFilterControls::iterator iter = m_aFilterControls.find(xText);
2361 if (iter != m_aFilterControls.end())
2362 m_aFilterControls.erase(iter);
2365 implControlRemoved( xControl, m_bDetachEvents );
2367 if ( isListeningForChanges() && m_bDetachEvents )
2368 stopControlModifyListening( xControl );
2371 // XLoadListener
2372 //------------------------------------------------------------------------------
2373 void FmXFormController::loaded(const EventObject& rEvent) throw( RuntimeException )
2375 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::loaded" );
2376 OSL_ENSURE( rEvent.Source == m_xModelAsIndex, "FmXFormController::loaded: where did this come from?" );
2378 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2379 ::osl::MutexGuard aGuard( m_aMutex );
2380 Reference< XRowSet > xForm(rEvent.Source, UNO_QUERY);
2381 // do we have a connected data source
2382 OStaticDataAccessTools aStaticTools;
2383 if (xForm.is() && aStaticTools.getRowSetConnection(xForm).is())
2385 Reference< XPropertySet > xSet(xForm, UNO_QUERY);
2386 if (xSet.is())
2388 Any aVal = xSet->getPropertyValue(FM_PROP_CYCLE);
2389 sal_Int32 aVal2 = 0;
2390 ::cppu::enum2int(aVal2,aVal);
2391 m_bCycle = !aVal.hasValue() || aVal2 == TabulatorCycle_RECORDS;
2392 m_bCanUpdate = aStaticTools.canUpdate(xSet);
2393 m_bCanInsert = aStaticTools.canInsert(xSet);
2394 m_bCurrentRecordModified = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED));
2395 m_bCurrentRecordNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
2397 startFormListening( xSet, sal_False );
2399 // set the locks for the current controls
2400 if (getContainer().is())
2402 m_aLoadEvent.Call();
2405 else
2407 m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2408 m_bCurrentRecordModified = sal_False;
2409 m_bCurrentRecordNew = sal_False;
2410 m_bLocked = sal_False;
2412 m_bDBConnection = sal_True;
2414 else
2416 m_bDBConnection = sal_False;
2417 m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2418 m_bCurrentRecordModified = sal_False;
2419 m_bCurrentRecordNew = sal_False;
2420 m_bLocked = sal_False;
2423 Reference< XColumnsSupplier > xFormColumns( xForm, UNO_QUERY );
2424 m_pColumnInfoCache.reset( xFormColumns.is() ? new ColumnInfoCache( xFormColumns ) : NULL );
2426 updateAllDispatchers();
2429 //------------------------------------------------------------------------------
2430 void FmXFormController::updateAllDispatchers() const
2432 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::updateAllDispatchers" );
2433 ::std::for_each(
2434 m_aFeatureDispatchers.begin(),
2435 m_aFeatureDispatchers.end(),
2436 ::std::compose1(
2437 UpdateAllListeners(),
2438 ::std::select2nd< DispatcherContainer::value_type >()
2443 //------------------------------------------------------------------------------
2444 IMPL_LINK(FmXFormController, OnLoad, void*, EMPTYARG)
2446 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2447 m_bLocked = determineLockState();
2449 setLocks();
2451 if (!m_bLocked)
2452 startListening();
2454 // just one exception toggle the auto values
2455 if (m_bCurrentRecordNew)
2456 toggleAutoFields(sal_True);
2458 return 1L;
2461 //------------------------------------------------------------------------------
2462 void FmXFormController::unloaded(const EventObject& /*rEvent*/) throw( RuntimeException )
2464 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::unloaded" );
2465 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2466 updateAllDispatchers();
2469 //------------------------------------------------------------------------------
2470 void FmXFormController::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2472 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::reloading" );
2473 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2474 ::osl::MutexGuard aGuard( m_aMutex );
2475 // do the same like in unloading
2476 // just one exception toggle the auto values
2477 m_aToggleEvent.CancelPendingCall();
2478 unload();
2481 //------------------------------------------------------------------------------
2482 void FmXFormController::reloaded(const EventObject& aEvent) throw( RuntimeException )
2484 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::reloaded" );
2485 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2486 loaded(aEvent);
2489 //------------------------------------------------------------------------------
2490 void FmXFormController::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2492 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::unloading" );
2493 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2494 unload();
2497 //------------------------------------------------------------------------------
2498 void FmXFormController::unload() throw( RuntimeException )
2500 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::unload" );
2501 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2502 ::osl::MutexGuard aGuard( m_aMutex );
2504 m_aLoadEvent.CancelPendingCall();
2506 // be sure not to have autofields
2507 if (m_bCurrentRecordNew)
2508 toggleAutoFields(sal_False);
2510 // remove bound field listing again
2511 removeBoundFieldListener();
2513 if (m_bDBConnection && isListeningForChanges())
2514 stopListening();
2516 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
2517 if ( m_bDBConnection && xSet.is() )
2518 stopFormListening( xSet, sal_False );
2520 m_bDBConnection = sal_False;
2521 m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2522 m_bCurrentRecordModified = m_bCurrentRecordNew = m_bLocked = sal_False;
2524 m_pColumnInfoCache.reset( NULL );
2527 // -----------------------------------------------------------------------------
2528 void FmXFormController::removeBoundFieldListener()
2530 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeBoundFieldListener" );
2531 const Reference< XControl >* pControls = m_aControls.getConstArray();
2532 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2533 while ( pControls != pControlsEnd )
2535 Reference< XPropertySet > xProp( *pControls++, UNO_QUERY );
2536 if ( xProp.is() )
2537 xProp->removePropertyChangeListener( FM_PROP_BOUNDFIELD, this );
2541 //------------------------------------------------------------------------------
2542 void FmXFormController::startFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
2544 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startFormListening" );
2547 if ( m_bCanInsert || m_bCanUpdate ) // form can be modified
2549 _rxForm->addPropertyChangeListener( FM_PROP_ISNEW, this );
2550 _rxForm->addPropertyChangeListener( FM_PROP_ISMODIFIED, this );
2552 if ( !_bPropertiesOnly )
2554 // set the Listener for UI interaction
2555 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2556 if ( xApprove.is() )
2557 xApprove->addRowSetApproveListener( this );
2559 // listener for row set changes
2560 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2561 if ( xRowSet.is() )
2562 xRowSet->addRowSetListener( this );
2566 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2567 if ( xInfo.is() && xInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER ) )
2568 _rxForm->addPropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER, this );
2570 catch( const Exception& )
2572 OSL_ENSURE( sal_False, "FmXFormController::startFormListening: caught an exception!" );
2576 //------------------------------------------------------------------------------
2577 void FmXFormController::stopFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
2579 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopFormListening" );
2582 if ( m_bCanInsert || m_bCanUpdate )
2584 _rxForm->removePropertyChangeListener( FM_PROP_ISNEW, this );
2585 _rxForm->removePropertyChangeListener( FM_PROP_ISMODIFIED, this );
2587 if ( !_bPropertiesOnly )
2589 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2590 if (xApprove.is())
2591 xApprove->removeRowSetApproveListener(this);
2593 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2594 if ( xRowSet.is() )
2595 xRowSet->removeRowSetListener( this );
2599 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2600 if ( xInfo.is() && xInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER ) )
2601 _rxForm->removePropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER, this );
2603 catch( const Exception& )
2605 OSL_ENSURE( sal_False, "FmXFormController::stopFormListening: caught an exception!" );
2609 // com::sun::star::sdbc::XRowSetListener
2610 //------------------------------------------------------------------------------
2611 void FmXFormController::cursorMoved(const EventObject& /*event*/) throw( RuntimeException )
2613 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::cursorMoved" );
2614 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2615 // toggle the locking ?
2616 if (m_bLocked != determineLockState())
2618 ::osl::MutexGuard aGuard( m_aMutex );
2619 m_bLocked = !m_bLocked;
2620 setLocks();
2621 if (isListeningForChanges())
2622 startListening();
2623 else
2624 stopListening();
2627 // neither the current control nor the current record are modified anymore
2628 m_bCurrentRecordModified = m_bModified = sal_False;
2631 //------------------------------------------------------------------------------
2632 void FmXFormController::rowChanged(const EventObject& /*event*/) throw( RuntimeException )
2634 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::rowChanged" );
2635 // not interested in ...
2637 //------------------------------------------------------------------------------
2638 void FmXFormController::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException )
2640 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::rowSetChanged" );
2641 // not interested in ...
2645 // XContainerListener
2646 //------------------------------------------------------------------------------
2647 void SAL_CALL FmXFormController::elementInserted(const ContainerEvent& evt) throw( RuntimeException )
2649 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::elementInserted" );
2650 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2651 Reference< XControl > xControl;
2652 evt.Element >>= xControl;
2653 if (!xControl.is())
2654 return;
2656 ::osl::MutexGuard aGuard( m_aMutex );
2657 Reference< XFormComponent > xModel(xControl->getModel(), UNO_QUERY);
2658 if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2660 insertControl(xControl);
2662 if ( m_aTabActivationTimer.IsActive() )
2663 m_aTabActivationTimer.Stop();
2665 m_aTabActivationTimer.Start();
2667 // are we in filtermode and a XModeSelector has inserted an element
2668 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2670 xModel = Reference< XFormComponent > (evt.Source, UNO_QUERY);
2671 if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2673 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2674 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2676 // does the model use a bound field ?
2677 Reference< XPropertySet > xField;
2678 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2680 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2681 // may we filter the field?
2682 if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
2683 ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2685 m_aFilterControls[xText] = xField;
2686 xText->addTextListener(this);
2693 //------------------------------------------------------------------------------
2694 void SAL_CALL FmXFormController::elementReplaced(const ContainerEvent& evt) throw( RuntimeException )
2696 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::elementReplaced" );
2697 // simulate an elementRemoved
2698 ContainerEvent aRemoveEvent( evt );
2699 aRemoveEvent.Element = evt.ReplacedElement;
2700 aRemoveEvent.ReplacedElement = Any();
2701 elementRemoved( aRemoveEvent );
2703 // simulate an elementInserted
2704 ContainerEvent aInsertEvent( evt );
2705 aInsertEvent.ReplacedElement = Any();
2706 elementInserted( aInsertEvent );
2709 //------------------------------------------------------------------------------
2710 void SAL_CALL FmXFormController::elementRemoved(const ContainerEvent& evt) throw( RuntimeException )
2712 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::elementRemoved" );
2713 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2714 ::osl::MutexGuard aGuard( m_aMutex );
2716 Reference< XControl > xControl;
2717 evt.Element >>= xControl;
2718 if (!xControl.is())
2719 return;
2721 Reference< XFormComponent > xModel(xControl->getModel(), UNO_QUERY);
2722 if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2724 removeControl(xControl);
2725 // TabOrder nicht neu berechnen, da das intern schon funktionieren muß!
2727 // are we in filtermode and a XModeSelector has inserted an element
2728 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2730 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2731 FmFilterControls::iterator iter = m_aFilterControls.find(xText);
2732 if (iter != m_aFilterControls.end())
2733 m_aFilterControls.erase(iter);
2737 //------------------------------------------------------------------------------
2738 Reference< XControl > FmXFormController::isInList(const Reference< XWindowPeer > & xPeer) const
2740 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::isInList" );
2741 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2742 const Reference< XControl >* pControls = m_aControls.getConstArray();
2744 sal_uInt32 nCtrls = m_aControls.getLength();
2745 for ( sal_uInt32 n = 0; n < nCtrls && xPeer.is(); ++n, ++pControls )
2747 if ( pControls->is() )
2749 Reference< XVclWindowPeer > xCtrlPeer( (*pControls)->getPeer(), UNO_QUERY);
2750 if ( ( xCtrlPeer.get() == xPeer.get() ) || xCtrlPeer->isChild( xPeer ) )
2751 return *pControls;
2754 return Reference< XControl > ();
2757 //------------------------------------------------------------------------------
2758 void FmXFormController::activateFirst() throw( RuntimeException )
2760 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::activateFirst" );
2761 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2762 ::osl::MutexGuard aGuard( m_aMutex );
2763 DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateFirst : invalid aggregate !");
2764 if (m_xTabController.is())
2765 m_xTabController->activateFirst();
2768 //------------------------------------------------------------------------------
2769 void FmXFormController::activateLast() throw( RuntimeException )
2771 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::activateLast" );
2772 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2773 ::osl::MutexGuard aGuard( m_aMutex );
2774 DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateLast : invalid aggregate !");
2775 if (m_xTabController.is())
2776 m_xTabController->activateLast();
2779 // XFormController
2780 //------------------------------------------------------------------------------
2781 Reference< XControl> SAL_CALL FmXFormController::getCurrentControl(void) throw( RuntimeException )
2783 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getCurrentControl" );
2784 ::osl::MutexGuard aGuard( m_aMutex );
2785 return m_xCurrentControl;
2788 //------------------------------------------------------------------------------
2789 void SAL_CALL FmXFormController::addActivateListener(const Reference< XFormControllerListener > & l) throw( RuntimeException )
2791 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addActivateListener" );
2792 ::osl::MutexGuard aGuard( m_aMutex );
2793 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2794 m_aActivateListeners.addInterface(l);
2796 //------------------------------------------------------------------------------
2797 void SAL_CALL FmXFormController::removeActivateListener(const Reference< XFormControllerListener > & l) throw( RuntimeException )
2799 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeActivateListener" );
2800 ::osl::MutexGuard aGuard( m_aMutex );
2801 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2802 m_aActivateListeners.removeInterface(l);
2805 //------------------------------------------------------------------------------
2806 void FmXFormController::setFilter(::std::vector<FmFieldInfo>& rFieldInfos)
2808 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setFilter" );
2809 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2810 // create the composer
2811 Reference< XRowSet > xForm(m_xModelAsIndex, UNO_QUERY);
2812 Reference< XConnection > xConnection(OStaticDataAccessTools().getRowSetConnection(xForm));
2813 if (xForm.is())
2817 Reference< XMultiServiceFactory > xFactory( xConnection, UNO_QUERY_THROW );
2818 m_xComposer.set(
2819 xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
2820 UNO_QUERY_THROW );
2822 Reference< XPropertySet > xSet( xForm, UNO_QUERY );
2823 ::rtl::OUString sStatement = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_ACTIVECOMMAND ) );
2824 ::rtl::OUString sFilter = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_FILTER ) );
2825 m_xComposer->setElementaryQuery( sStatement );
2826 m_xComposer->setFilter( sFilter );
2828 catch( const Exception& )
2830 DBG_UNHANDLED_EXCEPTION();
2834 if (m_xComposer.is())
2836 Sequence < PropertyValue> aLevel;
2837 Sequence< Sequence < PropertyValue > > aFilterRows = m_xComposer->getStructuredFilter();
2839 // ok, we recieve the list of filters as sequence of fieldnames, value
2840 // now we have to transform the fieldname into UI names, that could be a label of the field or
2841 // a aliasname or the fieldname itself
2843 // first adjust the field names if necessary
2844 Reference< XNameAccess > xQueryColumns =
2845 Reference< XColumnsSupplier >( m_xComposer, UNO_QUERY_THROW )->getColumns();
2847 for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
2848 iter != rFieldInfos.end(); iter++)
2850 if ( xQueryColumns->hasByName((*iter).aFieldName) )
2852 if ( (xQueryColumns->getByName((*iter).aFieldName) >>= (*iter).xField) && (*iter).xField.is() )
2853 (*iter).xField->getPropertyValue(FM_PROP_REALNAME) >>= (*iter).aFieldName;
2857 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
2858 // now transfer the filters into Value/TextComponent pairs
2859 ::comphelper::UStringMixEqual aCompare(xMetaData->storesMixedCaseQuotedIdentifiers());
2861 // need to parse criteria localized
2862 OStaticDataAccessTools aStaticTools;
2863 Reference< XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
2864 Reference< XNumberFormatter> xFormatter(m_xORB
2865 ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
2866 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
2867 Locale aAppLocale = Application::GetSettings().GetUILocale();
2868 LocaleDataWrapper aLocaleWrapper(m_xORB,aAppLocale);
2870 // retrieving the filter
2871 const Sequence < PropertyValue >* pRow = aFilterRows.getConstArray();
2872 for (sal_Int32 i = 0, nLen = aFilterRows.getLength(); i < nLen; ++i)
2874 FmFilterRow aRow;
2876 // search a field for the given name
2877 const PropertyValue* pRefValues = pRow[i].getConstArray();
2878 for (sal_Int32 j = 0, nLen1 = pRow[i].getLength(); j < nLen1; j++)
2880 // look for the text component
2881 Reference< XPropertySet > xField;
2884 Reference< XPropertySet > xSet;
2885 ::rtl::OUString aRealName;
2887 // first look with the given name
2888 if (xQueryColumns->hasByName(pRefValues[j].Name))
2890 xQueryColumns->getByName(pRefValues[j].Name) >>= xSet;
2892 // get the RealName
2893 xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
2895 // compare the condition field name and the RealName
2896 if (aCompare(aRealName, pRefValues[j].Name))
2897 xField = xSet;
2899 if (!xField.is())
2901 // no we have to check every column to find the realname
2902 Reference< XIndexAccess > xColumnsByIndex(xQueryColumns, UNO_QUERY);
2903 for (sal_Int32 n = 0, nCount = xColumnsByIndex->getCount(); n < nCount; n++)
2905 xColumnsByIndex->getByIndex(n) >>= xSet;
2906 xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
2907 if (aCompare(aRealName, pRefValues[j].Name))
2909 // get the column by its alias
2910 xField = xSet;
2911 break;
2915 if (!xField.is())
2916 continue;
2918 catch (const Exception&)
2920 continue;
2923 // find the text component
2924 for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
2925 iter != rFieldInfos.end(); iter++)
2927 // we found the field so insert a new entry to the filter row
2928 if ((*iter).xField == xField)
2930 // do we already have the control ?
2931 if (aRow.find((*iter).xText) != aRow.end())
2933 ::rtl::OUString aCompText = aRow[(*iter).xText];
2934 aCompText += ::rtl::OUString::createFromAscii(" ");
2935 ::rtl::OString aVal = m_xParser->getContext().getIntlKeywordAscii(OParseContext::KEY_AND);
2936 aCompText += ::rtl::OUString(aVal.getStr(),aVal.getLength(),RTL_TEXTENCODING_ASCII_US);
2937 aCompText += ::rtl::OUString::createFromAscii(" ");
2938 aCompText += ::comphelper::getString(pRefValues[j].Value);
2939 aRow[(*iter).xText] = aCompText;
2941 else
2943 ::rtl::OUString sPredicate,sErrorMsg;
2944 pRefValues[j].Value >>= sPredicate;
2945 ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(sErrorMsg, sPredicate, xFormatter, xField);
2946 if ( xParseNode.is() )
2948 ::rtl::OUString sCriteria;
2949 xParseNode->parseNodeToPredicateStr( sCriteria
2950 ,xConnection
2951 ,xFormatter
2952 ,xField
2953 ,aAppLocale
2954 ,(sal_Char)aLocaleWrapper.getNumDecimalSep().GetChar(0)
2955 ,getParseContext());
2956 aRow[(*iter).xText] = sCriteria;
2959 break;
2964 if (aRow.empty())
2965 continue;
2967 m_aFilters.push_back(aRow);
2971 // now set the filter controls
2972 for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
2973 iter != rFieldInfos.end(); iter++)
2975 m_aFilterControls[(*iter).xText] = (*iter).xField;
2978 // add an empty row
2979 m_aFilters.push_back(FmFilterRow());
2982 //------------------------------------------------------------------------------
2983 void FmXFormController::startFiltering()
2985 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startFiltering" );
2986 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2988 OStaticDataAccessTools aStaticTools;
2989 Reference< XConnection > xConnection( aStaticTools.getRowSetConnection( Reference< XRowSet >( m_xModelAsIndex, UNO_QUERY ) ) );
2990 if ( !xConnection.is() )
2991 // nothing to do - can't filter a form which is not connected
2992 // 98023 - 19.03.2002 - fs@openoffice.org
2993 return;
2995 // stop listening for controls
2996 if (isListeningForChanges())
2997 stopListening();
2999 m_bFiltering = sal_True;
3001 // as we don't want new controls to be attached to the scripting environment
3002 // we change attach flags
3003 m_bAttachEvents = sal_False;
3005 // Austauschen der Kontrols fuer das aktuelle Formular
3006 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3007 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
3008 sal_Int32 nControlCount = aControlsCopy.getLength();
3010 // the control we have to activate after replacement
3011 Reference< XDatabaseMetaData > xMetaData(xConnection->getMetaData());
3012 Reference< XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats(xConnection, sal_True);
3013 Reference< XNumberFormatter > xFormatter(m_xORB
3014 ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
3015 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3017 // structure for storing the field info
3018 ::std::vector<FmFieldInfo> aFieldInfos;
3020 for (sal_Int32 i = nControlCount; i > 0;)
3022 Reference< XControl > xControl = pControls[--i];
3023 if (xControl.is())
3025 // no events for the control anymore
3026 removeFromEventAttacher(xControl);
3028 // do we have a mode selector
3029 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3030 if (xSelector.is())
3032 xSelector->setMode(FILTER_MODE);
3034 // listening for new controls of the selector
3035 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3036 if (xContainer.is())
3037 xContainer->addContainerListener(this);
3039 Reference< XEnumerationAccess > xElementAccess(xSelector, UNO_QUERY);
3040 if (xElementAccess.is())
3042 Reference< XEnumeration > xEnumeration(xElementAccess->createEnumeration());
3043 Reference< XControl > xSubControl;
3044 while (xEnumeration->hasMoreElements())
3046 xEnumeration->nextElement() >>= xSubControl;
3047 if (xSubControl.is())
3049 Reference< XPropertySet > xSet(xSubControl->getModel(), UNO_QUERY);
3050 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
3052 // does the model use a bound field ?
3053 Reference< XPropertySet > xField;
3054 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3056 Reference< XTextComponent > xText(xSubControl, UNO_QUERY);
3057 // may we filter the field?
3058 if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
3059 ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
3061 aFieldInfos.push_back(FmFieldInfo(xField, xText));
3062 xText->addTextListener(this);
3068 continue;
3071 Reference< XPropertySet > xModel( xControl->getModel(), UNO_QUERY );
3072 if (xModel.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xModel))
3074 // does the model use a bound field ?
3075 Any aVal = xModel->getPropertyValue(FM_PROP_BOUNDFIELD);
3076 Reference< XPropertySet > xField;
3077 aVal >>= xField;
3079 // may we filter the field?
3081 if ( xField.is()
3082 && ::comphelper::hasProperty( FM_PROP_SEARCHABLE, xField )
3083 && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_SEARCHABLE ) )
3086 // create a filter control
3087 Sequence< Any > aCreationArgs( 3 );
3088 aCreationArgs[ 0 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "MessageParent" ), makeAny( VCLUnoHelper::GetInterface( getDialogParentWindow() ) ) );
3089 aCreationArgs[ 1 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "NumberFormatter" ), makeAny( xFormatter ) );
3090 aCreationArgs[ 2 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "ControlModel" ), makeAny( xModel ) );
3091 Reference< XControl > xFilterControl(
3092 m_xORB->createInstanceWithArguments(
3093 ::rtl::OUString::createFromAscii( "com.sun.star.form.control.FilterControl" ),
3094 aCreationArgs
3096 UNO_QUERY
3098 DBG_ASSERT( xFilterControl.is(), "FmXFormController::startFiltering: could not create a filter control!" );
3100 if ( replaceControl( xControl, xFilterControl ) )
3102 Reference< XTextComponent > xFilterText( xFilterControl, UNO_QUERY );
3103 aFieldInfos.push_back( FmFieldInfo( xField, xFilterText ) );
3104 xFilterText->addTextListener(this);
3108 else
3110 // abmelden vom EventManager
3115 // we have all filter controls now, so the next step is to read the filters from the form
3116 // resolve all aliases and set the current filter to the according structure
3117 setFilter(aFieldInfos);
3119 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3120 if ( xSet.is() )
3121 stopFormListening( xSet, sal_True );
3123 impl_setTextOnAllFilter_throw();
3125 // lock all controls which are not used for filtering
3126 m_bLocked = determineLockState();
3127 setLocks();
3128 m_bAttachEvents = sal_True;
3131 //------------------------------------------------------------------------------
3132 void FmXFormController::stopFiltering()
3134 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopFiltering" );
3135 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3136 if ( !m_bFiltering ) // #104693# OJ
3137 { // nothing to do
3138 return;
3141 m_bFiltering = sal_False;
3142 m_bDetachEvents = sal_False;
3144 ::comphelper::disposeComponent(m_xComposer);
3146 // Austauschen der Kontrols fuer das aktuelle Formular
3147 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3148 const Reference< XControl > * pControls = aControlsCopy.getConstArray();
3149 sal_Int32 nControlCount = aControlsCopy.getLength();
3150 // SdrPageView* pCurPageView = m_pView->GetSdrPageView();
3152 // sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
3153 // const SdrPageWindow* pWindow = pCurPageView ? pCurPageView->FindPageWindow(*((OutputDevice*)m_pView->GetActualOutDev())) : 0L;
3155 // clear the filter control map
3156 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
3157 iter != m_aFilterControls.end(); iter++)
3158 (*iter).first->removeTextListener(this);
3160 m_aFilterControls.clear();
3162 for ( sal_Int32 i = nControlCount; i > 0; )
3164 Reference< XControl > xControl = pControls[--i];
3165 if (xControl.is())
3167 // now enable eventhandling again
3168 addToEventAttacher(xControl);
3170 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3171 if (xSelector.is())
3173 xSelector->setMode(DATA_MODE);
3175 // listening for new controls of the selector
3176 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3177 if (xContainer.is())
3178 xContainer->removeContainerListener(this);
3179 continue;
3182 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
3183 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
3185 // does the model use a bound field ?
3186 Reference< XPropertySet > xField;
3187 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3189 // may we filter the field?
3190 if ( xField.is()
3191 && ::comphelper::hasProperty( FM_PROP_SEARCHABLE, xField )
3192 && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_SEARCHABLE ) )
3195 ::rtl::OUString sServiceName;
3196 OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DEFAULTCONTROL ) >>= sServiceName );
3197 Reference< XControl > xNewControl( m_xORB->createInstance( sServiceName ), UNO_QUERY );
3198 replaceControl( xControl, xNewControl );
3204 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3205 if ( xSet.is() )
3206 startFormListening( xSet, sal_True );
3208 m_bDetachEvents = sal_True;
3210 m_aFilters.clear();
3211 m_nCurrentFilterPosition = 0;
3213 // release the locks if possible
3214 // lock all controls which are not used for filtering
3215 m_bLocked = determineLockState();
3216 setLocks();
3218 // restart listening for control modifications
3219 if (isListeningForChanges())
3220 startListening();
3223 // XModeSelector
3224 //------------------------------------------------------------------------------
3225 void FmXFormController::setMode(const ::rtl::OUString& Mode) throw( NoSupportException, RuntimeException )
3227 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setMode" );
3228 ::osl::MutexGuard aGuard( m_aMutex );
3230 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3231 if (!supportsMode(Mode))
3232 throw NoSupportException();
3234 if (Mode == m_aMode)
3235 return;
3237 m_aMode = Mode;
3239 if (Mode == FILTER_MODE)
3240 startFiltering();
3241 else
3242 stopFiltering();
3244 for (FmFormControllers::const_iterator i = m_aChilds.begin();
3245 i != m_aChilds.end(); ++i)
3247 Reference< XModeSelector > xMode(*i, UNO_QUERY);
3248 if ( xMode.is() )
3249 xMode->setMode(Mode);
3253 //------------------------------------------------------------------------------
3254 ::rtl::OUString SAL_CALL FmXFormController::getMode(void) throw( RuntimeException )
3256 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getMode" );
3257 ::osl::MutexGuard aGuard( m_aMutex );
3258 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3259 return m_aMode;
3262 //------------------------------------------------------------------------------
3263 Sequence< ::rtl::OUString > SAL_CALL FmXFormController::getSupportedModes(void) throw( RuntimeException )
3265 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSupportedModes" );
3266 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3267 static Sequence< ::rtl::OUString > aModes;
3268 if (!aModes.getLength())
3270 aModes.realloc(2);
3271 ::rtl::OUString* pModes = aModes.getArray();
3272 pModes[0] = DATA_MODE;
3273 pModes[1] = FILTER_MODE;
3275 return aModes;
3278 //------------------------------------------------------------------------------
3279 sal_Bool SAL_CALL FmXFormController::supportsMode(const ::rtl::OUString& Mode) throw( RuntimeException )
3281 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::supportsMode" );
3282 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3283 Sequence< ::rtl::OUString > aModes(getSupportedModes());
3284 const ::rtl::OUString* pModes = aModes.getConstArray();
3285 for (sal_Int32 i = aModes.getLength(); i > 0; )
3287 if (pModes[--i] == Mode)
3288 return sal_True;
3290 return sal_False;
3293 //------------------------------------------------------------------------------
3294 Window* FmXFormController::getDialogParentWindow()
3296 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getDialogParentWindow" );
3297 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3298 Window* pParent = m_pWindow;
3299 if ( !pParent )
3303 Reference< XControl > xContainerControl( getContainer(), UNO_QUERY_THROW );
3304 Reference< XWindowPeer > xContainerPeer( xContainerControl->getPeer(), UNO_QUERY_THROW );
3305 pParent = VCLUnoHelper::GetWindow( xContainerPeer );
3307 catch( const Exception& )
3309 OSL_ENSURE( sal_False, "FmXFormController::getDialogParentWindow: caught an exception!" );
3312 return pParent;
3314 //------------------------------------------------------------------------------
3315 bool FmXFormController::checkFormComponentValidity( ::rtl::OUString& /* [out] */ _rFirstInvalidityExplanation, Reference< XControlModel >& /* [out] */ _rxFirstInvalidModel ) SAL_THROW(())
3317 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::checkFormComponentValidity" );
3320 Reference< XEnumerationAccess > xControlEnumAcc( getModel(), UNO_QUERY );
3321 Reference< XEnumeration > xControlEnumeration;
3322 if ( xControlEnumAcc.is() )
3323 xControlEnumeration = xControlEnumAcc->createEnumeration();
3324 OSL_ENSURE( xControlEnumeration.is(), "FmXFormController::checkFormComponentValidity: cannot enumerate the controls!" );
3325 if ( !xControlEnumeration.is() )
3326 // assume all valid
3327 return true;
3329 Reference< XValidatableFormComponent > xValidatable;
3330 while ( xControlEnumeration->hasMoreElements() )
3332 if ( !( xControlEnumeration->nextElement() >>= xValidatable ) )
3333 // control does not support validation
3334 continue;
3336 if ( xValidatable->isValid() )
3337 continue;
3339 Reference< XValidator > xValidator( xValidatable->getValidator() );
3340 OSL_ENSURE( xValidator.is(), "FmXFormController::checkFormComponentValidity: invalid, but no validator?" );
3341 if ( !xValidator.is() )
3342 // this violates the interface definition of css.form.validation.XValidatableFormComponent ...
3343 continue;
3345 _rFirstInvalidityExplanation = xValidator->explainInvalid( xValidatable->getCurrentValue() );
3346 _rxFirstInvalidModel = _rxFirstInvalidModel.query( xValidatable );
3347 return false;
3350 catch( const Exception& )
3352 OSL_ENSURE( sal_False, "FmXFormController::checkFormComponentValidity: caught an exception!" );
3354 return true;
3357 //------------------------------------------------------------------------------
3358 Reference< XControl > FmXFormController::locateControl( const Reference< XControlModel >& _rxModel ) SAL_THROW(())
3360 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::locateControl" );
3363 Sequence< Reference< XControl > > aControls( getControls() );
3364 const Reference< XControl >* pControls = aControls.getConstArray();
3365 const Reference< XControl >* pControlsEnd = aControls.getConstArray() + aControls.getLength();
3367 for ( ; pControls != pControlsEnd; ++pControls )
3369 OSL_ENSURE( pControls->is(), "FmXFormController::locateControl: NULL-control?" );
3370 if ( pControls->is() )
3372 if ( ( *pControls)->getModel() == _rxModel )
3373 return *pControls;
3376 OSL_ENSURE( sal_False, "FmXFormController::locateControl: did not find a control for this model!" );
3378 catch( const Exception& )
3380 OSL_ENSURE( sal_False, "FmXFormController::locateControl: caught an exception!" );
3382 return NULL;
3385 //------------------------------------------------------------------------------
3386 namespace
3388 void displayErrorSetFocus( const String& _rMessage, const Reference< XControl >& _rxFocusControl, Window* _pDialogParent )
3390 SQLContext aError;
3391 aError.Message = String( SVX_RES( RID_STR_WRITEERROR ) );
3392 aError.Details = _rMessage;
3393 displayException( aError, _pDialogParent );
3395 if ( _rxFocusControl.is() )
3397 Reference< XWindow > xControlWindow( _rxFocusControl, UNO_QUERY );
3398 OSL_ENSURE( xControlWindow.is(), "displayErrorSetFocus: invalid control!" );
3399 if ( xControlWindow.is() )
3400 xControlWindow->setFocus();
3404 sal_Bool lcl_shouldValidateRequiredFields_nothrow( const Reference< XInterface >& _rxForm )
3408 static ::rtl::OUString s_sFormsCheckRequiredFields( RTL_CONSTASCII_USTRINGPARAM( "FormsCheckRequiredFields" ) );
3410 // first, check whether the form has a property telling us the answer
3411 // this allows people to use the XPropertyContainer interface of a form to control
3412 // the behaviour on a per-form basis.
3413 Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY_THROW );
3414 Reference< XPropertySetInfo > xPSI( xFormProps->getPropertySetInfo() );
3415 if ( xPSI->hasPropertyByName( s_sFormsCheckRequiredFields ) )
3417 sal_Bool bShouldValidate = true;
3418 OSL_VERIFY( xFormProps->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3419 return bShouldValidate;
3422 // next, check the data source which created the connection
3423 Reference< XChild > xConnectionAsChild( xFormProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ), UNO_QUERY_THROW );
3424 Reference< XPropertySet > xDataSource( xConnectionAsChild->getParent(), UNO_QUERY );
3425 if ( !xDataSource.is() )
3426 // seldom (but possible): this is not a connection created by a data source
3427 return sal_True;
3429 Reference< XPropertySet > xDataSourceSettings(
3430 xDataSource->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings" ) ) ),
3431 UNO_QUERY_THROW );
3433 sal_Bool bShouldValidate = true;
3434 OSL_VERIFY( xDataSourceSettings->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3435 return bShouldValidate;
3437 catch( const Exception& )
3439 DBG_UNHANDLED_EXCEPTION();
3442 return sal_True;
3446 // XRowSetApproveListener
3447 //------------------------------------------------------------------------------
3448 sal_Bool SAL_CALL FmXFormController::approveRowChange(const RowChangeEvent& _rEvent) throw( RuntimeException )
3450 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveRowChange" );
3451 ::osl::ClearableMutexGuard aGuard( m_aMutex );
3453 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3454 ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3455 sal_Bool bValid = sal_True;
3456 if (aIter.hasMoreElements())
3458 RowChangeEvent aEvt( _rEvent );
3459 aEvt.Source = *this;
3460 bValid = ((XRowSetApproveListener*)aIter.next())->approveRowChange(aEvt);
3463 if ( !bValid )
3464 return bValid;
3466 if ( ( _rEvent.Action != RowChangeAction::INSERT )
3467 && ( _rEvent.Action != RowChangeAction::UPDATE )
3469 return bValid;
3471 // if some of the control models are bound to validators, check them
3472 ::rtl::OUString sInvalidityExplanation;
3473 Reference< XControlModel > xInvalidModel;
3474 if ( !checkFormComponentValidity( sInvalidityExplanation, xInvalidModel ) )
3476 Reference< XControl > xControl( locateControl( xInvalidModel ) );
3477 aGuard.clear();
3478 displayErrorSetFocus( sInvalidityExplanation, xControl, getDialogParentWindow() );
3479 return false;
3482 // check values on NULL and required flag
3483 if ( !lcl_shouldValidateRequiredFields_nothrow( _rEvent.Source ) )
3484 return sal_True;
3486 OSL_ENSURE( m_pColumnInfoCache.get(), "FmXFormController::approveRowChange: no column infos!" );
3487 if ( !m_pColumnInfoCache.get() )
3488 return sal_True;
3492 if ( !m_pColumnInfoCache->controlsInitialized() )
3493 m_pColumnInfoCache->initializeControls( getControls() );
3495 size_t colCount = m_pColumnInfoCache->getColumnCount();
3496 for ( size_t col = 0; col < colCount; ++col )
3498 const ColumnInfo& rColInfo = m_pColumnInfoCache->getColumnInfo( col );
3499 if ( rColInfo.nNullable != ColumnValue::NO_NULLS )
3500 continue;
3502 if ( rColInfo.bAutoIncrement )
3503 continue;
3505 if ( !rColInfo.xFirstControlWithInputRequired.is() && !rColInfo.xFirstGridWithInputRequiredColumn.is() )
3506 continue;
3508 // TODO: in case of binary fields, this "getString" below is extremely expensive
3509 if ( rColInfo.xColumn->getString().getLength() || !rColInfo.xColumn->wasNull() )
3510 continue;
3512 String sMessage( SVX_RES( RID_ERR_FIELDREQUIRED ) );
3513 sMessage.SearchAndReplace( '#', rColInfo.sName );
3515 // the control to focus
3516 Reference< XControl > xControl( rColInfo.xFirstControlWithInputRequired );
3517 if ( !xControl.is() )
3518 xControl.set( rColInfo.xFirstGridWithInputRequiredColumn, UNO_QUERY );
3520 aGuard.clear();
3521 displayErrorSetFocus( sMessage, rColInfo.xFirstControlWithInputRequired, getDialogParentWindow() );
3522 return sal_False;
3525 catch( const Exception& )
3527 DBG_UNHANDLED_EXCEPTION();
3530 return true;
3533 //------------------------------------------------------------------------------
3534 sal_Bool SAL_CALL FmXFormController::approveCursorMove(const EventObject& event) throw( RuntimeException )
3536 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveCursorMove" );
3537 ::osl::MutexGuard aGuard( m_aMutex );
3538 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3539 ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3540 if (aIter.hasMoreElements())
3542 EventObject aEvt(event);
3543 aEvt.Source = *this;
3544 return ((XRowSetApproveListener*)aIter.next())->approveCursorMove(aEvt);
3547 return sal_True;
3550 //------------------------------------------------------------------------------
3551 sal_Bool SAL_CALL FmXFormController::approveRowSetChange(const EventObject& event) throw( RuntimeException )
3553 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveRowSetChange" );
3554 ::osl::MutexGuard aGuard( m_aMutex );
3555 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3556 ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3557 if (aIter.hasMoreElements())
3559 EventObject aEvt(event);
3560 aEvt.Source = *this;
3561 return ((XRowSetApproveListener*)aIter.next())->approveRowSetChange(aEvt);
3564 return sal_True;
3567 // XRowSetApproveBroadcaster
3568 //------------------------------------------------------------------------------
3569 void SAL_CALL FmXFormController::addRowSetApproveListener(const Reference< XRowSetApproveListener > & _rxListener) throw( RuntimeException )
3571 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addRowSetApproveListener" );
3572 ::osl::MutexGuard aGuard( m_aMutex );
3573 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3574 m_aRowSetApproveListeners.addInterface(_rxListener);
3577 //------------------------------------------------------------------------------
3578 void SAL_CALL FmXFormController::removeRowSetApproveListener(const Reference< XRowSetApproveListener > & _rxListener) throw( RuntimeException )
3580 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeRowSetApproveListener" );
3581 ::osl::MutexGuard aGuard( m_aMutex );
3582 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3583 m_aRowSetApproveListeners.removeInterface(_rxListener);
3586 // XErrorListener
3587 //------------------------------------------------------------------------------
3588 void SAL_CALL FmXFormController::errorOccured(const SQLErrorEvent& aEvent) throw( RuntimeException )
3590 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::errorOccured" );
3591 ::osl::ClearableMutexGuard aGuard( m_aMutex );
3592 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3594 ::cppu::OInterfaceIteratorHelper aIter(m_aErrorListeners);
3595 if (aIter.hasMoreElements())
3597 SQLErrorEvent aEvt(aEvent);
3598 aEvt.Source = *this;
3599 ((XSQLErrorListener*)aIter.next())->errorOccured(aEvt);
3601 else
3603 aGuard.clear();
3604 displayException( aEvent );
3608 // XErrorBroadcaster
3609 //------------------------------------------------------------------------------
3610 void SAL_CALL FmXFormController::addSQLErrorListener(const Reference< XSQLErrorListener > & aListener) throw( RuntimeException )
3612 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addSQLErrorListener" );
3613 ::osl::MutexGuard aGuard( m_aMutex );
3614 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3615 m_aErrorListeners.addInterface(aListener);
3618 //------------------------------------------------------------------------------
3619 void SAL_CALL FmXFormController::removeSQLErrorListener(const Reference< XSQLErrorListener > & aListener) throw( RuntimeException )
3621 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeSQLErrorListener" );
3622 ::osl::MutexGuard aGuard( m_aMutex );
3623 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3624 m_aErrorListeners.removeInterface(aListener);
3627 // XDatabaseParameterBroadcaster2
3628 //------------------------------------------------------------------------------
3629 void SAL_CALL FmXFormController::addDatabaseParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3631 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addDatabaseParameterListener" );
3632 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3633 m_aParameterListeners.addInterface(aListener);
3636 //------------------------------------------------------------------------------
3637 void SAL_CALL FmXFormController::removeDatabaseParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3639 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeDatabaseParameterListener" );
3640 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3641 m_aParameterListeners.removeInterface(aListener);
3644 // XDatabaseParameterBroadcaster
3645 //------------------------------------------------------------------------------
3646 void SAL_CALL FmXFormController::addParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3648 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addParameterListener" );
3649 FmXFormController::addDatabaseParameterListener( aListener );
3652 //------------------------------------------------------------------------------
3653 void SAL_CALL FmXFormController::removeParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3655 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeParameterListener" );
3656 FmXFormController::removeDatabaseParameterListener( aListener );
3659 // XDatabaseParameterListener
3660 //------------------------------------------------------------------------------
3661 sal_Bool SAL_CALL FmXFormController::approveParameter(const DatabaseParameterEvent& aEvent) throw( RuntimeException )
3663 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveParameter" );
3664 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3666 ::cppu::OInterfaceIteratorHelper aIter(m_aParameterListeners);
3667 if (aIter.hasMoreElements())
3669 DatabaseParameterEvent aEvt(aEvent);
3670 aEvt.Source = *this;
3671 return ((XDatabaseParameterListener*)aIter.next())->approveParameter(aEvt);
3673 else
3675 // default handling: instantiate an interaction handler and let it handle the parameter request
3678 if ( !ensureInteractionHandler() )
3679 return sal_False;
3681 // two continuations allowed: OK and Cancel
3682 OParameterContinuation* pParamValues = new OParameterContinuation;
3683 OInteractionAbort* pAbort = new OInteractionAbort;
3684 // the request
3685 ParametersRequest aRequest;
3686 aRequest.Parameters = aEvent.Parameters;
3687 aRequest.Connection = OStaticDataAccessTools().getRowSetConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
3688 OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
3689 Reference< XInteractionRequest > xParamRequest(pParamRequest);
3690 // some knittings
3691 pParamRequest->addContinuation(pParamValues);
3692 pParamRequest->addContinuation(pAbort);
3694 // handle the request
3696 ::vos::OGuard aGuard(Application::GetSolarMutex());
3697 m_xInteractionHandler->handle(xParamRequest);
3700 if (!pParamValues->wasSelected())
3701 // canceled
3702 return sal_False;
3704 // transfer the values into the parameter supplier
3705 Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
3706 if (aFinalValues.getLength() != aRequest.Parameters->getCount())
3708 DBG_ERROR("FmXFormController::approveParameter: the InteractionHandler returned nonsense!");
3709 return sal_False;
3711 const PropertyValue* pFinalValues = aFinalValues.getConstArray();
3712 for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
3714 Reference< XPropertySet > xParam;
3715 ::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i));
3716 if (xParam.is())
3718 #ifdef DBG_UTIL
3719 ::rtl::OUString sName;
3720 xParam->getPropertyValue(FM_PROP_NAME) >>= sName;
3721 DBG_ASSERT(sName.equals(pFinalValues->Name), "FmXFormController::approveParameter: suspicious value names!");
3722 #endif
3723 try { xParam->setPropertyValue(FM_PROP_VALUE, pFinalValues->Value); }
3724 catch(Exception&)
3726 DBG_ERROR("FmXFormController::approveParameter: setting one of the properties failed!");
3731 catch(Exception&)
3733 DBG_ERROR("FmXFormController::approveParameter: caught an Exception (tried to let the InteractionHandler handle it)!");
3736 return sal_True;
3739 // XConfirmDeleteBroadcaster
3740 //------------------------------------------------------------------------------
3741 void SAL_CALL FmXFormController::addConfirmDeleteListener(const Reference< XConfirmDeleteListener > & aListener) throw( RuntimeException )
3743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addConfirmDeleteListener" );
3744 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3745 m_aDeleteListeners.addInterface(aListener);
3748 //------------------------------------------------------------------------------
3749 void SAL_CALL FmXFormController::removeConfirmDeleteListener(const Reference< XConfirmDeleteListener > & aListener) throw( RuntimeException )
3751 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeConfirmDeleteListener" );
3752 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3753 m_aDeleteListeners.removeInterface(aListener);
3756 // XConfirmDeleteListener
3757 //------------------------------------------------------------------------------
3758 sal_Bool SAL_CALL FmXFormController::confirmDelete(const RowChangeEvent& aEvent) throw( RuntimeException )
3760 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::confirmDelete" );
3761 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3763 ::cppu::OInterfaceIteratorHelper aIter(m_aDeleteListeners);
3764 if (aIter.hasMoreElements())
3766 RowChangeEvent aEvt(aEvent);
3767 aEvt.Source = *this;
3768 return ((XConfirmDeleteListener*)aIter.next())->confirmDelete(aEvt);
3770 else
3772 // default handling
3773 UniString aTitle;
3774 sal_Int32 nLength = aEvent.Rows;
3775 if (nLength > 1)
3777 aTitle = SVX_RES(RID_STR_DELETECONFIRM_RECORDS);
3778 aTitle.SearchAndReplace('#', String::CreateFromInt32(nLength));
3780 else
3781 aTitle = SVX_RES(RID_STR_DELETECONFIRM_RECORD);
3783 ConfirmDeleteDialog aDlg(getDialogParentWindow(), aTitle);
3784 return RET_YES == aDlg.Execute();
3788 //------------------------------------------------------------------------------
3789 void FmXFormController::invalidateFeatures( const ::std::vector< sal_Int32 >& _rFeatures )
3791 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::invalidateFeatures" );
3792 ::osl::MutexGuard aGuard( m_aMutex );
3793 // for now, just copy the ids of the features, because ....
3794 ::std::copy( _rFeatures.begin(), _rFeatures.end(),
3795 ::std::insert_iterator< ::std::set< sal_Int32 > >( m_aInvalidFeatures, m_aInvalidFeatures.begin() )
3798 // ... we will do the real invalidation asynchronously
3799 if ( !m_aFeatureInvalidationTimer.IsActive() )
3800 m_aFeatureInvalidationTimer.Start();
3803 //------------------------------------------------------------------------------
3804 Reference< XDispatch >
3805 FmXFormController::interceptedQueryDispatch(sal_uInt16 /*_nId*/, const URL& aURL,
3806 const ::rtl::OUString& /*aTargetFrameName*/, sal_Int32 /*nSearchFlags*/)
3807 throw( RuntimeException )
3809 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::interceptedQueryDispatch" );
3810 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3811 Reference< XDispatch > xReturn;
3812 // dispatches handled by ourself
3813 if ( ( aURL.Complete == FMURL_CONFIRM_DELETION )
3814 || ( ( aURL.Complete.equalsAscii( "private:/InteractionHandler" ) )
3815 && ensureInteractionHandler()
3818 xReturn = static_cast< XDispatch* >( this );
3820 // dispatches of FormSlot-URLs we have to translate
3821 if ( !xReturn.is() && m_aControllerFeatures.isAssigned() )
3823 // find the slot id which corresponds to the URL
3824 sal_Int32 nFeatureId = ::svx::FeatureSlotTranslation::getControllerFeatureSlotIdForURL( aURL.Main );
3825 if ( nFeatureId > 0 )
3827 // get the dispatcher for this feature, create if necessary
3828 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( nFeatureId );
3829 if ( aDispatcherPos == m_aFeatureDispatchers.end() )
3831 aDispatcherPos = m_aFeatureDispatchers.insert(
3832 DispatcherContainer::value_type( nFeatureId, new ::svx::OSingleFeatureDispatcher( aURL, nFeatureId, *m_aControllerFeatures, m_aMutex ) )
3833 ).first;
3836 OSL_ENSURE( aDispatcherPos->second.is(), "FmXFormController::interceptedQueryDispatch: should have a dispatcher by now!" );
3837 return aDispatcherPos->second;
3841 // no more to offer
3842 return xReturn;
3845 //------------------------------------------------------------------------------
3846 void SAL_CALL FmXFormController::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArgs ) throw (RuntimeException)
3848 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::dispatch" );
3849 if ( _rArgs.getLength() != 1 )
3851 DBG_ERROR( "FmXFormController::dispatch: no arguments -> no dispatch!" );
3852 return;
3855 if ( _rURL.Complete.equalsAscii( "private:/InteractionHandler" ) )
3857 Reference< XInteractionRequest > xRequest;
3858 OSL_VERIFY( _rArgs[0].Value >>= xRequest );
3859 if ( xRequest.is() )
3860 handle( xRequest );
3861 return;
3864 if ( _rURL.Complete == FMURL_CONFIRM_DELETION )
3866 DBG_ERROR( "FmXFormController::dispatch: How do you expect me to return something via this call?" );
3867 // confirmDelete has a return value - dispatch hasn't
3868 return;
3871 DBG_ERROR( "FmXFormController::dispatch: unknown URL!" );
3874 //------------------------------------------------------------------------------
3875 void SAL_CALL FmXFormController::addStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
3877 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addStatusListener" );
3878 if (_rURL.Complete == FMURL_CONFIRM_DELETION)
3880 if (_rxListener.is())
3881 { // send an initial statusChanged event
3882 FeatureStateEvent aEvent;
3883 aEvent.FeatureURL = _rURL;
3884 aEvent.IsEnabled = sal_True;
3885 _rxListener->statusChanged(aEvent);
3886 // and don't add the listener at all (the status will never change)
3889 else
3890 OSL_ENSURE(sal_False, "FmXFormController::addStatusListener: invalid (unsupported) URL!");
3893 //------------------------------------------------------------------------------
3894 void SAL_CALL FmXFormController::removeStatusListener( const Reference< XStatusListener >& /*_rxListener*/, const URL& _rURL ) throw (RuntimeException)
3896 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeStatusListener" );
3897 (void)_rURL;
3898 OSL_ENSURE(_rURL.Complete == FMURL_CONFIRM_DELETION, "FmXFormController::removeStatusListener: invalid (unsupported) URL!");
3899 // we never really added the listener, so we don't need to remove it
3902 //------------------------------------------------------------------------------
3903 Reference< XDispatchProviderInterceptor > FmXFormController::createInterceptor(const Reference< XDispatchProviderInterception > & _xInterception)
3905 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::createInterceptor" );
3906 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3907 #ifdef DBG_UTIL
3908 // check if we already have a interceptor for the given object
3909 for ( ConstInterceptorsIterator aIter = m_aControlDispatchInterceptors.begin();
3910 aIter != m_aControlDispatchInterceptors.end();
3911 ++aIter
3914 if ((*aIter)->getIntercepted() == _xInterception)
3915 DBG_ERROR("FmXFormController::createInterceptor : we already do intercept this objects dispatches !");
3917 #endif
3919 ::rtl::OUString sInterceptorScheme(RTL_CONSTASCII_USTRINGPARAM("*"));
3920 FmXDispatchInterceptorImpl* pInterceptor = new FmXDispatchInterceptorImpl(_xInterception, this, 0, Sequence< ::rtl::OUString >(&sInterceptorScheme, 1));
3921 pInterceptor->acquire();
3922 m_aControlDispatchInterceptors.insert(m_aControlDispatchInterceptors.end(), pInterceptor);
3924 return (XDispatchProviderInterceptor*)pInterceptor;
3927 //------------------------------------------------------------------------------
3928 bool FmXFormController::ensureInteractionHandler()
3930 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::ensureInteractionHandler" );
3931 if ( m_xInteractionHandler.is() )
3932 return true;
3933 if ( m_bAttemptedHandlerCreation )
3934 return false;
3935 m_bAttemptedHandlerCreation = true;
3936 if ( !m_xORB.is() )
3937 return false;
3939 m_xInteractionHandler.set( m_xORB->createInstance( SRV_SDB_INTERACTION_HANDLER ), UNO_QUERY );
3940 OSL_ENSURE( m_xInteractionHandler.is(), "FmXFormController::ensureInteractionHandler: could not create an interaction handler!" );
3941 return m_xInteractionHandler.is();
3944 //------------------------------------------------------------------------------
3945 void SAL_CALL FmXFormController::handle( const Reference< XInteractionRequest >& _rRequest ) throw (RuntimeException)
3947 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::handle" );
3948 if ( !ensureInteractionHandler() )
3949 return;
3950 m_xInteractionHandler->handle( _rRequest );
3953 //------------------------------------------------------------------------------
3954 void FmXFormController::deleteInterceptor(const Reference< XDispatchProviderInterception > & _xInterception)
3956 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::deleteInterceptor" );
3957 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3958 // search the interceptor responsible for the given object
3959 InterceptorsIterator aIter;
3960 for ( aIter = m_aControlDispatchInterceptors.begin();
3961 aIter != m_aControlDispatchInterceptors.end();
3962 ++aIter
3965 if ((*aIter)->getIntercepted() == _xInterception)
3966 break;
3968 if (aIter == m_aControlDispatchInterceptors.end())
3970 return;
3973 // log off the interception from it's interception object
3974 FmXDispatchInterceptorImpl* pInterceptorImpl = *aIter;
3975 pInterceptorImpl->dispose();
3976 pInterceptorImpl->release();
3978 // remove the interceptor from our array
3979 m_aControlDispatchInterceptors.erase(aIter);
3982 //--------------------------------------------------------------------
3983 void SAL_CALL FmXFormController::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
3985 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::initialize" );
3986 DBG_ASSERT( !m_xInteractionHandler.is(), "FmXFormController::initialize: already initialized!" );
3987 // currently, we only initialize our interaction handler here, so it's sufficient to assert this
3989 ::comphelper::NamedValueCollection aArgs( aArguments );
3990 m_xInteractionHandler = aArgs.getOrDefault( "InteractionHandler", m_xInteractionHandler );
3993 //--------------------------------------------------------------------
3994 void FmXFormController::implInvalidateCurrentControlDependentFeatures()
3996 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implInvalidateCurrentControlDependentFeatures" );
3997 ::std::vector< sal_Int32 > aCurrentControlDependentFeatures;
3999 aCurrentControlDependentFeatures.push_back( SID_FM_SORTUP );
4000 aCurrentControlDependentFeatures.push_back( SID_FM_SORTDOWN );
4001 aCurrentControlDependentFeatures.push_back( SID_FM_AUTOFILTER );
4002 aCurrentControlDependentFeatures.push_back( SID_FM_REFRESH_FORM_CONTROL );
4004 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
4005 m_pView->GetFormShell()->GetImpl()->invalidateFeatures( aCurrentControlDependentFeatures );
4006 invalidateFeatures( aCurrentControlDependentFeatures );
4009 //--------------------------------------------------------------------
4010 void SAL_CALL FmXFormController::columnChanged( const EventObject& /*_event*/ ) throw (RuntimeException)
4012 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::columnChanged" );
4013 implInvalidateCurrentControlDependentFeatures();