LCOV - code coverage report
Current view: top level - svx/source/form - formcontroller.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 2007 0.0 %
Date: 2014-04-14 Functions: 0 202 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10