Update ooo320-m1
[ooovba.git] / svx / source / form / fmctrler.cxx
blob5f6c07ce7ce7849b64106ccae8f52e7747dd1744
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 sal_Bool bReadOnly;
133 ::rtl::OUString sName;
135 // information about the control(s) bound to this column
137 /// the first control which is bound to the given column, and which requires input
138 Reference< XControl > xFirstControlWithInputRequired;
139 /** the first grid control which contains a column which is bound to the given database column, and requires
140 input
142 Reference< XGrid > xFirstGridWithInputRequiredColumn;
143 /** if xFirstControlWithInputRequired is a grid control, then nRequiredGridColumn specifies the position
144 of the grid column which is actually bound
146 sal_Int32 nRequiredGridColumn;
148 ColumnInfo()
149 :xColumn()
150 ,nNullable( ColumnValue::NULLABLE_UNKNOWN )
151 ,bAutoIncrement( sal_False )
152 ,bReadOnly( sal_False )
153 ,sName()
154 ,xFirstControlWithInputRequired()
155 ,xFirstGridWithInputRequiredColumn()
156 ,nRequiredGridColumn( -1 )
161 //==============================================================================
162 //= ColumnInfoCache
163 //==============================================================================
164 class ColumnInfoCache
166 public:
167 ColumnInfoCache( const Reference< XColumnsSupplier >& _rxColSupplier );
169 size_t getColumnCount() const { return m_aColumns.size(); }
170 const ColumnInfo& getColumnInfo( size_t _pos );
172 bool controlsInitialized() const { return m_bControlsInitialized; }
173 void initializeControls( const Sequence< Reference< XControl > >& _rControls );
174 void deinitializeControls();
176 private:
177 typedef ::std::vector< ColumnInfo > ColumnInfos;
178 ColumnInfos m_aColumns;
179 bool m_bControlsInitialized;
182 //------------------------------------------------------------------------------
183 ColumnInfoCache::ColumnInfoCache( const Reference< XColumnsSupplier >& _rxColSupplier )
184 :m_aColumns()
185 ,m_bControlsInitialized( false )
187 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::ColumnInfoCache" );
190 m_aColumns.clear();
192 Reference< XColumnsSupplier > xSupplyCols( _rxColSupplier, UNO_SET_THROW );
193 Reference< XIndexAccess > xColumns( xSupplyCols->getColumns(), UNO_QUERY_THROW );
194 sal_Int32 nColumnCount = xColumns->getCount();
195 m_aColumns.reserve( nColumnCount );
197 Reference< XPropertySet > xColumnProps;
198 for ( sal_Int32 i = 0; i < nColumnCount; ++i )
200 ColumnInfo aColInfo;
201 aColInfo.xColumn.set( xColumns->getByIndex(i), UNO_QUERY_THROW );
203 xColumnProps.set( aColInfo.xColumn, UNO_QUERY_THROW );
204 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_ISNULLABLE ) >>= aColInfo.nNullable );
205 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_AUTOINCREMENT ) >>= aColInfo.bAutoIncrement );
206 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_NAME ) >>= aColInfo.sName );
207 OSL_VERIFY( xColumnProps->getPropertyValue( FM_PROP_ISREADONLY ) >>= aColInfo.bReadOnly );
209 m_aColumns.push_back( aColInfo );
212 catch( const Exception& )
214 DBG_UNHANDLED_EXCEPTION();
218 //------------------------------------------------------------------------------
219 namespace
221 bool lcl_isBoundTo( const Reference< XPropertySet >& _rxControlModel, const Reference< XInterface >& _rxNormDBField )
223 Reference< XInterface > xNormBoundField( _rxControlModel->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY );
224 return ( xNormBoundField.get() == _rxNormDBField.get() );
227 bool lcl_isInputRequired( const Reference< XPropertySet >& _rxControlModel )
229 sal_Bool bInputRequired = sal_True;
230 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_INPUT_REQUIRED ) >>= bInputRequired );
231 return ( bInputRequired != sal_False );
234 void lcl_resetColumnControlInfo( ColumnInfo& _rColInfo )
236 _rColInfo.xFirstControlWithInputRequired.clear();
237 _rColInfo.xFirstGridWithInputRequiredColumn.clear();
238 _rColInfo.nRequiredGridColumn = -1;
242 //------------------------------------------------------------------------------
243 void ColumnInfoCache::deinitializeControls()
245 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::deinitializeControls" );
246 for ( ColumnInfos::iterator col = m_aColumns.begin();
247 col != m_aColumns.end();
248 ++col
251 lcl_resetColumnControlInfo( *col );
255 //------------------------------------------------------------------------------
256 void ColumnInfoCache::initializeControls( const Sequence< Reference< XControl > >& _rControls )
258 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::initializeControls" );
261 // for every of our known columns, find the controls which are bound to this column
262 for ( ColumnInfos::iterator col = m_aColumns.begin();
263 col != m_aColumns.end();
264 ++col
267 OSL_ENSURE( !col->xFirstControlWithInputRequired.is() && !col->xFirstGridWithInputRequiredColumn.is()
268 && ( col->nRequiredGridColumn == -1 ), "ColumnInfoCache::initializeControls: called me twice?" );
270 lcl_resetColumnControlInfo( *col );
272 Reference< XInterface > xNormColumn( col->xColumn, UNO_QUERY_THROW );
274 const Reference< XControl >* pControl( _rControls.getConstArray() );
275 const Reference< XControl >* pControlEnd( pControl + _rControls.getLength() );
276 for ( ; pControl != pControlEnd; ++pControl )
278 if ( !pControl->is() )
279 continue;
281 Reference< XPropertySet > xModel( (*pControl)->getModel(), UNO_QUERY_THROW );
282 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
284 // special handling for grid controls
285 Reference< XGrid > xGrid( *pControl, UNO_QUERY );
286 if ( xGrid.is() )
288 Reference< XIndexAccess > xGridColAccess( xModel, UNO_QUERY_THROW );
289 sal_Int32 gridColCount = xGridColAccess->getCount();
290 sal_Int32 gridCol = 0;
291 for ( gridCol = 0; gridCol < gridColCount; ++gridCol )
293 Reference< XPropertySet > xGridColumnModel( xGridColAccess->getByIndex( gridCol ), UNO_QUERY_THROW );
295 if ( !lcl_isBoundTo( xGridColumnModel, xNormColumn )
296 || !lcl_isInputRequired( xGridColumnModel )
298 continue; // with next grid column
300 break;
303 if ( gridCol < gridColCount )
305 // found a grid column which is bound to the given
306 col->xFirstGridWithInputRequiredColumn = xGrid;
307 col->nRequiredGridColumn = gridCol;
308 break;
311 continue; // with next control
314 if ( !xModelPSI->hasPropertyByName( FM_PROP_BOUNDFIELD )
315 || !lcl_isBoundTo( xModel, xNormColumn )
316 || !lcl_isInputRequired( xModel )
318 continue; // with next control
320 break;
323 if ( pControl == pControlEnd )
324 // did not find a control which is bound to this particular column, and for which the input is required
325 continue; // with next DB column
327 col->xFirstControlWithInputRequired = *pControl;
330 catch( const Exception& )
332 DBG_UNHANDLED_EXCEPTION();
335 m_bControlsInitialized = true;
338 //------------------------------------------------------------------------------
339 const ColumnInfo& ColumnInfoCache::getColumnInfo( size_t _pos )
341 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "ColumnInfoCache::getColumnInfo" );
342 if ( _pos >= m_aColumns.size() )
343 throw IndexOutOfBoundsException();
345 return m_aColumns[ _pos ];
348 //==================================================================
349 // OParameterContinuation
350 //==================================================================
351 class OParameterContinuation : public OInteraction< XInteractionSupplyParameters >
353 Sequence< PropertyValue > m_aValues;
355 public:
356 OParameterContinuation() { }
358 Sequence< PropertyValue > getValues() const { return m_aValues; }
360 // XInteractionSupplyParameters
361 virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException);
364 //------------------------------------------------------------------
365 void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException)
367 m_aValues = _rValues;
370 //==================================================================
371 // FmXAutoControl
372 //==================================================================
373 struct FmFieldInfo
375 rtl::OUString aFieldName;
376 Reference< XPropertySet > xField;
377 Reference< XTextComponent > xText;
379 FmFieldInfo(const Reference< XPropertySet >& _xField, const Reference< XTextComponent >& _xText)
380 :xField(_xField)
381 ,xText(_xText)
382 {xField->getPropertyValue(FM_PROP_NAME) >>= aFieldName;}
385 //==================================================================
386 // FmXAutoControl
387 //==================================================================
388 class FmXAutoControl: public UnoControl
391 friend Reference< XInterface > SAL_CALL FmXAutoControl_NewInstance_Impl();
393 public:
394 FmXAutoControl(){}
396 virtual ::rtl::OUString GetComponentServiceName() {return ::rtl::OUString::createFromAscii("Edit");}
397 virtual void SAL_CALL createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw( RuntimeException );
399 protected:
400 virtual void ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal );
403 //------------------------------------------------------------------------------
404 void FmXAutoControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw( RuntimeException )
406 UnoControl::createPeer( rxToolkit, rParentPeer );
408 Reference< XTextComponent > xText(getPeer() , UNO_QUERY);
409 if (xText.is())
411 xText->setText(::rtl::OUString(String(SVX_RES(RID_STR_AUTOFIELD))));
412 xText->setEditable(sal_False);
416 //------------------------------------------------------------------------------
417 void FmXAutoControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal )
419 // these properties are ignored
420 if (rPropName == FM_PROP_TEXT)
421 return;
423 UnoControl::ImplSetPeerProperty( rPropName, rVal );
426 //------------------------------------------------------------------------------
427 IMPL_LINK( FmXFormController, OnActivateTabOrder, void*, /*EMPTYTAG*/ )
429 activateTabOrder();
430 return 1;
433 //------------------------------------------------------------------------------
434 struct UpdateAllListeners : public ::std::unary_function< Reference< XDispatch >, bool >
436 bool operator()( const Reference< XDispatch >& _rxDispatcher ) const
438 static_cast< ::svx::OSingleFeatureDispatcher* >( _rxDispatcher.get() )->updateAllListeners();
439 // the return is a dummy only so we can use this struct in a std::compose1 call
440 return true;
443 //..............................................................................
444 IMPL_LINK( FmXFormController, OnInvalidateFeatures, void*, /*_pNotInterestedInThisParam*/ )
446 ::osl::MutexGuard aGuard( m_aMutex );
447 for ( ::std::set< sal_Int32 >::const_iterator aLoop = m_aInvalidFeatures.begin();
448 aLoop != m_aInvalidFeatures.end();
449 ++aLoop
452 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( *aLoop );
453 if ( aDispatcherPos != m_aFeatureDispatchers.end() )
455 // TODO: for the real and actual listener notifications, we should release
456 // our mutex
457 UpdateAllListeners( )( aDispatcherPos->second );
460 return 1;
463 /*************************************************************************/
465 //------------------------------------------------------------------
466 Reference< XInterface > SAL_CALL
467 FmXFormController_NewInstance_Impl(const Reference< XMultiServiceFactory > & _rxORB)
469 return *(new FmXFormController(_rxORB));
472 //------------------------------------------------------------------
473 namespace fmctrlr
475 const ::rtl::OUString& getDataModeIdentifier()
477 static ::rtl::OUString s_sDataModeIdentifier = DATA_MODE;
478 return s_sDataModeIdentifier;
481 using namespace fmctrlr;
483 DBG_NAME( FmXFormController )
484 //------------------------------------------------------------------
485 FmXFormController::FmXFormController(const Reference< XMultiServiceFactory > & _rxORB,
486 FmFormView* _pView, Window* _pWindow )
487 :FmXFormController_BASE( m_aMutex )
488 ,OPropertySetHelper( FmXFormController_BASE::rBHelper )
489 ,OSQLParserClient(_rxORB)
490 ,m_xORB(_rxORB)
491 ,m_aActivateListeners(m_aMutex)
492 ,m_aModifyListeners(m_aMutex)
493 ,m_aErrorListeners(m_aMutex)
494 ,m_aDeleteListeners(m_aMutex)
495 ,m_aRowSetApproveListeners(m_aMutex)
496 ,m_aParameterListeners(m_aMutex)
497 ,m_pView(_pView)
498 ,m_pWindow(_pWindow)
499 ,m_pControlBorderManager( new ::svxform::ControlBorderManager )
500 ,m_aControllerFeatures( _rxORB, this )
501 ,m_aMode(getDataModeIdentifier())
502 ,m_aLoadEvent( LINK( this, FmXFormController, OnLoad ) )
503 ,m_aToggleEvent( LINK( this, FmXFormController, OnToggleAutoFields ) )
504 ,m_aActivationEvent( LINK( this, FmXFormController, OnActivated ) )
505 ,m_aDeactivationEvent( LINK( this, FmXFormController, OnDeactivated ) )
506 ,m_nCurrentFilterPosition(0)
507 ,m_bCurrentRecordModified(sal_False)
508 ,m_bCurrentRecordNew(sal_False)
509 ,m_bLocked(sal_False)
510 ,m_bDBConnection(sal_False)
511 ,m_bCycle(sal_False)
512 ,m_bCanInsert(sal_False)
513 ,m_bCanUpdate(sal_False)
514 ,m_bCommitLock(sal_False)
515 ,m_bModified(sal_False)
516 ,m_bControlsSorted(sal_False)
517 ,m_bFiltering(sal_False)
518 ,m_bAttachEvents(sal_True)
519 ,m_bDetachEvents(sal_True)
520 ,m_bAttemptedHandlerCreation( false )
522 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::FmXFormController" );
523 DBG_CTOR( FmXFormController, NULL );
525 ::comphelper::increment(m_refCount);
528 m_xAggregate = Reference< XAggregation >(
529 m_xORB->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.awt.TabController" ) ),
530 UNO_QUERY
532 DBG_ASSERT( m_xAggregate.is(), "FmXFormController::FmXFormController : could not create my aggregate !" );
533 m_xTabController = Reference< XTabController >( m_xAggregate, UNO_QUERY );
536 if ( m_xAggregate.is() )
537 m_xAggregate->setDelegator( *this );
539 ::comphelper::decrement(m_refCount);
541 m_aTabActivationTimer.SetTimeout( 500 );
542 m_aTabActivationTimer.SetTimeoutHdl( LINK( this, FmXFormController, OnActivateTabOrder ) );
544 m_aFeatureInvalidationTimer.SetTimeout( 200 );
545 m_aFeatureInvalidationTimer.SetTimeoutHdl( LINK( this, FmXFormController, OnInvalidateFeatures ) );
548 //------------------------------------------------------------------
549 FmXFormController::~FmXFormController()
552 ::osl::MutexGuard aGuard( m_aMutex );
554 m_aLoadEvent.CancelPendingCall();
555 m_aToggleEvent.CancelPendingCall();
556 m_aActivationEvent.CancelPendingCall();
557 m_aDeactivationEvent.CancelPendingCall();
559 if ( m_aTabActivationTimer.IsActive() )
560 m_aTabActivationTimer.Stop();
563 if ( m_aFeatureInvalidationTimer.IsActive() )
564 m_aFeatureInvalidationTimer.Stop();
566 disposeAllFeaturesAndDispatchers();
568 // Freigeben der Aggregation
569 if ( m_xAggregate.is() )
571 m_xAggregate->setDelegator( NULL );
572 m_xAggregate.clear();
575 DELETEZ( m_pControlBorderManager );
577 DBG_DTOR( FmXFormController, NULL );
580 // -----------------------------------------------------------------------------
581 void SAL_CALL FmXFormController::acquire() throw ()
583 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::acquire" );
584 FmXFormController_BASE::acquire();
587 // -----------------------------------------------------------------------------
588 void SAL_CALL FmXFormController::release() throw ()
590 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::release" );
591 FmXFormController_BASE::release();
594 //------------------------------------------------------------------
595 Any SAL_CALL FmXFormController::queryInterface( const Type& _rType ) throw(RuntimeException)
597 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::queryInterface" );
598 Any aRet = FmXFormController_BASE::queryInterface( _rType );
599 if ( !aRet.hasValue() )
600 aRet = OPropertySetHelper::queryInterface( _rType );
601 if ( !aRet.hasValue() )
602 aRet = m_xAggregate->queryAggregation( _rType );
603 return aRet;
606 //------------------------------------------------------------------------------
607 Sequence< sal_Int8 > SAL_CALL FmXFormController::getImplementationId() throw( RuntimeException )
609 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getImplementationId" );
610 static ::cppu::OImplementationId* pId = NULL;
611 if ( !pId )
613 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
614 if ( !pId )
616 static ::cppu::OImplementationId aId;
617 pId = &aId;
620 return pId->getImplementationId();
623 //------------------------------------------------------------------------------
624 Sequence< Type > SAL_CALL FmXFormController::getTypes( ) throw(RuntimeException)
626 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getTypes" );
627 return comphelper::concatSequences(
628 FmXFormController_BASE::getTypes(),
629 ::cppu::OPropertySetHelper::getTypes()
633 // -----------------------------------------------------------------------------
634 // XUnoTunnel
635 Sequence< sal_Int8 > FmXFormController::getUnoTunnelImplementationId()
637 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getUnoTunnelImplementationId" );
638 static ::cppu::OImplementationId * pId = NULL;
639 if ( !pId )
641 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
642 if ( !pId )
644 static ::cppu::OImplementationId aId;
645 pId = &aId;
648 return pId->getImplementationId();
650 //------------------------------------------------------------------------------
651 FmXFormController* FmXFormController::getImplementation( const Reference< XInterface >& _rxComponent )
653 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getImplementation" );
654 Reference< XUnoTunnel > xTunnel( _rxComponent, UNO_QUERY );
655 if ( xTunnel.is() )
656 return reinterpret_cast< FmXFormController* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
657 return NULL;
659 //------------------------------------------------------------------------------
660 sal_Int64 SAL_CALL FmXFormController::getSomething(Sequence<sal_Int8> const& rId)throw( RuntimeException )
662 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSomething" );
663 if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
664 return reinterpret_cast< sal_Int64 >( this );
666 return sal_Int64();
669 // XServiceInfo
670 //------------------------------------------------------------------------------
671 sal_Bool SAL_CALL FmXFormController::supportsService(const ::rtl::OUString& ServiceName) throw( RuntimeException )
673 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::supportsService" );
674 Sequence< ::rtl::OUString> aSNL(getSupportedServiceNames());
675 const ::rtl::OUString * pArray = aSNL.getConstArray();
676 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
677 if( pArray[i] == ServiceName )
678 return sal_True;
679 return sal_False;
682 //------------------------------------------------------------------------------
683 ::rtl::OUString SAL_CALL FmXFormController::getImplementationName() throw( RuntimeException )
685 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getImplementationName" );
686 return ::rtl::OUString::createFromAscii("com.sun.star.form.FmXFormController");
689 //------------------------------------------------------------------------------
690 Sequence< ::rtl::OUString> SAL_CALL FmXFormController::getSupportedServiceNames(void) throw( RuntimeException )
692 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSupportedServiceNames" );
693 // service names which are supported only, but cannot be used to created an
694 // instance at a service factory
695 Sequence< ::rtl::OUString > aNonCreatableServiceNames( 1 );
696 aNonCreatableServiceNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.FormControllerDispatcher" ) );
698 // services which can be used to created an instance at a service factory
699 Sequence< ::rtl::OUString > aCreatableServiceNames( getSupportedServiceNames_Static() );
700 return ::comphelper::concatSequences( aCreatableServiceNames, aNonCreatableServiceNames );
703 //------------------------------------------------------------------------------
704 sal_Bool SAL_CALL FmXFormController::approveReset(const EventObject& /*rEvent*/) throw( RuntimeException )
706 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveReset" );
707 return sal_True;
710 //------------------------------------------------------------------------------
711 void SAL_CALL FmXFormController::resetted(const EventObject& rEvent) throw( RuntimeException )
713 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::resetted" );
714 ::osl::MutexGuard aGuard(m_aMutex);
715 if (getCurrentControl().is() && (getCurrentControl()->getModel() == rEvent.Source))
716 m_bModified = sal_False;
719 //------------------------------------------------------------------------------
720 Sequence< ::rtl::OUString> FmXFormController::getSupportedServiceNames_Static(void)
722 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSupportedServiceNames_Static" );
723 static Sequence< ::rtl::OUString> aServices;
724 if (!aServices.getLength())
726 aServices.realloc(2);
727 aServices.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.form.FormController");
728 aServices.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.awt.control.TabController");
730 return aServices;
733 //------------------------------------------------------------------------------
734 void FmXFormController::setCurrentFilterPosition( sal_Int32 nPos )
736 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setCurrentFilterPosition" );
737 DBG_ASSERT(nPos < (sal_Int32)m_aFilters.size(), "Invalid Position");
739 if (nPos != m_nCurrentFilterPosition)
741 m_nCurrentFilterPosition = nPos;
743 // reset the text for all controls
744 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
745 iter != m_aFilterControls.end(); iter++)
746 (*iter).first->setText(rtl::OUString());
748 if ( nPos != -1 )
750 impl_setTextOnAllFilter_throw();
754 // -----------------------------------------------------------------------------
755 void FmXFormController::impl_setTextOnAllFilter_throw()
757 // set the text for all filters
758 OSL_ENSURE( ( m_aFilters.size() > (size_t)m_nCurrentFilterPosition ) && ( m_nCurrentFilterPosition >= 0 ),
759 "FmXFormController::setCurrentFilterPosition: m_nCurrentFilterPosition too big" );
761 if ( ( m_nCurrentFilterPosition >= 0 ) && ( (size_t)m_nCurrentFilterPosition < m_aFilters.size() ) )
763 FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
764 for (FmFilterRow::const_iterator iter2 = rRow.begin();
765 iter2 != rRow.end(); iter2++)
767 (*iter2).first->setText((*iter2).second);
769 } // if ( ( m_nCurrentFilterPosition >= 0 ) && ( (size_t)m_nCurrentFilterPosition < m_aFilters.size() ) )
771 // OPropertySetHelper
772 //------------------------------------------------------------------------------
773 sal_Bool FmXFormController::convertFastPropertyValue( Any & /*rConvertedValue*/, Any & /*rOldValue*/,
774 sal_Int32 /*nHandle*/, const Any& /*rValue*/ )
775 throw( IllegalArgumentException )
777 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::convertFastPropertyValue" );
778 return sal_False;
781 //------------------------------------------------------------------------------
782 void FmXFormController::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/, const Any& /*rValue*/ )
783 throw( Exception )
785 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setFastPropertyValue_NoBroadcast" );
788 //------------------------------------------------------------------------------
789 void FmXFormController::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
791 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getFastPropertyValue" );
792 switch (nHandle)
794 case FM_ATTR_FILTER:
796 ::rtl::OUStringBuffer aFilter;
797 OStaticDataAccessTools aStaticTools;
798 Reference<XConnection> xConnection(aStaticTools.getRowSetConnection(Reference< XRowSet>(m_xModelAsIndex, UNO_QUERY)));
799 if (xConnection.is())
801 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
802 Reference< XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
803 Reference< XNumberFormatter> xFormatter(m_xORB
804 ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
805 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
807 Reference< XColumnsSupplier> xSupplyCols(m_xModelAsIndex, UNO_QUERY);
808 Reference< XNameAccess> xFields(xSupplyCols->getColumns(), UNO_QUERY);
810 ::rtl::OUString aQuote( xMetaData->getIdentifierQuoteString() );
812 // now add the filter rows
813 for ( FmFilterRows::const_iterator row = m_aFilters.begin(); row != m_aFilters.end(); ++row )
815 const FmFilterRow& rRow = *row;
817 if ( rRow.empty() )
818 continue;
820 if ( aFilter.getLength() )
821 aFilter.appendAscii( " OR " );
823 aFilter.appendAscii( "( " );
824 for ( FmFilterRow::const_iterator condition = rRow.begin(); condition != rRow.end(); ++condition )
826 // get the field of the controls map
827 Reference< XTextComponent > xText = condition->first;
828 Reference< XPropertySet > xField = m_aFilterControls.find( xText )->second;
829 DBG_ASSERT( xField.is(), "FmXFormController::getFastPropertyValue: no field found!" );
830 if ( condition != rRow.begin() )
831 aFilter.appendAscii( " AND " );
833 ::rtl::OUString sFilterValue( condition->second );
835 ::rtl::OUString sErrorMsg, sCriteria;
836 ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree( sErrorMsg, sFilterValue, xFormatter, xField );
837 OSL_ENSURE( xParseNode.is(), "FmXFormController::getFastPropertyValue: could not parse the field value predicate!" );
838 if ( xParseNode.is() )
840 // don't use a parse context here, we need it unlocalized
841 xParseNode->parseNodeToStr( sCriteria, xConnection, NULL );
842 aFilter.append( sCriteria );
845 aFilter.appendAscii( " )" );
848 rValue <<= aFilter.makeStringAndClear();
850 break;
852 case FM_ATTR_FORM_OPERATIONS:
853 rValue <<= m_aControllerFeatures->getFormOperations();
854 break;
858 //------------------------------------------------------------------------------
859 Reference< XPropertySetInfo > FmXFormController::getPropertySetInfo() throw( RuntimeException )
861 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getPropertySetInfo" );
862 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
863 return xInfo;
866 //------------------------------------------------------------------------------
867 #define DECL_PROP_CORE(varname, type) \
868 pDesc[nPos++] = Property(FM_PROP_##varname, FM_ATTR_##varname, ::getCppuType((const type*)0),
871 #define DECL_PROP1(varname, type, attrib1) \
872 DECL_PROP_CORE(varname, type) PropertyAttribute::attrib1)
874 //------------------------------------------------------------------------------
875 void FmXFormController::fillProperties(
876 Sequence< Property >& /* [out] */ _rProps,
877 Sequence< Property >& /* [out] */ /*_rAggregateProps*/
878 ) const
880 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::fillProperties" );
881 _rProps.realloc(2);
882 sal_Int32 nPos = 0;
883 Property* pDesc = _rProps.getArray();
884 DECL_PROP1(FILTER, rtl::OUString, READONLY);
885 DECL_PROP1(FORM_OPERATIONS, Reference< XFormOperations >, READONLY);
888 //------------------------------------------------------------------------------
889 ::cppu::IPropertyArrayHelper& FmXFormController::getInfoHelper()
891 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getInfoHelper" );
892 return *getArrayHelper();
895 // XElementAccess
896 //------------------------------------------------------------------------------
897 sal_Bool SAL_CALL FmXFormController::hasElements(void) throw( RuntimeException )
899 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::hasElements" );
900 ::osl::MutexGuard aGuard( m_aMutex );
901 return !m_aChilds.empty();
904 //------------------------------------------------------------------------------
905 Type SAL_CALL FmXFormController::getElementType(void) throw( RuntimeException )
907 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getElementType" );
908 return ::getCppuType((const Reference< XFormController>*)0);
912 // XEnumerationAccess
913 //------------------------------------------------------------------------------
914 Reference< XEnumeration > SAL_CALL FmXFormController::createEnumeration(void) throw( RuntimeException )
916 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::createEnumeration" );
917 ::osl::MutexGuard aGuard( m_aMutex );
918 return new ::comphelper::OEnumerationByIndex(this);
921 // XIndexAccess
922 //------------------------------------------------------------------------------
923 sal_Int32 SAL_CALL FmXFormController::getCount(void) throw( RuntimeException )
925 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getCount" );
926 ::osl::MutexGuard aGuard( m_aMutex );
927 return m_aChilds.size();
930 //------------------------------------------------------------------------------
931 Any SAL_CALL FmXFormController::getByIndex(sal_Int32 Index) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
933 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getByIndex" );
934 ::osl::MutexGuard aGuard( m_aMutex );
935 if (Index < 0 ||
936 Index >= (sal_Int32)m_aChilds.size())
937 throw IndexOutOfBoundsException();
939 return makeAny(m_aChilds[Index]);
940 // , ::getCppuType((const XFormController*)0));
943 //-----------------------------------------------------------------------------
944 void FmXFormController::addChild(FmXFormController* pChild)
946 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addChild" );
947 Reference< XFormController > xController(pChild);
948 m_aChilds.push_back(xController);
949 pChild->setParent(static_cast< XFormController* >(this));
951 Reference< XFormComponent > xForm(pChild->getModel(), UNO_QUERY);
953 // search the position of the model within the form
954 sal_uInt32 nPos = m_xModelAsIndex->getCount();
955 Reference< XFormComponent > xTemp;
956 for( ; nPos; )
958 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
959 if ((XFormComponent*)xForm.get() == (XFormComponent*)xTemp.get())
961 Reference< XInterface > xIfc(xController, UNO_QUERY);
962 m_xModelAsManager->attach( nPos, xIfc, makeAny( xController) );
963 break;
968 // EventListener
969 //------------------------------------------------------------------------------
970 void SAL_CALL FmXFormController::disposing(const EventObject& e) throw( RuntimeException )
972 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::disposing" );
973 // Ist der Container disposed worden
974 ::osl::MutexGuard aGuard( m_aMutex );
975 Reference< XControlContainer > xContainer(e.Source, UNO_QUERY);
976 if (xContainer.is())
978 setContainer(Reference< XControlContainer > ());
980 else
982 // ist ein Control disposed worden
983 Reference< XControl > xControl(e.Source, UNO_QUERY);
984 if (xControl.is())
986 if (getContainer().is())
987 removeControl(xControl);
992 // OComponentHelper
993 //-----------------------------------------------------------------------------
994 void FmXFormController::disposeAllFeaturesAndDispatchers() SAL_THROW(())
996 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::disposeAllFeaturesAndDispatchers" );
997 for ( DispatcherContainer::iterator aDispatcher = m_aFeatureDispatchers.begin();
998 aDispatcher != m_aFeatureDispatchers.end();
999 ++aDispatcher
1004 ::comphelper::disposeComponent( aDispatcher->second );
1006 catch( const Exception& )
1008 OSL_ENSURE( sal_False, "FmXFormController::disposeAllFeaturesAndDispatchers: caught an exception while disposing a dispatcher!" );
1011 m_aFeatureDispatchers.clear();
1012 m_aControllerFeatures.dispose();
1015 //-----------------------------------------------------------------------------
1016 void FmXFormController::disposing(void)
1018 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::disposing" );
1019 EventObject aEvt(static_cast< XFormController* >(this));
1021 // if we're still active, simulate a "deactivated" event
1022 if ( m_xActiveControl.is() )
1023 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvt );
1025 // notify all our listeners
1026 m_aActivateListeners.disposeAndClear(aEvt);
1027 m_aModifyListeners.disposeAndClear(aEvt);
1028 m_aErrorListeners.disposeAndClear(aEvt);
1029 m_aDeleteListeners.disposeAndClear(aEvt);
1030 m_aRowSetApproveListeners.disposeAndClear(aEvt);
1031 m_aParameterListeners.disposeAndClear(aEvt);
1033 removeBoundFieldListener();
1034 stopFiltering();
1036 m_pControlBorderManager->restoreAll();
1038 m_aFilters.clear();
1040 ::osl::MutexGuard aGuard( m_aMutex );
1041 m_xActiveControl = NULL;
1042 implSetCurrentControl( NULL );
1044 // clean up our children
1045 for (FmFormControllers::const_iterator i = m_aChilds.begin();
1046 i != m_aChilds.end(); i++)
1048 // search the position of the model within the form
1049 Reference< XFormComponent > xForm((*i)->getModel(), UNO_QUERY);
1050 sal_uInt32 nPos = m_xModelAsIndex->getCount();
1051 Reference< XFormComponent > xTemp;
1052 for( ; nPos; )
1055 m_xModelAsIndex->getByIndex( --nPos ) >>= xTemp;
1056 if ( xForm.get() == xTemp.get() )
1058 Reference< XInterface > xIfc( *i, UNO_QUERY );
1059 m_xModelAsManager->detach( nPos, xIfc );
1060 break;
1064 Reference< XComponent > (*i, UNO_QUERY)->dispose();
1066 m_aChilds.clear();
1068 disposeAllFeaturesAndDispatchers();
1070 if (m_bDBConnection)
1071 unload();
1073 setContainer( NULL );
1074 setModel( NULL );
1075 setParent( NULL );
1077 ::comphelper::disposeComponent( m_xComposer );
1079 m_xORB = NULL;
1080 m_bDBConnection = sal_False;
1083 //------------------------------------------------------------------------------
1084 namespace
1086 static bool lcl_shouldUseDynamicControlBorder( const Reference< XInterface >& _rxForm, const Any& _rDynamicColorProp )
1088 bool bDoUse = false;
1089 if ( !( _rDynamicColorProp >>= bDoUse ) )
1091 DocumentType eDocType = DocumentClassification::classifyHostDocument( _rxForm );
1092 return ControlLayouter::useDynamicBorderColor( eDocType );
1094 return bDoUse;
1098 //------------------------------------------------------------------------------
1099 void SAL_CALL FmXFormController::propertyChange(const PropertyChangeEvent& evt) throw( RuntimeException )
1101 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::propertyChange" );
1102 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1103 if ( evt.PropertyName == FM_PROP_BOUNDFIELD )
1105 Reference<XPropertySet> xOldBound;
1106 evt.OldValue >>= xOldBound;
1107 if ( !xOldBound.is() && evt.NewValue.hasValue() )
1109 Reference< XControlModel > xControlModel(evt.Source,UNO_QUERY);
1110 Reference< XControl > xControl = findControl(m_aControls,xControlModel,sal_False,sal_False);
1111 if ( xControl.is() )
1113 startControlModifyListening( xControl );
1114 Reference<XPropertySet> xProp(xControlModel,UNO_QUERY);
1115 if ( xProp.is() )
1116 xProp->removePropertyChangeListener(FM_PROP_BOUNDFIELD, this);
1120 else
1122 sal_Bool bModifiedChanged = (evt.PropertyName == FM_PROP_ISMODIFIED);
1123 sal_Bool bNewChanged = (evt.PropertyName == FM_PROP_ISNEW);
1124 if (bModifiedChanged || bNewChanged)
1126 ::osl::MutexGuard aGuard( m_aMutex );
1127 if (bModifiedChanged)
1128 m_bCurrentRecordModified = ::comphelper::getBOOL(evt.NewValue);
1129 else
1130 m_bCurrentRecordNew = ::comphelper::getBOOL(evt.NewValue);
1132 // toggle the locking
1133 if (m_bLocked != determineLockState())
1135 m_bLocked = !m_bLocked;
1136 setLocks();
1137 if (isListeningForChanges())
1138 startListening();
1139 else
1140 stopListening();
1143 if ( bNewChanged )
1144 m_aToggleEvent.Call();
1146 if (!m_bCurrentRecordModified)
1147 m_bModified = sal_False;
1149 else if ( evt.PropertyName == FM_PROP_DYNAMIC_CONTROL_BORDER )
1151 bool bEnable = lcl_shouldUseDynamicControlBorder( evt.Source, evt.NewValue );
1152 if ( bEnable )
1154 m_pControlBorderManager->enableDynamicBorderColor();
1155 if ( m_xActiveControl.is() )
1156 m_pControlBorderManager->focusGained( m_xActiveControl.get() );
1158 else
1160 m_pControlBorderManager->disableDynamicBorderColor();
1166 //------------------------------------------------------------------------------
1167 bool FmXFormController::replaceControl( const Reference< XControl >& _rxExistentControl, const Reference< XControl >& _rxNewControl )
1169 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::replaceControl" );
1170 bool bSuccess = false;
1173 Reference< XIdentifierReplace > xContainer( getContainer(), UNO_QUERY );
1174 DBG_ASSERT( xContainer.is(), "FmXFormController::replaceControl: yes, it's not required by the service description, but XItentifierReplaces would be nice!" );
1175 if ( xContainer.is() )
1177 // look up the ID of _rxExistentControl
1178 Sequence< sal_Int32 > aIdentifiers( xContainer->getIdentifiers() );
1179 const sal_Int32* pIdentifiers = aIdentifiers.getConstArray();
1180 const sal_Int32* pIdentifiersEnd = aIdentifiers.getConstArray() + aIdentifiers.getLength();
1181 for ( ; pIdentifiers != pIdentifiersEnd; ++pIdentifiers )
1183 Reference< XControl > xCheck( xContainer->getByIdentifier( *pIdentifiers ), UNO_QUERY );
1184 if ( xCheck == _rxExistentControl )
1185 break;
1187 DBG_ASSERT( pIdentifiers != pIdentifiersEnd, "FmXFormController::replaceControl: did not find the control in the container!" );
1188 if ( pIdentifiers != pIdentifiersEnd )
1190 bool bReplacedWasActive = ( m_xActiveControl.get() == _rxExistentControl.get() );
1191 bool bReplacedWasCurrent = ( m_xCurrentControl.get() == _rxExistentControl.get() );
1193 if ( bReplacedWasActive )
1195 m_xActiveControl = NULL;
1196 implSetCurrentControl( NULL );
1198 else if ( bReplacedWasCurrent )
1200 implSetCurrentControl( _rxNewControl );
1203 // carry over the model
1204 _rxNewControl->setModel( _rxExistentControl->getModel() );
1206 xContainer->replaceByIdentifer( *pIdentifiers, makeAny( _rxNewControl ) );
1207 bSuccess = true;
1209 if ( bReplacedWasActive )
1211 Reference< XWindow > xControlWindow( _rxNewControl, UNO_QUERY );
1212 if ( xControlWindow.is() )
1213 xControlWindow->setFocus();
1218 catch( const Exception& )
1220 OSL_ENSURE( sal_False, "FmXFormController::replaceControl: caught an exception!" );
1223 Reference< XControl > xDisposeIt( bSuccess ? _rxExistentControl : _rxNewControl );
1224 ::comphelper::disposeComponent( xDisposeIt );
1225 return bSuccess;
1228 //------------------------------------------------------------------------------
1229 void FmXFormController::toggleAutoFields(sal_Bool bAutoFields)
1231 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::toggleAutoFields" );
1232 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1235 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
1236 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
1237 sal_Int32 nControls = aControlsCopy.getLength();
1239 if (bAutoFields)
1241 // as we don't want new controls to be attached to the scripting environment
1242 // we change attach flags
1243 m_bAttachEvents = sal_False;
1244 for (sal_Int32 i = nControls; i > 0;)
1246 Reference< XControl > xControl = pControls[--i];
1247 if (xControl.is())
1249 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1250 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1252 // does the model use a bound field ?
1253 Reference< XPropertySet > xField;
1254 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1256 // is it a autofield?
1257 if ( xField.is()
1258 && ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT, xField )
1259 && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_AUTOINCREMENT ) )
1262 replaceControl( xControl, new FmXAutoControl );
1267 m_bAttachEvents = sal_True;
1269 else
1271 m_bDetachEvents = sal_False;
1272 for (sal_Int32 i = nControls; i > 0;)
1274 Reference< XControl > xControl = pControls[--i];
1275 if (xControl.is())
1277 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1278 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
1280 // does the model use a bound field ?
1281 Reference< XPropertySet > xField;
1282 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
1284 // is it a autofield?
1285 if ( xField.is()
1286 && ::comphelper::hasProperty( FM_PROP_AUTOINCREMENT, xField )
1287 && ::comphelper::getBOOL( xField->getPropertyValue(FM_PROP_AUTOINCREMENT ) )
1290 ::rtl::OUString sServiceName;
1291 OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DEFAULTCONTROL ) >>= sServiceName );
1292 Reference< XControl > xNewControl( m_xORB->createInstance( sServiceName ), UNO_QUERY );
1293 replaceControl( xControl, xNewControl );
1298 m_bDetachEvents = sal_True;
1302 //------------------------------------------------------------------------------
1303 IMPL_LINK(FmXFormController, OnToggleAutoFields, void*, EMPTYARG)
1305 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1307 toggleAutoFields(m_bCurrentRecordNew);
1308 return 1L;
1311 // XTextListener
1312 //------------------------------------------------------------------------------
1313 void SAL_CALL FmXFormController::textChanged(const TextEvent& e) throw( RuntimeException )
1315 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::textChanged" );
1316 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1317 if (m_bFiltering)
1319 Reference< XTextComponent > xText(e.Source,UNO_QUERY);
1320 ::rtl::OUString aText = xText->getText();
1322 // Suchen der aktuellen Row
1323 OSL_ENSURE( ( m_aFilters.size() > (size_t)m_nCurrentFilterPosition ) && ( m_nCurrentFilterPosition >= 0 ),
1324 "FmXFormController::textChanged: m_nCurrentFilterPosition too big" );
1326 if ( ( m_nCurrentFilterPosition >= 0 ) && ( (size_t)m_nCurrentFilterPosition < m_aFilters.size() ) )
1328 FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
1330 // do we have a new filter
1331 if (aText.getLength())
1332 rRow[xText] = aText;
1333 else
1335 // do we have the control in the row
1336 FmFilterRow::iterator iter = rRow.find(xText);
1337 // erase the entry out of the row
1338 if (iter != rRow.end())
1339 rRow.erase(iter);
1343 else
1344 impl_onModify();
1347 // XItemListener
1348 //------------------------------------------------------------------------------
1349 void SAL_CALL FmXFormController::itemStateChanged(const ItemEvent& /*rEvent*/) throw( RuntimeException )
1351 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::itemStateChanged" );
1352 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1353 impl_onModify();
1356 // XModificationBroadcaster
1357 //------------------------------------------------------------------------------
1358 void SAL_CALL FmXFormController::addModifyListener(const Reference< XModifyListener > & l) throw( RuntimeException )
1360 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addModifyListener" );
1361 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1362 m_aModifyListeners.addInterface( l );
1365 //------------------------------------------------------------------------------
1366 void FmXFormController::removeModifyListener(const Reference< XModifyListener > & l) throw( RuntimeException )
1368 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeModifyListener" );
1369 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1370 m_aModifyListeners.removeInterface( l );
1373 // XModificationListener
1374 //------------------------------------------------------------------------------
1375 void FmXFormController::modified( const EventObject& _rEvent ) throw( RuntimeException )
1377 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::modified" );
1378 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1382 if ( _rEvent.Source != m_xActiveControl )
1383 { // let this control grab the focus
1384 // (this case may happen if somebody moves the scroll wheel of the mouse over a control
1385 // which does not have the focus)
1386 // 85511 - 29.05.2001 - frank.schoenheit@germany.sun.com
1388 // also, it happens when an image control gets a new image by double-clicking it
1389 // #i88458# / 2009-01-12 / frank.schoenheit@sun.com
1390 Reference< XWindow > xControlWindow( _rEvent.Source, UNO_QUERY_THROW );
1391 xControlWindow->setFocus();
1394 catch( const Exception& )
1396 DBG_UNHANDLED_EXCEPTION();
1399 impl_onModify();
1402 //------------------------------------------------------------------------------
1403 void FmXFormController::impl_onModify()
1405 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::onModify" );
1406 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1409 ::osl::MutexGuard aGuard( m_aMutex );
1410 if ( !m_bModified )
1411 m_bModified = sal_True;
1414 EventObject aEvt(static_cast<cppu::OWeakObject*>(this));
1415 m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
1418 //------------------------------------------------------------------------------
1419 sal_Bool FmXFormController::determineLockState() const
1421 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::determineLockState" );
1422 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1423 // a.) in filter mode we are always locked
1424 // b.) if we have no valid model or our model (a result set) is not alive -> we're locked
1425 // c.) if we are inserting everything is OK and we are not locked
1426 // d.) if are not updatable or on invalid position
1427 Reference< XResultSet > xResultSet(m_xModelAsIndex, UNO_QUERY);
1428 if (m_bFiltering || !xResultSet.is() || !isRowSetAlive(xResultSet))
1429 return sal_True;
1430 else
1431 return (m_bCanInsert && m_bCurrentRecordNew) ? sal_False
1432 : xResultSet->isBeforeFirst() || xResultSet->isAfterLast() || xResultSet->rowDeleted() || !m_bCanUpdate;
1435 // FocusListener
1436 //------------------------------------------------------------------------------
1437 void FmXFormController::focusGained(const FocusEvent& e) throw( RuntimeException )
1439 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::focusGained" );
1440 TRACE_RANGE( "FmXFormController::focusGained" );
1442 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1443 ::osl::MutexGuard aGuard( m_aMutex );
1444 Reference< XControl > xControl(e.Source, UNO_QUERY);
1446 m_pControlBorderManager->focusGained( e.Source );
1448 if (m_bDBConnection)
1450 // do we need to keep the locking of the commit
1451 // we hold the lock as long as the control differs from the current
1452 // otherwhise we disabled the lock
1453 m_bCommitLock = m_bCommitLock && (XControl*)xControl.get() != (XControl*)m_xCurrentControl.get();
1454 if (m_bCommitLock)
1455 return;
1457 // when do we have to commit a value to form or a filter
1458 // a.) if the current value is modified
1459 // b.) there must be a current control
1460 // c.) and it must be different from the new focus owning control or
1461 // d.) the focus is moving around (so we have only one control)
1463 if ( ( m_bModified || m_bFiltering )
1464 && m_xCurrentControl.is()
1465 && ( ( xControl.get() != m_xCurrentControl.get() )
1466 || ( ( e.FocusFlags & FocusChangeReason::AROUND )
1467 && ( m_bCycle || m_bFiltering )
1472 // check the old control if the content is ok
1473 #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
1474 Reference< XBoundControl > xLockingTest(m_xCurrentControl, UNO_QUERY);
1475 sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
1476 OSL_ENSURE(!bControlIsLocked, "FmXFormController::Gained: I'm modified and the current control is locked ? How this ?");
1477 // normalerweise sollte ein gelocktes Control nicht modified sein, also muss wohl mein bModified aus einem anderen Kontext
1478 // gesetzt worden sein, was ich nicht verstehen wuerde ...
1479 #endif
1480 DBG_ASSERT(m_xCurrentControl.is(), "kein CurrentControl gesetzt");
1481 // zunaechst das Control fragen ob es das IFace unterstuetzt
1482 Reference< XBoundComponent > xBound(m_xCurrentControl, UNO_QUERY);
1483 if (!xBound.is() && m_xCurrentControl.is())
1484 xBound = Reference< XBoundComponent > (m_xCurrentControl->getModel(), UNO_QUERY);
1486 // lock if we lose the focus during commit
1487 m_bCommitLock = sal_True;
1489 // Commit nicht erfolgreich, Focus zuruecksetzen
1490 if (xBound.is() && !xBound->commit())
1492 // the commit failed and we don't commit again until the current control
1493 // which couldn't be commit gains the focus again
1494 Reference< XWindow > xWindow(m_xCurrentControl, UNO_QUERY);
1495 if (xWindow.is())
1496 xWindow->setFocus();
1497 return;
1499 else
1501 m_bModified = sal_False;
1502 m_bCommitLock = sal_False;
1506 if (!m_bFiltering && m_bCycle && (e.FocusFlags & FocusChangeReason::AROUND) && m_xCurrentControl.is())
1508 if ( e.FocusFlags & FocusChangeReason::FORWARD )
1510 if ( m_aControllerFeatures->isEnabled( SID_FM_RECORD_NEXT ) )
1511 m_aControllerFeatures->moveRight();
1513 else // backward
1515 if ( m_aControllerFeatures->isEnabled( SID_FM_RECORD_PREV ) )
1516 m_aControllerFeatures->moveLeft();
1521 // Immer noch ein und dasselbe Control
1522 if ( (m_xActiveControl.get() == xControl.get())
1523 && (xControl.get() == m_xCurrentControl.get())
1526 DBG_ASSERT(m_xCurrentControl.is(), "Kein CurrentControl selektiert");
1527 return;
1530 sal_Bool bActivated = !m_xActiveControl.is() && xControl.is();
1532 m_xActiveControl = xControl;
1534 implSetCurrentControl( xControl );
1535 OSL_POSTCOND( m_xCurrentControl.is(), "implSetCurrentControl did nonsense!" );
1537 if ( bActivated )
1539 // (asynchronously) call activation handlers
1540 m_aActivationEvent.Call();
1542 // call modify listeners
1543 if ( m_bModified )
1544 m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *this ) );
1547 // invalidate all features which depend on the currently focused control
1548 if ( m_bDBConnection && !m_bFiltering && m_pView )
1549 implInvalidateCurrentControlDependentFeatures();
1551 if (m_xCurrentControl.is())
1553 // Control erhaelt Focus, dann eventuell in den sichtbaren Bereich
1554 Reference< XWindow > xWindow(xControl, UNO_QUERY);
1555 if (xWindow.is() && m_pView && m_pWindow)
1557 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
1558 ::Rectangle aNewRect(aRect.X,aRect.Y,aRect.X+aRect.Width,aRect.Y+aRect.Height);
1559 aNewRect = m_pWindow->PixelToLogic(aNewRect);
1560 m_pView->MakeVisible( aNewRect, *const_cast< Window* >( m_pWindow ) );
1565 //------------------------------------------------------------------------------
1566 IMPL_LINK( FmXFormController, OnActivated, void*, /**/ )
1568 EventObject aEvent;
1569 aEvent.Source = *this;
1570 m_aActivateListeners.notifyEach( &XFormControllerListener::formActivated, aEvent );
1572 return 0L;
1575 //------------------------------------------------------------------------------
1576 IMPL_LINK( FmXFormController, OnDeactivated, void*, /**/ )
1578 EventObject aEvent;
1579 aEvent.Source = *this;
1580 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvent );
1582 return 0L;
1585 //------------------------------------------------------------------------------
1586 void FmXFormController::focusLost(const FocusEvent& e) throw( RuntimeException )
1588 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::focusLost" );
1589 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1591 m_pControlBorderManager->focusLost( e.Source );
1593 Reference< XControl > xControl(e.Source, UNO_QUERY);
1594 Reference< XWindowPeer > xNext(e.NextFocus, UNO_QUERY);
1595 Reference< XControl > xNextControl = isInList(xNext);
1596 if (!xNextControl.is())
1598 m_xActiveControl = NULL;
1599 m_aDeactivationEvent.Call();
1603 //--------------------------------------------------------------------
1604 void SAL_CALL FmXFormController::mousePressed( const awt::MouseEvent& /*_rEvent*/ ) throw (RuntimeException)
1606 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mousePressed" );
1607 // not interested in
1610 //--------------------------------------------------------------------
1611 void SAL_CALL FmXFormController::mouseReleased( const awt::MouseEvent& /*_rEvent*/ ) throw (RuntimeException)
1613 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mouseReleased" );
1614 // not interested in
1617 //--------------------------------------------------------------------
1618 void SAL_CALL FmXFormController::mouseEntered( const awt::MouseEvent& _rEvent ) throw (RuntimeException)
1620 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mouseEntered" );
1621 m_pControlBorderManager->mouseEntered( _rEvent.Source );
1624 //--------------------------------------------------------------------
1625 void SAL_CALL FmXFormController::mouseExited( const awt::MouseEvent& _rEvent ) throw (RuntimeException)
1627 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::mouseExited" );
1628 m_pControlBorderManager->mouseExited( _rEvent.Source );
1631 //--------------------------------------------------------------------
1632 void SAL_CALL FmXFormController::componentValidityChanged( const EventObject& _rSource ) throw (RuntimeException)
1634 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::componentValidityChanged" );
1635 Reference< XControl > xControl( findControl( m_aControls, Reference< XControlModel >( _rSource.Source, UNO_QUERY ), sal_False, sal_False ) );
1636 Reference< XValidatableFormComponent > xValidatable( _rSource.Source, UNO_QUERY );
1638 OSL_ENSURE( xControl.is() && xValidatable.is(), "FmXFormController::componentValidityChanged: huh?" );
1640 if ( xControl.is() && xValidatable.is() )
1641 m_pControlBorderManager->validityChanged( xControl, xValidatable );
1644 //--------------------------------------------------------------------
1645 void FmXFormController::setModel(const Reference< XTabControllerModel > & Model) throw( RuntimeException )
1647 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setModel" );
1648 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1649 ::osl::MutexGuard aGuard( m_aMutex );
1650 DBG_ASSERT(m_xTabController.is(), "FmXFormController::setModel : invalid aggregate !");
1654 // disconnect from the old model
1655 if (m_xModelAsIndex.is())
1657 if (m_bDBConnection)
1659 // we are currently working on the model
1660 EventObject aEvt(m_xModelAsIndex);
1661 unloaded(aEvt);
1664 Reference< XLoadable > xForm(m_xModelAsIndex, UNO_QUERY);
1665 if (xForm.is())
1666 xForm->removeLoadListener(this);
1668 Reference< XSQLErrorBroadcaster > xBroadcaster(m_xModelAsIndex, UNO_QUERY);
1669 if (xBroadcaster.is())
1670 xBroadcaster->removeSQLErrorListener(this);
1672 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(m_xModelAsIndex, UNO_QUERY);
1673 if (xParamBroadcaster.is())
1674 xParamBroadcaster->removeParameterListener(this);
1677 disposeAllFeaturesAndDispatchers();
1679 // set the new model wait for the load event
1680 if (m_xTabController.is())
1681 m_xTabController->setModel(Model);
1682 m_xModelAsIndex = Reference< XIndexAccess > (Model, UNO_QUERY);
1683 m_xModelAsManager = Reference< XEventAttacherManager > (Model, UNO_QUERY);
1685 // only if both ifaces exit, the controller will work successful
1686 if (!m_xModelAsIndex.is() || !m_xModelAsManager.is())
1688 m_xModelAsManager = NULL;
1689 m_xModelAsIndex = NULL;
1692 if (m_xModelAsIndex.is())
1694 m_aControllerFeatures.assign( this );
1696 // adding load and ui interaction listeners
1697 Reference< XLoadable > xForm(Model, UNO_QUERY);
1698 if (xForm.is())
1699 xForm->addLoadListener(this);
1701 Reference< XSQLErrorBroadcaster > xBroadcaster(Model, UNO_QUERY);
1702 if (xBroadcaster.is())
1703 xBroadcaster->addSQLErrorListener(this);
1705 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(Model, UNO_QUERY);
1706 if (xParamBroadcaster.is())
1707 xParamBroadcaster->addParameterListener(this);
1709 // well, is the database already loaded?
1710 // then we have to simulate a load event
1711 Reference< XLoadable > xCursor(m_xModelAsIndex, UNO_QUERY);
1712 if (xCursor.is() && xCursor->isLoaded())
1714 EventObject aEvt(xCursor);
1715 loaded(aEvt);
1718 Reference< XPropertySet > xModelProps( m_xModelAsIndex, UNO_QUERY );
1719 Reference< XPropertySetInfo > xPropInfo( xModelProps->getPropertySetInfo() );
1720 if ( xPropInfo.is()
1721 && xPropInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER )
1722 && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_FOCUS )
1723 && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_MOUSE )
1724 && xPropInfo->hasPropertyByName( FM_PROP_CONTROL_BORDER_COLOR_INVALID )
1727 bool bEnableDynamicControlBorder = lcl_shouldUseDynamicControlBorder(
1728 xModelProps.get(), xModelProps->getPropertyValue( FM_PROP_DYNAMIC_CONTROL_BORDER ) );
1729 if ( bEnableDynamicControlBorder )
1730 m_pControlBorderManager->enableDynamicBorderColor();
1731 else
1732 m_pControlBorderManager->disableDynamicBorderColor();
1734 sal_Int32 nColor = 0;
1735 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_FOCUS ) >>= nColor )
1736 m_pControlBorderManager->setStatusColor( CONTROL_STATUS_FOCUSED, nColor );
1737 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_MOUSE ) >>= nColor )
1738 m_pControlBorderManager->setStatusColor( CONTROL_STATUS_MOUSE_HOVER, nColor );
1739 if ( xModelProps->getPropertyValue( FM_PROP_CONTROL_BORDER_COLOR_INVALID ) >>= nColor )
1740 m_pControlBorderManager->setStatusColor( CONTROL_STATUS_INVALID, nColor );
1744 catch( const Exception& )
1746 OSL_ENSURE( sal_False, "FmXFormController::setModel: caught an exception!" );
1750 //------------------------------------------------------------------------------
1751 Reference< XTabControllerModel > FmXFormController::getModel() throw( RuntimeException )
1753 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getModel" );
1754 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1755 DBG_ASSERT(m_xTabController.is(), "FmXFormController::getModel : invalid aggregate !");
1756 if (!m_xTabController.is())
1757 return Reference< XTabControllerModel > ();
1758 return m_xTabController->getModel();
1761 //------------------------------------------------------------------------------
1762 void FmXFormController::addToEventAttacher(const Reference< XControl > & xControl)
1764 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addToEventAttacher" );
1765 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1766 OSL_ENSURE( xControl.is(), "FmXFormController::addToEventAttacher: invalid control - how did you reach this?" );
1767 if ( !xControl.is() )
1768 return; /* throw IllegalArgumentException(); */
1770 // anmelden beim Eventattacher
1771 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1772 if (xComp.is() && m_xModelAsIndex.is())
1774 // Und die Position des ControlModel darin suchen
1775 sal_uInt32 nPos = m_xModelAsIndex->getCount();
1776 Reference< XFormComponent > xTemp;
1777 for( ; nPos; )
1779 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
1780 if ((XFormComponent*)xComp.get() == (XFormComponent*)xTemp.get())
1782 Reference< XInterface > xIfc(xControl, UNO_QUERY);
1783 m_xModelAsManager->attach( nPos, xIfc, makeAny(xControl) );
1784 break;
1790 //------------------------------------------------------------------------------
1791 void FmXFormController::removeFromEventAttacher(const Reference< XControl > & xControl)
1793 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeFromEventAttacher" );
1794 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1795 OSL_ENSURE( xControl.is(), "FmXFormController::removeFromEventAttacher: invalid control - how did you reach this?" );
1796 if ( !xControl.is() )
1797 return; /* throw IllegalArgumentException(); */
1799 // abmelden beim Eventattacher
1800 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1801 if ( xComp.is() && m_xModelAsIndex.is() )
1803 // Und die Position des ControlModel darin suchen
1804 sal_uInt32 nPos = m_xModelAsIndex->getCount();
1805 Reference< XFormComponent > xTemp;
1806 for( ; nPos; )
1808 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
1809 if ((XFormComponent*)xComp.get() == (XFormComponent*)xTemp.get())
1811 Reference< XInterface > xIfc(xControl, UNO_QUERY);
1812 m_xModelAsManager->detach( nPos, xIfc );
1813 break;
1819 //------------------------------------------------------------------------------
1820 void FmXFormController::setContainer(const Reference< XControlContainer > & xContainer) throw( RuntimeException )
1822 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setContainer" );
1823 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1824 Reference< XTabControllerModel > xTabModel(getModel());
1825 DBG_ASSERT(xTabModel.is() || !xContainer.is(), "No Model defined");
1826 // if we have a new container we need a model
1827 DBG_ASSERT(m_xTabController.is(), "FmXFormController::setContainer : invalid aggregate !");
1829 ::osl::MutexGuard aGuard( m_aMutex );
1830 Reference< XContainer > xCurrentContainer;
1831 if (m_xTabController.is())
1832 xCurrentContainer = Reference< XContainer > (m_xTabController->getContainer(), UNO_QUERY);
1833 if (xCurrentContainer.is())
1835 xCurrentContainer->removeContainerListener(this);
1837 if ( m_aTabActivationTimer.IsActive() )
1838 m_aTabActivationTimer.Stop();
1840 // clear the filter map
1841 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
1842 iter != m_aFilterControls.end(); ++iter)
1843 (*iter).first->removeTextListener(this);
1845 m_aFilterControls.clear();
1847 // einsammeln der Controls
1848 const Reference< XControl >* pControls = m_aControls.getConstArray();
1849 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
1850 while ( pControls != pControlsEnd )
1851 implControlRemoved( *pControls++, true );
1853 // Datenbank spezifische Dinge vornehmen
1854 if (m_bDBConnection && isListeningForChanges())
1855 stopListening();
1857 m_aControls.realloc( 0 );
1860 if (m_xTabController.is())
1861 m_xTabController->setContainer(xContainer);
1863 // Welche Controls gehoeren zum Container ?
1864 if (xContainer.is() && xTabModel.is())
1866 Sequence< Reference< XControlModel > > aModels = xTabModel->getControlModels();
1867 const Reference< XControlModel > * pModels = aModels.getConstArray();
1868 Sequence< Reference< XControl > > aAllControls = xContainer->getControls();
1870 sal_Int32 nCount = aModels.getLength();
1871 m_aControls = Sequence< Reference< XControl > >( nCount );
1872 Reference< XControl > * pControls = m_aControls.getArray();
1874 // einsammeln der Controls
1875 sal_Int32 i, j;
1876 for (i = 0, j = 0; i < nCount; ++i, ++pModels )
1878 Reference< XControl > xControl = findControl( aAllControls, *pModels, sal_False, sal_True );
1879 if ( xControl.is() )
1881 pControls[j++] = xControl;
1882 implControlInserted( xControl, true );
1886 // not every model had an associated control
1887 if (j != i)
1888 m_aControls.realloc(j);
1890 // am Container horchen
1891 Reference< XContainer > xNewContainer(xContainer, UNO_QUERY);
1892 if (xNewContainer.is())
1893 xNewContainer->addContainerListener(this);
1895 // Datenbank spezifische Dinge vornehmen
1896 if (m_bDBConnection)
1898 m_bLocked = determineLockState();
1899 setLocks();
1900 if (!isLocked())
1901 startListening();
1904 // befinden sich die Controls in der richtigen Reihenfolge
1905 m_bControlsSorted = sal_True;
1908 //------------------------------------------------------------------------------
1909 Reference< XControlContainer > FmXFormController::getContainer() throw( RuntimeException )
1911 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getContainer" );
1912 ::osl::MutexGuard aGuard( m_aMutex );
1913 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1914 DBG_ASSERT(m_xTabController.is(), "FmXFormController::getContainer : invalid aggregate !");
1915 if (!m_xTabController.is())
1916 return Reference< XControlContainer > ();
1917 return m_xTabController->getContainer();
1920 //------------------------------------------------------------------------------
1921 Sequence< Reference< XControl > > FmXFormController::getControls(void) throw( RuntimeException )
1923 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getControls" );
1924 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1925 ::osl::MutexGuard aGuard( m_aMutex );
1926 if (!m_bControlsSorted)
1928 Reference< XTabControllerModel > xModel = getModel();
1929 if (!xModel.is())
1930 return m_aControls;
1932 Sequence< Reference< XControlModel > > aControlModels = xModel->getControlModels();
1933 const Reference< XControlModel > * pModels = aControlModels.getConstArray();
1934 sal_Int32 nModels = aControlModels.getLength();
1936 Sequence< Reference< XControl > > aNewControls(nModels);
1938 Reference< XControl > * pControls = aNewControls.getArray();
1939 Reference< XControl > xControl;
1941 // Umsortieren der Controls entsprechend der TabReihenfolge
1942 sal_Int32 j = 0;
1943 for (sal_Int32 i = 0; i < nModels; ++i, ++pModels )
1945 xControl = findControl( m_aControls, *pModels, sal_True, sal_True );
1946 if ( xControl.is() )
1947 pControls[j++] = xControl;
1950 // not every model had an associated control
1951 if ( j != nModels )
1952 aNewControls.realloc( j );
1954 m_aControls = aNewControls;
1955 m_bControlsSorted = sal_True;
1957 return m_aControls;
1960 //------------------------------------------------------------------------------
1961 void FmXFormController::autoTabOrder() throw( RuntimeException )
1963 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::autoTabOrder" );
1964 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1965 ::osl::MutexGuard aGuard( m_aMutex );
1966 DBG_ASSERT(m_xTabController.is(), "FmXFormController::autoTabOrder : invalid aggregate !");
1967 if (m_xTabController.is())
1968 m_xTabController->autoTabOrder();
1971 //------------------------------------------------------------------------------
1972 void FmXFormController::activateTabOrder() throw( RuntimeException )
1974 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::activateTabOrder" );
1975 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1976 ::osl::MutexGuard aGuard( m_aMutex );
1977 DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateTabOrder : invalid aggregate !");
1978 if (m_xTabController.is())
1979 m_xTabController->activateTabOrder();
1982 //------------------------------------------------------------------------------
1983 void FmXFormController::setControlLock(const Reference< XControl > & xControl)
1985 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setControlLock" );
1986 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
1987 sal_Bool bLocked = isLocked();
1989 // es wird gelockt
1990 // a.) wenn der ganze Datensatz gesperrt ist
1991 // b.) wenn das zugehoerige Feld gespeert ist
1992 Reference< XBoundControl > xBound(xControl, UNO_QUERY);
1993 if (xBound.is() && (( (bLocked && bLocked != xBound->getLock()) ||
1994 !bLocked))) // beim entlocken immer einzelne Felder ueberprüfen
1996 // gibt es eine Datenquelle
1997 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1998 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000 // wie sieht mit den Properties ReadOnly und Enable aus
2001 sal_Bool bTouch = sal_True;
2002 if (::comphelper::hasProperty(FM_PROP_ENABLED, xSet))
2003 bTouch = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ENABLED));
2004 if (::comphelper::hasProperty(FM_PROP_READONLY, xSet))
2005 bTouch = !::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_READONLY));
2007 if (bTouch)
2009 Reference< XPropertySet > xField;
2010 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2011 if (xField.is())
2013 if (bLocked)
2014 xBound->setLock(bLocked);
2015 else
2019 Any aVal = xField->getPropertyValue(FM_PROP_ISREADONLY);
2020 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2021 xBound->setLock(sal_True);
2022 else
2023 xBound->setLock(bLocked);
2025 catch(...)
2036 //------------------------------------------------------------------------------
2037 void FmXFormController::setLocks()
2039 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setLocks" );
2040 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2041 // alle Controls, die mit einer Datenquelle verbunden sind locken/unlocken
2042 const Reference< XControl >* pControls = m_aControls.getConstArray();
2043 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2044 while ( pControls != pControlsEnd )
2045 setControlLock( *pControls++ );
2048 //------------------------------------------------------------------------------
2049 namespace
2051 bool lcl_shouldListenForModifications( const Reference< XControl >& _rxControl, const Reference< XPropertyChangeListener >& _rxBoundFieldListener )
2053 bool bShould = false;
2055 Reference< XBoundComponent > xBound( _rxControl, UNO_QUERY );
2056 if ( xBound.is() )
2058 bShould = true;
2060 else if ( _rxControl.is() )
2062 Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
2063 if ( xModelProps.is() && ::comphelper::hasProperty( FM_PROP_BOUNDFIELD, xModelProps ) )
2065 Reference< XPropertySet > xField;
2066 xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
2067 bShould = xField.is();
2069 if ( !bShould && _rxBoundFieldListener.is() )
2070 xModelProps->addPropertyChangeListener( FM_PROP_BOUNDFIELD, _rxBoundFieldListener );
2074 return bShould;
2078 //------------------------------------------------------------------------------
2079 void FmXFormController::startControlModifyListening(const Reference< XControl > & xControl)
2081 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startControlModifyListening" );
2082 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2084 bool bModifyListening = lcl_shouldListenForModifications( xControl, this );
2086 // artificial while
2087 while ( bModifyListening )
2089 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2090 if (xMod.is())
2092 xMod->addModifyListener(this);
2093 break;
2096 // alle die Text um vorzeitig ein modified zu erkennen
2097 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2098 if (xText.is())
2100 xText->addTextListener(this);
2101 break;
2104 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2105 if (xBox.is())
2107 xBox->addItemListener(this);
2108 break;
2111 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2112 if (xCbBox.is())
2114 xCbBox->addItemListener(this);
2115 break;
2118 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2119 if (xListBox.is())
2121 xListBox->addItemListener(this);
2122 break;
2124 break;
2128 //------------------------------------------------------------------------------
2129 void FmXFormController::stopControlModifyListening(const Reference< XControl > & xControl)
2131 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopControlModifyListening" );
2132 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2134 bool bModifyListening = lcl_shouldListenForModifications( xControl, NULL );
2136 // kuenstliches while
2137 while (bModifyListening)
2139 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2140 if (xMod.is())
2142 xMod->removeModifyListener(this);
2143 break;
2145 // alle die Text um vorzeitig ein modified zu erkennen
2146 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2147 if (xText.is())
2149 xText->removeTextListener(this);
2150 break;
2153 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2154 if (xBox.is())
2156 xBox->removeItemListener(this);
2157 break;
2160 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2161 if (xCbBox.is())
2163 xCbBox->removeItemListener(this);
2164 break;
2167 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2168 if (xListBox.is())
2170 xListBox->removeItemListener(this);
2171 break;
2173 break;
2177 //------------------------------------------------------------------------------
2178 void FmXFormController::startListening()
2180 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startListening" );
2181 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2182 m_bModified = sal_False;
2184 // jetzt anmelden bei gebundenen feldern
2185 const Reference< XControl >* pControls = m_aControls.getConstArray();
2186 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2187 while ( pControls != pControlsEnd )
2188 startControlModifyListening( *pControls++ );
2191 //------------------------------------------------------------------------------
2192 void FmXFormController::stopListening()
2194 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopListening" );
2195 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2196 m_bModified = sal_False;
2198 // jetzt anmelden bei gebundenen feldern
2199 const Reference< XControl >* pControls = m_aControls.getConstArray();
2200 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2201 while ( pControls != pControlsEnd )
2202 stopControlModifyListening( *pControls++ );
2206 //------------------------------------------------------------------------------
2207 Reference< XControl > FmXFormController::findControl(Sequence< Reference< XControl > >& _rControls, const Reference< XControlModel > & xCtrlModel ,sal_Bool _bRemove,sal_Bool _bOverWrite) const
2209 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::findControl" );
2210 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2211 DBG_ASSERT( xCtrlModel.is(), "findControl - welches ?!" );
2213 Reference< XControl >* pControls = _rControls.getArray();
2214 Reference< XControlModel > xModel;
2215 for ( sal_Int32 i = 0, nCount = _rControls.getLength(); i < nCount; ++i, ++pControls )
2217 if ( pControls->is() )
2219 xModel = (*pControls)->getModel();
2220 if ( xModel.get() == xCtrlModel.get() )
2222 Reference< XControl > xControl( *pControls );
2223 if ( _bRemove )
2224 ::comphelper::removeElementAt( _rControls, i );
2225 else if ( _bOverWrite )
2226 *pControls = Reference< XControl >();
2227 return xControl;
2231 return Reference< XControl > ();
2234 //------------------------------------------------------------------------------
2235 void FmXFormController::implControlInserted( const Reference< XControl>& _rxControl, bool _bAddToEventAttacher )
2237 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implControlInserted" );
2238 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2239 if ( xWindow.is() )
2241 xWindow->addFocusListener( this );
2242 xWindow->addMouseListener( this );
2244 if ( _bAddToEventAttacher )
2245 addToEventAttacher( _rxControl );
2248 // add a dispatch interceptor to the control (if supported)
2249 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY );
2250 if ( xInterception.is() )
2251 createInterceptor( xInterception );
2253 if ( _rxControl.is() )
2255 Reference< XControlModel > xModel( _rxControl->getModel() );
2257 // we want to know about the reset of the the model of our controls
2258 // (for correctly resetting m_bModified)
2259 Reference< XReset > xReset( xModel, UNO_QUERY );
2260 if ( xReset.is() )
2261 xReset->addResetListener( this );
2263 // and we want to know about the validity, to visually indicate it
2264 Reference< XValidatableFormComponent > xValidatable( xModel, UNO_QUERY );
2265 if ( xValidatable.is() )
2267 xValidatable->addFormComponentValidityListener( this );
2268 m_pControlBorderManager->validityChanged( _rxControl, xValidatable );
2274 //------------------------------------------------------------------------------
2275 void FmXFormController::implControlRemoved( const Reference< XControl>& _rxControl, bool _bRemoveFromEventAttacher )
2277 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implControlRemoved" );
2278 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2279 if ( xWindow.is() )
2281 xWindow->removeFocusListener( this );
2282 xWindow->removeMouseListener( this );
2284 if ( _bRemoveFromEventAttacher )
2285 removeFromEventAttacher( _rxControl );
2288 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY);
2289 if ( xInterception.is() )
2290 deleteInterceptor( xInterception );
2292 if ( _rxControl.is() )
2294 Reference< XControlModel > xModel( _rxControl->getModel() );
2296 Reference< XReset > xReset( xModel, UNO_QUERY );
2297 if ( xReset.is() )
2298 xReset->removeResetListener( this );
2300 Reference< XValidatableFormComponent > xValidatable( xModel, UNO_QUERY );
2301 if ( xValidatable.is() )
2302 xValidatable->removeFormComponentValidityListener( this );
2306 //------------------------------------------------------------------------------
2307 void FmXFormController::implSetCurrentControl( const Reference< XControl >& _rxControl )
2309 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implSetCurrentControl" );
2310 if ( m_xCurrentControl.get() == _rxControl.get() )
2311 return;
2313 Reference< XGridControl > xGridControl( m_xCurrentControl, UNO_QUERY );
2314 if ( xGridControl.is() )
2315 xGridControl->removeGridControlListener( this );
2317 m_xCurrentControl = _rxControl;
2319 xGridControl.set( m_xCurrentControl, UNO_QUERY );
2320 if ( xGridControl.is() )
2321 xGridControl->addGridControlListener( this );
2324 //------------------------------------------------------------------------------
2325 void FmXFormController::insertControl(const Reference< XControl > & xControl)
2327 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::insertControl" );
2328 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2329 m_bControlsSorted = sal_False;
2330 m_aControls.realloc(m_aControls.getLength() + 1);
2331 m_aControls.getArray()[m_aControls.getLength() - 1] = xControl;
2333 if ( m_pColumnInfoCache.get() )
2334 m_pColumnInfoCache->deinitializeControls();
2336 implControlInserted( xControl, m_bAttachEvents );
2338 if (m_bDBConnection && !m_bFiltering)
2339 setControlLock(xControl);
2341 if (isListeningForChanges() && m_bAttachEvents)
2342 startControlModifyListening( xControl );
2345 //------------------------------------------------------------------------------
2346 void FmXFormController::removeControl(const Reference< XControl > & xControl)
2348 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeControl" );
2349 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2350 const Reference< XControl >* pControls = m_aControls.getConstArray();
2351 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2352 while ( pControls != pControlsEnd )
2354 if ( xControl.get() == (*pControls++).get() )
2356 ::comphelper::removeElementAt( m_aControls, pControls - m_aControls.getConstArray() - 1 );
2357 break;
2361 if (m_aFilterControls.size())
2363 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2364 FmFilterControls::iterator iter = m_aFilterControls.find(xText);
2365 if (iter != m_aFilterControls.end())
2366 m_aFilterControls.erase(iter);
2369 implControlRemoved( xControl, m_bDetachEvents );
2371 if ( isListeningForChanges() && m_bDetachEvents )
2372 stopControlModifyListening( xControl );
2375 // XLoadListener
2376 //------------------------------------------------------------------------------
2377 void FmXFormController::loaded(const EventObject& rEvent) throw( RuntimeException )
2379 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::loaded" );
2380 OSL_ENSURE( rEvent.Source == m_xModelAsIndex, "FmXFormController::loaded: where did this come from?" );
2382 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2383 ::osl::MutexGuard aGuard( m_aMutex );
2384 Reference< XRowSet > xForm(rEvent.Source, UNO_QUERY);
2385 // do we have a connected data source
2386 OStaticDataAccessTools aStaticTools;
2387 if (xForm.is() && aStaticTools.getRowSetConnection(xForm).is())
2389 Reference< XPropertySet > xSet(xForm, UNO_QUERY);
2390 if (xSet.is())
2392 Any aVal = xSet->getPropertyValue(FM_PROP_CYCLE);
2393 sal_Int32 aVal2 = 0;
2394 ::cppu::enum2int(aVal2,aVal);
2395 m_bCycle = !aVal.hasValue() || aVal2 == TabulatorCycle_RECORDS;
2396 m_bCanUpdate = aStaticTools.canUpdate(xSet);
2397 m_bCanInsert = aStaticTools.canInsert(xSet);
2398 m_bCurrentRecordModified = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED));
2399 m_bCurrentRecordNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
2401 startFormListening( xSet, sal_False );
2403 // set the locks for the current controls
2404 if (getContainer().is())
2406 m_aLoadEvent.Call();
2409 else
2411 m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2412 m_bCurrentRecordModified = sal_False;
2413 m_bCurrentRecordNew = sal_False;
2414 m_bLocked = sal_False;
2416 m_bDBConnection = sal_True;
2418 else
2420 m_bDBConnection = sal_False;
2421 m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2422 m_bCurrentRecordModified = sal_False;
2423 m_bCurrentRecordNew = sal_False;
2424 m_bLocked = sal_False;
2427 Reference< XColumnsSupplier > xFormColumns( xForm, UNO_QUERY );
2428 m_pColumnInfoCache.reset( xFormColumns.is() ? new ColumnInfoCache( xFormColumns ) : NULL );
2430 updateAllDispatchers();
2433 //------------------------------------------------------------------------------
2434 void FmXFormController::updateAllDispatchers() const
2436 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::updateAllDispatchers" );
2437 ::std::for_each(
2438 m_aFeatureDispatchers.begin(),
2439 m_aFeatureDispatchers.end(),
2440 ::std::compose1(
2441 UpdateAllListeners(),
2442 ::std::select2nd< DispatcherContainer::value_type >()
2447 //------------------------------------------------------------------------------
2448 IMPL_LINK(FmXFormController, OnLoad, void*, EMPTYARG)
2450 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2451 m_bLocked = determineLockState();
2453 setLocks();
2455 if (!m_bLocked)
2456 startListening();
2458 // just one exception toggle the auto values
2459 if (m_bCurrentRecordNew)
2460 toggleAutoFields(sal_True);
2462 return 1L;
2465 //------------------------------------------------------------------------------
2466 void FmXFormController::unloaded(const EventObject& /*rEvent*/) throw( RuntimeException )
2468 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::unloaded" );
2469 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2470 updateAllDispatchers();
2473 //------------------------------------------------------------------------------
2474 void FmXFormController::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2476 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::reloading" );
2477 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2478 ::osl::MutexGuard aGuard( m_aMutex );
2479 // do the same like in unloading
2480 // just one exception toggle the auto values
2481 m_aToggleEvent.CancelPendingCall();
2482 unload();
2485 //------------------------------------------------------------------------------
2486 void FmXFormController::reloaded(const EventObject& aEvent) throw( RuntimeException )
2488 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::reloaded" );
2489 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2490 loaded(aEvent);
2493 //------------------------------------------------------------------------------
2494 void FmXFormController::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2496 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::unloading" );
2497 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2498 unload();
2501 //------------------------------------------------------------------------------
2502 void FmXFormController::unload() throw( RuntimeException )
2504 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::unload" );
2505 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2506 ::osl::MutexGuard aGuard( m_aMutex );
2508 m_aLoadEvent.CancelPendingCall();
2510 // be sure not to have autofields
2511 if (m_bCurrentRecordNew)
2512 toggleAutoFields(sal_False);
2514 // remove bound field listing again
2515 removeBoundFieldListener();
2517 if (m_bDBConnection && isListeningForChanges())
2518 stopListening();
2520 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
2521 if ( m_bDBConnection && xSet.is() )
2522 stopFormListening( xSet, sal_False );
2524 m_bDBConnection = sal_False;
2525 m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
2526 m_bCurrentRecordModified = m_bCurrentRecordNew = m_bLocked = sal_False;
2528 m_pColumnInfoCache.reset( NULL );
2531 // -----------------------------------------------------------------------------
2532 void FmXFormController::removeBoundFieldListener()
2534 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeBoundFieldListener" );
2535 const Reference< XControl >* pControls = m_aControls.getConstArray();
2536 const Reference< XControl >* pControlsEnd = pControls + m_aControls.getLength();
2537 while ( pControls != pControlsEnd )
2539 Reference< XPropertySet > xProp( *pControls++, UNO_QUERY );
2540 if ( xProp.is() )
2541 xProp->removePropertyChangeListener( FM_PROP_BOUNDFIELD, this );
2545 //------------------------------------------------------------------------------
2546 void FmXFormController::startFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
2548 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startFormListening" );
2551 if ( m_bCanInsert || m_bCanUpdate ) // form can be modified
2553 _rxForm->addPropertyChangeListener( FM_PROP_ISNEW, this );
2554 _rxForm->addPropertyChangeListener( FM_PROP_ISMODIFIED, this );
2556 if ( !_bPropertiesOnly )
2558 // set the Listener for UI interaction
2559 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2560 if ( xApprove.is() )
2561 xApprove->addRowSetApproveListener( this );
2563 // listener for row set changes
2564 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2565 if ( xRowSet.is() )
2566 xRowSet->addRowSetListener( this );
2570 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2571 if ( xInfo.is() && xInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER ) )
2572 _rxForm->addPropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER, this );
2574 catch( const Exception& )
2576 OSL_ENSURE( sal_False, "FmXFormController::startFormListening: caught an exception!" );
2580 //------------------------------------------------------------------------------
2581 void FmXFormController::stopFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
2583 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopFormListening" );
2586 if ( m_bCanInsert || m_bCanUpdate )
2588 _rxForm->removePropertyChangeListener( FM_PROP_ISNEW, this );
2589 _rxForm->removePropertyChangeListener( FM_PROP_ISMODIFIED, this );
2591 if ( !_bPropertiesOnly )
2593 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2594 if (xApprove.is())
2595 xApprove->removeRowSetApproveListener(this);
2597 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2598 if ( xRowSet.is() )
2599 xRowSet->removeRowSetListener( this );
2603 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2604 if ( xInfo.is() && xInfo->hasPropertyByName( FM_PROP_DYNAMIC_CONTROL_BORDER ) )
2605 _rxForm->removePropertyChangeListener( FM_PROP_DYNAMIC_CONTROL_BORDER, this );
2607 catch( const Exception& )
2609 OSL_ENSURE( sal_False, "FmXFormController::stopFormListening: caught an exception!" );
2613 // com::sun::star::sdbc::XRowSetListener
2614 //------------------------------------------------------------------------------
2615 void FmXFormController::cursorMoved(const EventObject& /*event*/) throw( RuntimeException )
2617 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::cursorMoved" );
2618 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2619 // toggle the locking ?
2620 if (m_bLocked != determineLockState())
2622 ::osl::MutexGuard aGuard( m_aMutex );
2623 m_bLocked = !m_bLocked;
2624 setLocks();
2625 if (isListeningForChanges())
2626 startListening();
2627 else
2628 stopListening();
2631 // neither the current control nor the current record are modified anymore
2632 m_bCurrentRecordModified = m_bModified = sal_False;
2635 //------------------------------------------------------------------------------
2636 void FmXFormController::rowChanged(const EventObject& /*event*/) throw( RuntimeException )
2638 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::rowChanged" );
2639 // not interested in ...
2641 //------------------------------------------------------------------------------
2642 void FmXFormController::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException )
2644 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::rowSetChanged" );
2645 // not interested in ...
2649 // XContainerListener
2650 //------------------------------------------------------------------------------
2651 void SAL_CALL FmXFormController::elementInserted(const ContainerEvent& evt) throw( RuntimeException )
2653 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::elementInserted" );
2654 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2655 Reference< XControl > xControl;
2656 evt.Element >>= xControl;
2657 if (!xControl.is())
2658 return;
2660 ::osl::MutexGuard aGuard( m_aMutex );
2661 Reference< XFormComponent > xModel(xControl->getModel(), UNO_QUERY);
2662 if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2664 insertControl(xControl);
2666 if ( m_aTabActivationTimer.IsActive() )
2667 m_aTabActivationTimer.Stop();
2669 m_aTabActivationTimer.Start();
2671 // are we in filtermode and a XModeSelector has inserted an element
2672 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2674 xModel = Reference< XFormComponent > (evt.Source, UNO_QUERY);
2675 if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2677 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2678 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2680 // does the model use a bound field ?
2681 Reference< XPropertySet > xField;
2682 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2684 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2685 // may we filter the field?
2686 if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
2687 ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2689 m_aFilterControls[xText] = xField;
2690 xText->addTextListener(this);
2697 //------------------------------------------------------------------------------
2698 void SAL_CALL FmXFormController::elementReplaced(const ContainerEvent& evt) throw( RuntimeException )
2700 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::elementReplaced" );
2701 // simulate an elementRemoved
2702 ContainerEvent aRemoveEvent( evt );
2703 aRemoveEvent.Element = evt.ReplacedElement;
2704 aRemoveEvent.ReplacedElement = Any();
2705 elementRemoved( aRemoveEvent );
2707 // simulate an elementInserted
2708 ContainerEvent aInsertEvent( evt );
2709 aInsertEvent.ReplacedElement = Any();
2710 elementInserted( aInsertEvent );
2713 //------------------------------------------------------------------------------
2714 void SAL_CALL FmXFormController::elementRemoved(const ContainerEvent& evt) throw( RuntimeException )
2716 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::elementRemoved" );
2717 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2718 ::osl::MutexGuard aGuard( m_aMutex );
2720 Reference< XControl > xControl;
2721 evt.Element >>= xControl;
2722 if (!xControl.is())
2723 return;
2725 Reference< XFormComponent > xModel(xControl->getModel(), UNO_QUERY);
2726 if (xModel.is() && m_xModelAsIndex == xModel->getParent())
2728 removeControl(xControl);
2729 // TabOrder nicht neu berechnen, da das intern schon funktionieren muß!
2731 // are we in filtermode and a XModeSelector has inserted an element
2732 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2734 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2735 FmFilterControls::iterator iter = m_aFilterControls.find(xText);
2736 if (iter != m_aFilterControls.end())
2737 m_aFilterControls.erase(iter);
2741 //------------------------------------------------------------------------------
2742 Reference< XControl > FmXFormController::isInList(const Reference< XWindowPeer > & xPeer) const
2744 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::isInList" );
2745 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2746 const Reference< XControl >* pControls = m_aControls.getConstArray();
2748 sal_uInt32 nCtrls = m_aControls.getLength();
2749 for ( sal_uInt32 n = 0; n < nCtrls && xPeer.is(); ++n, ++pControls )
2751 if ( pControls->is() )
2753 Reference< XVclWindowPeer > xCtrlPeer( (*pControls)->getPeer(), UNO_QUERY);
2754 if ( ( xCtrlPeer.get() == xPeer.get() ) || xCtrlPeer->isChild( xPeer ) )
2755 return *pControls;
2758 return Reference< XControl > ();
2761 //------------------------------------------------------------------------------
2762 void FmXFormController::activateFirst() throw( RuntimeException )
2764 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::activateFirst" );
2765 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2766 ::osl::MutexGuard aGuard( m_aMutex );
2767 DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateFirst : invalid aggregate !");
2768 if (m_xTabController.is())
2769 m_xTabController->activateFirst();
2772 //------------------------------------------------------------------------------
2773 void FmXFormController::activateLast() throw( RuntimeException )
2775 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::activateLast" );
2776 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2777 ::osl::MutexGuard aGuard( m_aMutex );
2778 DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateLast : invalid aggregate !");
2779 if (m_xTabController.is())
2780 m_xTabController->activateLast();
2783 // XFormController
2784 //------------------------------------------------------------------------------
2785 Reference< XControl> SAL_CALL FmXFormController::getCurrentControl(void) throw( RuntimeException )
2787 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getCurrentControl" );
2788 ::osl::MutexGuard aGuard( m_aMutex );
2789 return m_xCurrentControl;
2792 //------------------------------------------------------------------------------
2793 void SAL_CALL FmXFormController::addActivateListener(const Reference< XFormControllerListener > & l) throw( RuntimeException )
2795 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addActivateListener" );
2796 ::osl::MutexGuard aGuard( m_aMutex );
2797 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2798 m_aActivateListeners.addInterface(l);
2800 //------------------------------------------------------------------------------
2801 void SAL_CALL FmXFormController::removeActivateListener(const Reference< XFormControllerListener > & l) throw( RuntimeException )
2803 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeActivateListener" );
2804 ::osl::MutexGuard aGuard( m_aMutex );
2805 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2806 m_aActivateListeners.removeInterface(l);
2809 //------------------------------------------------------------------------------
2810 void FmXFormController::setFilter(::std::vector<FmFieldInfo>& rFieldInfos)
2812 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setFilter" );
2813 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2814 // create the composer
2815 Reference< XRowSet > xForm(m_xModelAsIndex, UNO_QUERY);
2816 Reference< XConnection > xConnection(OStaticDataAccessTools().getRowSetConnection(xForm));
2817 if (xForm.is())
2821 Reference< XMultiServiceFactory > xFactory( xConnection, UNO_QUERY_THROW );
2822 m_xComposer.set(
2823 xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
2824 UNO_QUERY_THROW );
2826 Reference< XPropertySet > xSet( xForm, UNO_QUERY );
2827 ::rtl::OUString sStatement = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_ACTIVECOMMAND ) );
2828 ::rtl::OUString sFilter = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_FILTER ) );
2829 m_xComposer->setElementaryQuery( sStatement );
2830 m_xComposer->setFilter( sFilter );
2832 catch( const Exception& )
2834 DBG_UNHANDLED_EXCEPTION();
2838 if (m_xComposer.is())
2840 Sequence < PropertyValue> aLevel;
2841 Sequence< Sequence < PropertyValue > > aFilterRows = m_xComposer->getStructuredFilter();
2843 // ok, we recieve the list of filters as sequence of fieldnames, value
2844 // now we have to transform the fieldname into UI names, that could be a label of the field or
2845 // a aliasname or the fieldname itself
2847 // first adjust the field names if necessary
2848 Reference< XNameAccess > xQueryColumns =
2849 Reference< XColumnsSupplier >( m_xComposer, UNO_QUERY_THROW )->getColumns();
2851 for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
2852 iter != rFieldInfos.end(); iter++)
2854 if ( xQueryColumns->hasByName((*iter).aFieldName) )
2856 if ( (xQueryColumns->getByName((*iter).aFieldName) >>= (*iter).xField) && (*iter).xField.is() )
2857 (*iter).xField->getPropertyValue(FM_PROP_REALNAME) >>= (*iter).aFieldName;
2861 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
2862 // now transfer the filters into Value/TextComponent pairs
2863 ::comphelper::UStringMixEqual aCompare(xMetaData->storesMixedCaseQuotedIdentifiers());
2865 // need to parse criteria localized
2866 OStaticDataAccessTools aStaticTools;
2867 Reference< XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
2868 Reference< XNumberFormatter> xFormatter(m_xORB
2869 ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
2870 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
2871 Locale aAppLocale = Application::GetSettings().GetUILocale();
2872 LocaleDataWrapper aLocaleWrapper(m_xORB,aAppLocale);
2874 // retrieving the filter
2875 const Sequence < PropertyValue >* pRow = aFilterRows.getConstArray();
2876 for (sal_Int32 i = 0, nLen = aFilterRows.getLength(); i < nLen; ++i)
2878 FmFilterRow aRow;
2880 // search a field for the given name
2881 const PropertyValue* pRefValues = pRow[i].getConstArray();
2882 for (sal_Int32 j = 0, nLen1 = pRow[i].getLength(); j < nLen1; j++)
2884 // look for the text component
2885 Reference< XPropertySet > xField;
2888 Reference< XPropertySet > xSet;
2889 ::rtl::OUString aRealName;
2891 // first look with the given name
2892 if (xQueryColumns->hasByName(pRefValues[j].Name))
2894 xQueryColumns->getByName(pRefValues[j].Name) >>= xSet;
2896 // get the RealName
2897 xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
2899 // compare the condition field name and the RealName
2900 if (aCompare(aRealName, pRefValues[j].Name))
2901 xField = xSet;
2903 if (!xField.is())
2905 // no we have to check every column to find the realname
2906 Reference< XIndexAccess > xColumnsByIndex(xQueryColumns, UNO_QUERY);
2907 for (sal_Int32 n = 0, nCount = xColumnsByIndex->getCount(); n < nCount; n++)
2909 xColumnsByIndex->getByIndex(n) >>= xSet;
2910 xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
2911 if (aCompare(aRealName, pRefValues[j].Name))
2913 // get the column by its alias
2914 xField = xSet;
2915 break;
2919 if (!xField.is())
2920 continue;
2922 catch (const Exception&)
2924 continue;
2927 // find the text component
2928 for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
2929 iter != rFieldInfos.end(); iter++)
2931 // we found the field so insert a new entry to the filter row
2932 if ((*iter).xField == xField)
2934 // do we already have the control ?
2935 if (aRow.find((*iter).xText) != aRow.end())
2937 ::rtl::OUString aCompText = aRow[(*iter).xText];
2938 aCompText += ::rtl::OUString::createFromAscii(" ");
2939 ::rtl::OString aVal = m_xParser->getContext().getIntlKeywordAscii(OParseContext::KEY_AND);
2940 aCompText += ::rtl::OUString(aVal.getStr(),aVal.getLength(),RTL_TEXTENCODING_ASCII_US);
2941 aCompText += ::rtl::OUString::createFromAscii(" ");
2942 aCompText += ::comphelper::getString(pRefValues[j].Value);
2943 aRow[(*iter).xText] = aCompText;
2945 else
2947 ::rtl::OUString sPredicate,sErrorMsg;
2948 pRefValues[j].Value >>= sPredicate;
2949 ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(sErrorMsg, sPredicate, xFormatter, xField);
2950 if ( xParseNode.is() )
2952 ::rtl::OUString sCriteria;
2953 xParseNode->parseNodeToPredicateStr( sCriteria
2954 ,xConnection
2955 ,xFormatter
2956 ,xField
2957 ,aAppLocale
2958 ,(sal_Char)aLocaleWrapper.getNumDecimalSep().GetChar(0)
2959 ,getParseContext());
2960 aRow[(*iter).xText] = sCriteria;
2967 if (aRow.empty())
2968 continue;
2970 m_aFilters.push_back(aRow);
2974 // now set the filter controls
2975 for (::std::vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
2976 iter != rFieldInfos.end(); iter++)
2978 m_aFilterControls[(*iter).xText] = (*iter).xField;
2981 // add an empty row
2982 m_aFilters.push_back(FmFilterRow());
2985 //------------------------------------------------------------------------------
2986 void FmXFormController::startFiltering()
2988 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::startFiltering" );
2989 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
2991 OStaticDataAccessTools aStaticTools;
2992 Reference< XConnection > xConnection( aStaticTools.getRowSetConnection( Reference< XRowSet >( m_xModelAsIndex, UNO_QUERY ) ) );
2993 if ( !xConnection.is() )
2994 // nothing to do - can't filter a form which is not connected
2995 // 98023 - 19.03.2002 - fs@openoffice.org
2996 return;
2998 // stop listening for controls
2999 if (isListeningForChanges())
3000 stopListening();
3002 m_bFiltering = sal_True;
3004 // as we don't want new controls to be attached to the scripting environment
3005 // we change attach flags
3006 m_bAttachEvents = sal_False;
3008 // Austauschen der Kontrols fuer das aktuelle Formular
3009 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3010 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
3011 sal_Int32 nControlCount = aControlsCopy.getLength();
3013 // the control we have to activate after replacement
3014 Reference< XDatabaseMetaData > xMetaData(xConnection->getMetaData());
3015 Reference< XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats(xConnection, sal_True);
3016 Reference< XNumberFormatter > xFormatter(m_xORB
3017 ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
3018 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3020 // structure for storing the field info
3021 ::std::vector<FmFieldInfo> aFieldInfos;
3023 for (sal_Int32 i = nControlCount; i > 0;)
3025 Reference< XControl > xControl = pControls[--i];
3026 if (xControl.is())
3028 // no events for the control anymore
3029 removeFromEventAttacher(xControl);
3031 // do we have a mode selector
3032 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3033 if (xSelector.is())
3035 xSelector->setMode(FILTER_MODE);
3037 // listening for new controls of the selector
3038 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3039 if (xContainer.is())
3040 xContainer->addContainerListener(this);
3042 Reference< XEnumerationAccess > xElementAccess(xSelector, UNO_QUERY);
3043 if (xElementAccess.is())
3045 Reference< XEnumeration > xEnumeration(xElementAccess->createEnumeration());
3046 Reference< XControl > xSubControl;
3047 while (xEnumeration->hasMoreElements())
3049 xEnumeration->nextElement() >>= xSubControl;
3050 if (xSubControl.is())
3052 Reference< XPropertySet > xSet(xSubControl->getModel(), UNO_QUERY);
3053 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
3055 // does the model use a bound field ?
3056 Reference< XPropertySet > xField;
3057 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3059 Reference< XTextComponent > xText(xSubControl, UNO_QUERY);
3060 // may we filter the field?
3061 if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
3062 ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
3064 aFieldInfos.push_back(FmFieldInfo(xField, xText));
3065 xText->addTextListener(this);
3071 continue;
3074 Reference< XPropertySet > xModel( xControl->getModel(), UNO_QUERY );
3075 if (xModel.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xModel))
3077 // does the model use a bound field ?
3078 Any aVal = xModel->getPropertyValue(FM_PROP_BOUNDFIELD);
3079 Reference< XPropertySet > xField;
3080 aVal >>= xField;
3082 // may we filter the field?
3084 if ( xField.is()
3085 && ::comphelper::hasProperty( FM_PROP_SEARCHABLE, xField )
3086 && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_SEARCHABLE ) )
3089 // create a filter control
3090 Sequence< Any > aCreationArgs( 3 );
3091 aCreationArgs[ 0 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "MessageParent" ), makeAny( VCLUnoHelper::GetInterface( getDialogParentWindow() ) ) );
3092 aCreationArgs[ 1 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "NumberFormatter" ), makeAny( xFormatter ) );
3093 aCreationArgs[ 2 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "ControlModel" ), makeAny( xModel ) );
3094 Reference< XControl > xFilterControl(
3095 m_xORB->createInstanceWithArguments(
3096 ::rtl::OUString::createFromAscii( "com.sun.star.form.control.FilterControl" ),
3097 aCreationArgs
3099 UNO_QUERY
3101 DBG_ASSERT( xFilterControl.is(), "FmXFormController::startFiltering: could not create a filter control!" );
3103 if ( replaceControl( xControl, xFilterControl ) )
3105 Reference< XTextComponent > xFilterText( xFilterControl, UNO_QUERY );
3106 aFieldInfos.push_back( FmFieldInfo( xField, xFilterText ) );
3107 xFilterText->addTextListener(this);
3111 else
3113 // abmelden vom EventManager
3118 // we have all filter controls now, so the next step is to read the filters from the form
3119 // resolve all aliases and set the current filter to the according structure
3120 setFilter(aFieldInfos);
3122 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3123 if ( xSet.is() )
3124 stopFormListening( xSet, sal_True );
3126 impl_setTextOnAllFilter_throw();
3128 // lock all controls which are not used for filtering
3129 m_bLocked = determineLockState();
3130 setLocks();
3131 m_bAttachEvents = sal_True;
3134 //------------------------------------------------------------------------------
3135 void FmXFormController::stopFiltering()
3137 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::stopFiltering" );
3138 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3139 if ( !m_bFiltering ) // #104693# OJ
3140 { // nothing to do
3141 return;
3144 m_bFiltering = sal_False;
3145 m_bDetachEvents = sal_False;
3147 ::comphelper::disposeComponent(m_xComposer);
3149 // Austauschen der Kontrols fuer das aktuelle Formular
3150 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3151 const Reference< XControl > * pControls = aControlsCopy.getConstArray();
3152 sal_Int32 nControlCount = aControlsCopy.getLength();
3153 // SdrPageView* pCurPageView = m_pView->GetSdrPageView();
3155 // sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
3156 // const SdrPageWindow* pWindow = pCurPageView ? pCurPageView->FindPageWindow(*((OutputDevice*)m_pView->GetActualOutDev())) : 0L;
3158 // clear the filter control map
3159 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
3160 iter != m_aFilterControls.end(); iter++)
3161 (*iter).first->removeTextListener(this);
3163 m_aFilterControls.clear();
3165 for ( sal_Int32 i = nControlCount; i > 0; )
3167 Reference< XControl > xControl = pControls[--i];
3168 if (xControl.is())
3170 // now enable eventhandling again
3171 addToEventAttacher(xControl);
3173 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3174 if (xSelector.is())
3176 xSelector->setMode(DATA_MODE);
3178 // listening for new controls of the selector
3179 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3180 if (xContainer.is())
3181 xContainer->removeContainerListener(this);
3182 continue;
3185 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
3186 if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
3188 // does the model use a bound field ?
3189 Reference< XPropertySet > xField;
3190 xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
3192 // may we filter the field?
3193 if ( xField.is()
3194 && ::comphelper::hasProperty( FM_PROP_SEARCHABLE, xField )
3195 && ::comphelper::getBOOL( xField->getPropertyValue( FM_PROP_SEARCHABLE ) )
3198 ::rtl::OUString sServiceName;
3199 OSL_VERIFY( xSet->getPropertyValue( FM_PROP_DEFAULTCONTROL ) >>= sServiceName );
3200 Reference< XControl > xNewControl( m_xORB->createInstance( sServiceName ), UNO_QUERY );
3201 replaceControl( xControl, xNewControl );
3207 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3208 if ( xSet.is() )
3209 startFormListening( xSet, sal_True );
3211 m_bDetachEvents = sal_True;
3213 m_aFilters.clear();
3214 m_nCurrentFilterPosition = 0;
3216 // release the locks if possible
3217 // lock all controls which are not used for filtering
3218 m_bLocked = determineLockState();
3219 setLocks();
3221 // restart listening for control modifications
3222 if (isListeningForChanges())
3223 startListening();
3226 // XModeSelector
3227 //------------------------------------------------------------------------------
3228 void FmXFormController::setMode(const ::rtl::OUString& Mode) throw( NoSupportException, RuntimeException )
3230 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::setMode" );
3231 ::osl::MutexGuard aGuard( m_aMutex );
3233 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3234 if (!supportsMode(Mode))
3235 throw NoSupportException();
3237 if (Mode == m_aMode)
3238 return;
3240 m_aMode = Mode;
3242 if (Mode == FILTER_MODE)
3243 startFiltering();
3244 else
3245 stopFiltering();
3247 for (FmFormControllers::const_iterator i = m_aChilds.begin();
3248 i != m_aChilds.end(); ++i)
3250 Reference< XModeSelector > xMode(*i, UNO_QUERY);
3251 if ( xMode.is() )
3252 xMode->setMode(Mode);
3256 //------------------------------------------------------------------------------
3257 ::rtl::OUString SAL_CALL FmXFormController::getMode(void) throw( RuntimeException )
3259 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getMode" );
3260 ::osl::MutexGuard aGuard( m_aMutex );
3261 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3262 return m_aMode;
3265 //------------------------------------------------------------------------------
3266 Sequence< ::rtl::OUString > SAL_CALL FmXFormController::getSupportedModes(void) throw( RuntimeException )
3268 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getSupportedModes" );
3269 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3270 static Sequence< ::rtl::OUString > aModes;
3271 if (!aModes.getLength())
3273 aModes.realloc(2);
3274 ::rtl::OUString* pModes = aModes.getArray();
3275 pModes[0] = DATA_MODE;
3276 pModes[1] = FILTER_MODE;
3278 return aModes;
3281 //------------------------------------------------------------------------------
3282 sal_Bool SAL_CALL FmXFormController::supportsMode(const ::rtl::OUString& Mode) throw( RuntimeException )
3284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::supportsMode" );
3285 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3286 Sequence< ::rtl::OUString > aModes(getSupportedModes());
3287 const ::rtl::OUString* pModes = aModes.getConstArray();
3288 for (sal_Int32 i = aModes.getLength(); i > 0; )
3290 if (pModes[--i] == Mode)
3291 return sal_True;
3293 return sal_False;
3296 //------------------------------------------------------------------------------
3297 Window* FmXFormController::getDialogParentWindow()
3299 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::getDialogParentWindow" );
3300 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3301 Window* pParent = m_pWindow;
3302 if ( !pParent )
3306 Reference< XControl > xContainerControl( getContainer(), UNO_QUERY_THROW );
3307 Reference< XWindowPeer > xContainerPeer( xContainerControl->getPeer(), UNO_QUERY_THROW );
3308 pParent = VCLUnoHelper::GetWindow( xContainerPeer );
3310 catch( const Exception& )
3312 OSL_ENSURE( sal_False, "FmXFormController::getDialogParentWindow: caught an exception!" );
3315 return pParent;
3317 //------------------------------------------------------------------------------
3318 bool FmXFormController::checkFormComponentValidity( ::rtl::OUString& /* [out] */ _rFirstInvalidityExplanation, Reference< XControlModel >& /* [out] */ _rxFirstInvalidModel ) SAL_THROW(())
3320 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::checkFormComponentValidity" );
3323 Reference< XEnumerationAccess > xControlEnumAcc( getModel(), UNO_QUERY );
3324 Reference< XEnumeration > xControlEnumeration;
3325 if ( xControlEnumAcc.is() )
3326 xControlEnumeration = xControlEnumAcc->createEnumeration();
3327 OSL_ENSURE( xControlEnumeration.is(), "FmXFormController::checkFormComponentValidity: cannot enumerate the controls!" );
3328 if ( !xControlEnumeration.is() )
3329 // assume all valid
3330 return true;
3332 Reference< XValidatableFormComponent > xValidatable;
3333 while ( xControlEnumeration->hasMoreElements() )
3335 if ( !( xControlEnumeration->nextElement() >>= xValidatable ) )
3336 // control does not support validation
3337 continue;
3339 if ( xValidatable->isValid() )
3340 continue;
3342 Reference< XValidator > xValidator( xValidatable->getValidator() );
3343 OSL_ENSURE( xValidator.is(), "FmXFormController::checkFormComponentValidity: invalid, but no validator?" );
3344 if ( !xValidator.is() )
3345 // this violates the interface definition of css.form.validation.XValidatableFormComponent ...
3346 continue;
3348 _rFirstInvalidityExplanation = xValidator->explainInvalid( xValidatable->getCurrentValue() );
3349 _rxFirstInvalidModel = _rxFirstInvalidModel.query( xValidatable );
3350 return false;
3353 catch( const Exception& )
3355 OSL_ENSURE( sal_False, "FmXFormController::checkFormComponentValidity: caught an exception!" );
3357 return true;
3360 //------------------------------------------------------------------------------
3361 Reference< XControl > FmXFormController::locateControl( const Reference< XControlModel >& _rxModel ) SAL_THROW(())
3363 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::locateControl" );
3366 Sequence< Reference< XControl > > aControls( getControls() );
3367 const Reference< XControl >* pControls = aControls.getConstArray();
3368 const Reference< XControl >* pControlsEnd = aControls.getConstArray() + aControls.getLength();
3370 for ( ; pControls != pControlsEnd; ++pControls )
3372 OSL_ENSURE( pControls->is(), "FmXFormController::locateControl: NULL-control?" );
3373 if ( pControls->is() )
3375 if ( ( *pControls)->getModel() == _rxModel )
3376 return *pControls;
3379 OSL_ENSURE( sal_False, "FmXFormController::locateControl: did not find a control for this model!" );
3381 catch( const Exception& )
3383 OSL_ENSURE( sal_False, "FmXFormController::locateControl: caught an exception!" );
3385 return NULL;
3388 //------------------------------------------------------------------------------
3389 namespace
3391 void displayErrorSetFocus( const String& _rMessage, const Reference< XControl >& _rxFocusControl, Window* _pDialogParent )
3393 SQLContext aError;
3394 aError.Message = String( SVX_RES( RID_STR_WRITEERROR ) );
3395 aError.Details = _rMessage;
3396 displayException( aError, _pDialogParent );
3398 if ( _rxFocusControl.is() )
3400 Reference< XWindow > xControlWindow( _rxFocusControl, UNO_QUERY );
3401 OSL_ENSURE( xControlWindow.is(), "displayErrorSetFocus: invalid control!" );
3402 if ( xControlWindow.is() )
3403 xControlWindow->setFocus();
3407 sal_Bool lcl_shouldValidateRequiredFields_nothrow( const Reference< XInterface >& _rxForm )
3411 static ::rtl::OUString s_sFormsCheckRequiredFields( RTL_CONSTASCII_USTRINGPARAM( "FormsCheckRequiredFields" ) );
3413 // first, check whether the form has a property telling us the answer
3414 // this allows people to use the XPropertyContainer interface of a form to control
3415 // the behaviour on a per-form basis.
3416 Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY_THROW );
3417 Reference< XPropertySetInfo > xPSI( xFormProps->getPropertySetInfo() );
3418 if ( xPSI->hasPropertyByName( s_sFormsCheckRequiredFields ) )
3420 sal_Bool bShouldValidate = true;
3421 OSL_VERIFY( xFormProps->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3422 return bShouldValidate;
3425 // next, check the data source which created the connection
3426 Reference< XChild > xConnectionAsChild( xFormProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ), UNO_QUERY_THROW );
3427 Reference< XPropertySet > xDataSource( xConnectionAsChild->getParent(), UNO_QUERY );
3428 if ( !xDataSource.is() )
3429 // seldom (but possible): this is not a connection created by a data source
3430 return sal_True;
3432 Reference< XPropertySet > xDataSourceSettings(
3433 xDataSource->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings" ) ) ),
3434 UNO_QUERY_THROW );
3436 sal_Bool bShouldValidate = true;
3437 OSL_VERIFY( xDataSourceSettings->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3438 return bShouldValidate;
3440 catch( const Exception& )
3442 DBG_UNHANDLED_EXCEPTION();
3445 return sal_True;
3449 // XRowSetApproveListener
3450 //------------------------------------------------------------------------------
3451 sal_Bool SAL_CALL FmXFormController::approveRowChange(const RowChangeEvent& _rEvent) throw( RuntimeException )
3453 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveRowChange" );
3454 ::osl::ClearableMutexGuard aGuard( m_aMutex );
3456 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3457 ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3458 sal_Bool bValid = sal_True;
3459 if (aIter.hasMoreElements())
3461 RowChangeEvent aEvt( _rEvent );
3462 aEvt.Source = *this;
3463 bValid = ((XRowSetApproveListener*)aIter.next())->approveRowChange(aEvt);
3466 if ( !bValid )
3467 return bValid;
3469 if ( ( _rEvent.Action != RowChangeAction::INSERT )
3470 && ( _rEvent.Action != RowChangeAction::UPDATE )
3472 return bValid;
3474 // if some of the control models are bound to validators, check them
3475 ::rtl::OUString sInvalidityExplanation;
3476 Reference< XControlModel > xInvalidModel;
3477 if ( !checkFormComponentValidity( sInvalidityExplanation, xInvalidModel ) )
3479 Reference< XControl > xControl( locateControl( xInvalidModel ) );
3480 aGuard.clear();
3481 displayErrorSetFocus( sInvalidityExplanation, xControl, getDialogParentWindow() );
3482 return false;
3485 // check values on NULL and required flag
3486 if ( !lcl_shouldValidateRequiredFields_nothrow( _rEvent.Source ) )
3487 return sal_True;
3489 OSL_ENSURE( m_pColumnInfoCache.get(), "FmXFormController::approveRowChange: no column infos!" );
3490 if ( !m_pColumnInfoCache.get() )
3491 return sal_True;
3495 if ( !m_pColumnInfoCache->controlsInitialized() )
3496 m_pColumnInfoCache->initializeControls( getControls() );
3498 size_t colCount = m_pColumnInfoCache->getColumnCount();
3499 for ( size_t col = 0; col < colCount; ++col )
3501 const ColumnInfo& rColInfo = m_pColumnInfoCache->getColumnInfo( col );
3502 if ( rColInfo.nNullable != ColumnValue::NO_NULLS )
3503 continue;
3505 if ( rColInfo.bAutoIncrement )
3506 continue;
3508 if ( rColInfo.bReadOnly )
3509 continue;
3511 if ( !rColInfo.xFirstControlWithInputRequired.is() && !rColInfo.xFirstGridWithInputRequiredColumn.is() )
3512 continue;
3514 // TODO: in case of binary fields, this "getString" below is extremely expensive
3515 if ( rColInfo.xColumn->getString().getLength() || !rColInfo.xColumn->wasNull() )
3516 continue;
3518 String sMessage( SVX_RES( RID_ERR_FIELDREQUIRED ) );
3519 sMessage.SearchAndReplace( '#', rColInfo.sName );
3521 // the control to focus
3522 Reference< XControl > xControl( rColInfo.xFirstControlWithInputRequired );
3523 if ( !xControl.is() )
3524 xControl.set( rColInfo.xFirstGridWithInputRequiredColumn, UNO_QUERY );
3526 aGuard.clear();
3527 displayErrorSetFocus( sMessage, rColInfo.xFirstControlWithInputRequired, getDialogParentWindow() );
3528 return sal_False;
3531 catch( const Exception& )
3533 DBG_UNHANDLED_EXCEPTION();
3536 return true;
3539 //------------------------------------------------------------------------------
3540 sal_Bool SAL_CALL FmXFormController::approveCursorMove(const EventObject& event) throw( RuntimeException )
3542 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveCursorMove" );
3543 ::osl::MutexGuard aGuard( m_aMutex );
3544 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3545 ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3546 if (aIter.hasMoreElements())
3548 EventObject aEvt(event);
3549 aEvt.Source = *this;
3550 return ((XRowSetApproveListener*)aIter.next())->approveCursorMove(aEvt);
3553 return sal_True;
3556 //------------------------------------------------------------------------------
3557 sal_Bool SAL_CALL FmXFormController::approveRowSetChange(const EventObject& event) throw( RuntimeException )
3559 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveRowSetChange" );
3560 ::osl::MutexGuard aGuard( m_aMutex );
3561 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3562 ::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
3563 if (aIter.hasMoreElements())
3565 EventObject aEvt(event);
3566 aEvt.Source = *this;
3567 return ((XRowSetApproveListener*)aIter.next())->approveRowSetChange(aEvt);
3570 return sal_True;
3573 // XRowSetApproveBroadcaster
3574 //------------------------------------------------------------------------------
3575 void SAL_CALL FmXFormController::addRowSetApproveListener(const Reference< XRowSetApproveListener > & _rxListener) throw( RuntimeException )
3577 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addRowSetApproveListener" );
3578 ::osl::MutexGuard aGuard( m_aMutex );
3579 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3580 m_aRowSetApproveListeners.addInterface(_rxListener);
3583 //------------------------------------------------------------------------------
3584 void SAL_CALL FmXFormController::removeRowSetApproveListener(const Reference< XRowSetApproveListener > & _rxListener) throw( RuntimeException )
3586 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeRowSetApproveListener" );
3587 ::osl::MutexGuard aGuard( m_aMutex );
3588 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3589 m_aRowSetApproveListeners.removeInterface(_rxListener);
3592 // XErrorListener
3593 //------------------------------------------------------------------------------
3594 void SAL_CALL FmXFormController::errorOccured(const SQLErrorEvent& aEvent) throw( RuntimeException )
3596 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::errorOccured" );
3597 ::osl::ClearableMutexGuard aGuard( m_aMutex );
3598 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3600 ::cppu::OInterfaceIteratorHelper aIter(m_aErrorListeners);
3601 if (aIter.hasMoreElements())
3603 SQLErrorEvent aEvt(aEvent);
3604 aEvt.Source = *this;
3605 ((XSQLErrorListener*)aIter.next())->errorOccured(aEvt);
3607 else
3609 aGuard.clear();
3610 displayException( aEvent );
3614 // XErrorBroadcaster
3615 //------------------------------------------------------------------------------
3616 void SAL_CALL FmXFormController::addSQLErrorListener(const Reference< XSQLErrorListener > & aListener) throw( RuntimeException )
3618 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addSQLErrorListener" );
3619 ::osl::MutexGuard aGuard( m_aMutex );
3620 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3621 m_aErrorListeners.addInterface(aListener);
3624 //------------------------------------------------------------------------------
3625 void SAL_CALL FmXFormController::removeSQLErrorListener(const Reference< XSQLErrorListener > & aListener) throw( RuntimeException )
3627 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeSQLErrorListener" );
3628 ::osl::MutexGuard aGuard( m_aMutex );
3629 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3630 m_aErrorListeners.removeInterface(aListener);
3633 // XDatabaseParameterBroadcaster2
3634 //------------------------------------------------------------------------------
3635 void SAL_CALL FmXFormController::addDatabaseParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3637 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addDatabaseParameterListener" );
3638 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3639 m_aParameterListeners.addInterface(aListener);
3642 //------------------------------------------------------------------------------
3643 void SAL_CALL FmXFormController::removeDatabaseParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3645 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeDatabaseParameterListener" );
3646 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3647 m_aParameterListeners.removeInterface(aListener);
3650 // XDatabaseParameterBroadcaster
3651 //------------------------------------------------------------------------------
3652 void SAL_CALL FmXFormController::addParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3654 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addParameterListener" );
3655 FmXFormController::addDatabaseParameterListener( aListener );
3658 //------------------------------------------------------------------------------
3659 void SAL_CALL FmXFormController::removeParameterListener(const Reference< XDatabaseParameterListener > & aListener) throw( RuntimeException )
3661 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeParameterListener" );
3662 FmXFormController::removeDatabaseParameterListener( aListener );
3665 // XDatabaseParameterListener
3666 //------------------------------------------------------------------------------
3667 sal_Bool SAL_CALL FmXFormController::approveParameter(const DatabaseParameterEvent& aEvent) throw( RuntimeException )
3669 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::approveParameter" );
3670 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3672 ::cppu::OInterfaceIteratorHelper aIter(m_aParameterListeners);
3673 if (aIter.hasMoreElements())
3675 DatabaseParameterEvent aEvt(aEvent);
3676 aEvt.Source = *this;
3677 return ((XDatabaseParameterListener*)aIter.next())->approveParameter(aEvt);
3679 else
3681 // default handling: instantiate an interaction handler and let it handle the parameter request
3684 if ( !ensureInteractionHandler() )
3685 return sal_False;
3687 // two continuations allowed: OK and Cancel
3688 OParameterContinuation* pParamValues = new OParameterContinuation;
3689 OInteractionAbort* pAbort = new OInteractionAbort;
3690 // the request
3691 ParametersRequest aRequest;
3692 aRequest.Parameters = aEvent.Parameters;
3693 aRequest.Connection = OStaticDataAccessTools().getRowSetConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
3694 OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
3695 Reference< XInteractionRequest > xParamRequest(pParamRequest);
3696 // some knittings
3697 pParamRequest->addContinuation(pParamValues);
3698 pParamRequest->addContinuation(pAbort);
3700 // handle the request
3702 ::vos::OGuard aGuard(Application::GetSolarMutex());
3703 m_xInteractionHandler->handle(xParamRequest);
3706 if (!pParamValues->wasSelected())
3707 // canceled
3708 return sal_False;
3710 // transfer the values into the parameter supplier
3711 Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
3712 if (aFinalValues.getLength() != aRequest.Parameters->getCount())
3714 DBG_ERROR("FmXFormController::approveParameter: the InteractionHandler returned nonsense!");
3715 return sal_False;
3717 const PropertyValue* pFinalValues = aFinalValues.getConstArray();
3718 for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
3720 Reference< XPropertySet > xParam;
3721 ::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i));
3722 if (xParam.is())
3724 #ifdef DBG_UTIL
3725 ::rtl::OUString sName;
3726 xParam->getPropertyValue(FM_PROP_NAME) >>= sName;
3727 DBG_ASSERT(sName.equals(pFinalValues->Name), "FmXFormController::approveParameter: suspicious value names!");
3728 #endif
3729 try { xParam->setPropertyValue(FM_PROP_VALUE, pFinalValues->Value); }
3730 catch(Exception&)
3732 DBG_ERROR("FmXFormController::approveParameter: setting one of the properties failed!");
3737 catch(Exception&)
3739 DBG_ERROR("FmXFormController::approveParameter: caught an Exception (tried to let the InteractionHandler handle it)!");
3742 return sal_True;
3745 // XConfirmDeleteBroadcaster
3746 //------------------------------------------------------------------------------
3747 void SAL_CALL FmXFormController::addConfirmDeleteListener(const Reference< XConfirmDeleteListener > & aListener) throw( RuntimeException )
3749 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addConfirmDeleteListener" );
3750 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3751 m_aDeleteListeners.addInterface(aListener);
3754 //------------------------------------------------------------------------------
3755 void SAL_CALL FmXFormController::removeConfirmDeleteListener(const Reference< XConfirmDeleteListener > & aListener) throw( RuntimeException )
3757 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeConfirmDeleteListener" );
3758 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3759 m_aDeleteListeners.removeInterface(aListener);
3762 // XConfirmDeleteListener
3763 //------------------------------------------------------------------------------
3764 sal_Bool SAL_CALL FmXFormController::confirmDelete(const RowChangeEvent& aEvent) throw( RuntimeException )
3766 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::confirmDelete" );
3767 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3769 ::cppu::OInterfaceIteratorHelper aIter(m_aDeleteListeners);
3770 if (aIter.hasMoreElements())
3772 RowChangeEvent aEvt(aEvent);
3773 aEvt.Source = *this;
3774 return ((XConfirmDeleteListener*)aIter.next())->confirmDelete(aEvt);
3776 else
3778 // default handling
3779 UniString aTitle;
3780 sal_Int32 nLength = aEvent.Rows;
3781 if (nLength > 1)
3783 aTitle = SVX_RES(RID_STR_DELETECONFIRM_RECORDS);
3784 aTitle.SearchAndReplace('#', String::CreateFromInt32(nLength));
3786 else
3787 aTitle = SVX_RES(RID_STR_DELETECONFIRM_RECORD);
3789 ConfirmDeleteDialog aDlg(getDialogParentWindow(), aTitle);
3790 return RET_YES == aDlg.Execute();
3794 //------------------------------------------------------------------------------
3795 void FmXFormController::invalidateFeatures( const ::std::vector< sal_Int32 >& _rFeatures )
3797 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::invalidateFeatures" );
3798 ::osl::MutexGuard aGuard( m_aMutex );
3799 // for now, just copy the ids of the features, because ....
3800 ::std::copy( _rFeatures.begin(), _rFeatures.end(),
3801 ::std::insert_iterator< ::std::set< sal_Int32 > >( m_aInvalidFeatures, m_aInvalidFeatures.begin() )
3804 // ... we will do the real invalidation asynchronously
3805 if ( !m_aFeatureInvalidationTimer.IsActive() )
3806 m_aFeatureInvalidationTimer.Start();
3809 //------------------------------------------------------------------------------
3810 Reference< XDispatch >
3811 FmXFormController::interceptedQueryDispatch(sal_uInt16 /*_nId*/, const URL& aURL,
3812 const ::rtl::OUString& /*aTargetFrameName*/, sal_Int32 /*nSearchFlags*/)
3813 throw( RuntimeException )
3815 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::interceptedQueryDispatch" );
3816 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3817 Reference< XDispatch > xReturn;
3818 // dispatches handled by ourself
3819 if ( ( aURL.Complete == FMURL_CONFIRM_DELETION )
3820 || ( ( aURL.Complete.equalsAscii( "private:/InteractionHandler" ) )
3821 && ensureInteractionHandler()
3824 xReturn = static_cast< XDispatch* >( this );
3826 // dispatches of FormSlot-URLs we have to translate
3827 if ( !xReturn.is() && m_aControllerFeatures.isAssigned() )
3829 // find the slot id which corresponds to the URL
3830 sal_Int32 nFeatureId = ::svx::FeatureSlotTranslation::getControllerFeatureSlotIdForURL( aURL.Main );
3831 if ( nFeatureId > 0 )
3833 // get the dispatcher for this feature, create if necessary
3834 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( nFeatureId );
3835 if ( aDispatcherPos == m_aFeatureDispatchers.end() )
3837 aDispatcherPos = m_aFeatureDispatchers.insert(
3838 DispatcherContainer::value_type( nFeatureId, new ::svx::OSingleFeatureDispatcher( aURL, nFeatureId, *m_aControllerFeatures, m_aMutex ) )
3839 ).first;
3842 OSL_ENSURE( aDispatcherPos->second.is(), "FmXFormController::interceptedQueryDispatch: should have a dispatcher by now!" );
3843 return aDispatcherPos->second;
3847 // no more to offer
3848 return xReturn;
3851 //------------------------------------------------------------------------------
3852 void SAL_CALL FmXFormController::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArgs ) throw (RuntimeException)
3854 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::dispatch" );
3855 if ( _rArgs.getLength() != 1 )
3857 DBG_ERROR( "FmXFormController::dispatch: no arguments -> no dispatch!" );
3858 return;
3861 if ( _rURL.Complete.equalsAscii( "private:/InteractionHandler" ) )
3863 Reference< XInteractionRequest > xRequest;
3864 OSL_VERIFY( _rArgs[0].Value >>= xRequest );
3865 if ( xRequest.is() )
3866 handle( xRequest );
3867 return;
3870 if ( _rURL.Complete == FMURL_CONFIRM_DELETION )
3872 DBG_ERROR( "FmXFormController::dispatch: How do you expect me to return something via this call?" );
3873 // confirmDelete has a return value - dispatch hasn't
3874 return;
3877 DBG_ERROR( "FmXFormController::dispatch: unknown URL!" );
3880 //------------------------------------------------------------------------------
3881 void SAL_CALL FmXFormController::addStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
3883 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::addStatusListener" );
3884 if (_rURL.Complete == FMURL_CONFIRM_DELETION)
3886 if (_rxListener.is())
3887 { // send an initial statusChanged event
3888 FeatureStateEvent aEvent;
3889 aEvent.FeatureURL = _rURL;
3890 aEvent.IsEnabled = sal_True;
3891 _rxListener->statusChanged(aEvent);
3892 // and don't add the listener at all (the status will never change)
3895 else
3896 OSL_ENSURE(sal_False, "FmXFormController::addStatusListener: invalid (unsupported) URL!");
3899 //------------------------------------------------------------------------------
3900 void SAL_CALL FmXFormController::removeStatusListener( const Reference< XStatusListener >& /*_rxListener*/, const URL& _rURL ) throw (RuntimeException)
3902 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::removeStatusListener" );
3903 (void)_rURL;
3904 OSL_ENSURE(_rURL.Complete == FMURL_CONFIRM_DELETION, "FmXFormController::removeStatusListener: invalid (unsupported) URL!");
3905 // we never really added the listener, so we don't need to remove it
3908 //------------------------------------------------------------------------------
3909 Reference< XDispatchProviderInterceptor > FmXFormController::createInterceptor(const Reference< XDispatchProviderInterception > & _xInterception)
3911 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::createInterceptor" );
3912 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3913 #ifdef DBG_UTIL
3914 // check if we already have a interceptor for the given object
3915 for ( ConstInterceptorsIterator aIter = m_aControlDispatchInterceptors.begin();
3916 aIter != m_aControlDispatchInterceptors.end();
3917 ++aIter
3920 if ((*aIter)->getIntercepted() == _xInterception)
3921 DBG_ERROR("FmXFormController::createInterceptor : we already do intercept this objects dispatches !");
3923 #endif
3925 ::rtl::OUString sInterceptorScheme(RTL_CONSTASCII_USTRINGPARAM("*"));
3926 FmXDispatchInterceptorImpl* pInterceptor = new FmXDispatchInterceptorImpl(_xInterception, this, 0, Sequence< ::rtl::OUString >(&sInterceptorScheme, 1));
3927 pInterceptor->acquire();
3928 m_aControlDispatchInterceptors.insert(m_aControlDispatchInterceptors.end(), pInterceptor);
3930 return (XDispatchProviderInterceptor*)pInterceptor;
3933 //------------------------------------------------------------------------------
3934 bool FmXFormController::ensureInteractionHandler()
3936 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::ensureInteractionHandler" );
3937 if ( m_xInteractionHandler.is() )
3938 return true;
3939 if ( m_bAttemptedHandlerCreation )
3940 return false;
3941 m_bAttemptedHandlerCreation = true;
3942 if ( !m_xORB.is() )
3943 return false;
3945 m_xInteractionHandler.set( m_xORB->createInstance( SRV_SDB_INTERACTION_HANDLER ), UNO_QUERY );
3946 OSL_ENSURE( m_xInteractionHandler.is(), "FmXFormController::ensureInteractionHandler: could not create an interaction handler!" );
3947 return m_xInteractionHandler.is();
3950 //------------------------------------------------------------------------------
3951 void SAL_CALL FmXFormController::handle( const Reference< XInteractionRequest >& _rRequest ) throw (RuntimeException)
3953 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::handle" );
3954 if ( !ensureInteractionHandler() )
3955 return;
3956 m_xInteractionHandler->handle( _rRequest );
3959 //------------------------------------------------------------------------------
3960 void FmXFormController::deleteInterceptor(const Reference< XDispatchProviderInterception > & _xInterception)
3962 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::deleteInterceptor" );
3963 OSL_ENSURE( !impl_isDisposed_nofail(), "FmXFormController: already disposed!" );
3964 // search the interceptor responsible for the given object
3965 InterceptorsIterator aIter;
3966 for ( aIter = m_aControlDispatchInterceptors.begin();
3967 aIter != m_aControlDispatchInterceptors.end();
3968 ++aIter
3971 if ((*aIter)->getIntercepted() == _xInterception)
3972 break;
3974 if (aIter == m_aControlDispatchInterceptors.end())
3976 return;
3979 // log off the interception from it's interception object
3980 FmXDispatchInterceptorImpl* pInterceptorImpl = *aIter;
3981 pInterceptorImpl->dispose();
3982 pInterceptorImpl->release();
3984 // remove the interceptor from our array
3985 m_aControlDispatchInterceptors.erase(aIter);
3988 //--------------------------------------------------------------------
3989 void SAL_CALL FmXFormController::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
3991 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::initialize" );
3992 DBG_ASSERT( !m_xInteractionHandler.is(), "FmXFormController::initialize: already initialized!" );
3993 // currently, we only initialize our interaction handler here, so it's sufficient to assert this
3995 ::comphelper::NamedValueCollection aArgs( aArguments );
3996 m_xInteractionHandler = aArgs.getOrDefault( "InteractionHandler", m_xInteractionHandler );
3999 //--------------------------------------------------------------------
4000 void FmXFormController::implInvalidateCurrentControlDependentFeatures()
4002 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::implInvalidateCurrentControlDependentFeatures" );
4003 ::std::vector< sal_Int32 > aCurrentControlDependentFeatures;
4005 aCurrentControlDependentFeatures.push_back( SID_FM_SORTUP );
4006 aCurrentControlDependentFeatures.push_back( SID_FM_SORTDOWN );
4007 aCurrentControlDependentFeatures.push_back( SID_FM_AUTOFILTER );
4008 aCurrentControlDependentFeatures.push_back( SID_FM_REFRESH_FORM_CONTROL );
4010 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
4011 m_pView->GetFormShell()->GetImpl()->invalidateFeatures( aCurrentControlDependentFeatures );
4012 invalidateFeatures( aCurrentControlDependentFeatures );
4015 //--------------------------------------------------------------------
4016 void SAL_CALL FmXFormController::columnChanged( const EventObject& /*_event*/ ) throw (RuntimeException)
4018 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormController::columnChanged" );
4019 implInvalidateCurrentControlDependentFeatures();