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