LCOV - code coverage report
Current view: top level - svx/source/form - formcontroller.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 473 2010 23.5 %
Date: 2014-11-03 Functions: 52 202 25.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10