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