LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/svx/source/form - formcontroller.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 473 2021 23.4 %
Date: 2013-07-09 Functions: 52 202 25.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10