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

Generated by: LCOV version 1.10