LCOV - code coverage report
Current view: top level - toolkit/source/controls - unocontrolcontainer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 258 358 72.1 %
Date: 2015-06-13 12:38:46 Functions: 47 60 78.3 %
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             : #include <com/sun/star/awt/XVclContainerPeer.hpp>
      21             : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
      22             : #include <com/sun/star/uno/XComponentContext.hpp>
      23             : 
      24             : #include <cppuhelper/typeprovider.hxx>
      25             : #include <cppuhelper/implbase1.hxx>
      26             : #include <rtl/uuid.h>
      27             : 
      28             : #include <toolkit/controls/unocontrolcontainer.hxx>
      29             : #include <toolkit/helper/property.hxx>
      30             : #include <toolkit/helper/servicenames.hxx>
      31             : #include <comphelper/sequence.hxx>
      32             : 
      33             : #include <tools/debug.hxx>
      34             : #include <vcl/svapp.hxx>
      35             : #include <vcl/window.hxx>
      36             : 
      37             : #include <limits>
      38             : #include <map>
      39             : #include <boost/shared_ptr.hpp>
      40             : #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
      41             : 
      42             : using namespace ::com::sun::star;
      43             : 
      44             : 
      45             : //  class UnoControlHolder
      46             : 
      47         236 : struct UnoControlHolder
      48             : {
      49             :     uno::Reference< awt::XControl > mxControl;
      50             :     OUString                 msName;
      51             : 
      52             : public:
      53         242 :     UnoControlHolder( const OUString& rName, const uno::Reference< awt::XControl > & rControl )
      54             :     :   mxControl( rControl ),
      55         242 :         msName( rName )
      56             :     {
      57         242 :     }
      58             : 
      59         175 :     inline const OUString&                   getName() const { return msName; }
      60         488 :     inline const uno::Reference< awt::XControl >&   getControl() const { return mxControl; }
      61             : };
      62             : 
      63             : class UnoControlHolderList
      64             : {
      65             : public:
      66             :     typedef sal_Int32                                       ControlIdentifier;
      67             : private:
      68             :     typedef ::boost::shared_ptr< UnoControlHolder >         ControlInfo;
      69             :     typedef ::std::map< ControlIdentifier, ControlInfo >    ControlMap;
      70             : 
      71             : private:
      72             :     ControlMap  maControls;
      73             : 
      74             : public:
      75             :     UnoControlHolderList();
      76             :     ~UnoControlHolderList();
      77             : 
      78             :     /** adds a control with the given name to the list
      79             :         @param _rxControl
      80             :             the control to add. Must not be <NULL/>
      81             :         @param _pBName
      82             :             the name of the control, or <NULL/> if an automatic name should be generated
      83             :         @return
      84             :             the identifier of the newly added control
      85             :     */
      86             :     ControlIdentifier   addControl( const uno::Reference< awt::XControl >& _rxControl, const OUString* _pName );
      87             : 
      88             :     /** determines whether or not the list is empty
      89             :     */
      90           0 :     inline bool         empty() const { return maControls.empty(); }
      91             : 
      92             :     /** retrieves all controls currently in the list
      93             :         @return
      94             :             the number of controls in the list
      95             :     */
      96             :     size_t  getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const;
      97             : 
      98             :     /** retrieves all identifiers of all controls currently in the list
      99             :         @return
     100             :             the number of controls in the list
     101             :     */
     102             :     size_t  getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const;
     103             : 
     104             :     /** returns the first control which is registered under the given name
     105             :     */
     106             :     uno::Reference< awt::XControl >
     107             :             getControlForName( const OUString& _rName ) const;
     108             : 
     109             :     /** returns the identifier which a control is registered for, or -1 if the control
     110             :             isn't registered
     111             :     */
     112             :     ControlIdentifier
     113             :             getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl );
     114             : 
     115             :     /** retrieves the control for a given id
     116             :         @param _nIdentifier
     117             :             the identifier for the control
     118             :         @param _out_rxControl
     119             :             takes the XControl upon successful return
     120             :         @return
     121             :             <TRUE/> if and only if a control with the given id is part of the list
     122             :     */
     123             :     bool    getControlForIdentifier( ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const;
     124             : 
     125             :     /** removes a control from the list, given by id
     126             :         @param _nId
     127             :             The identifier of the control to remove.
     128             :     */
     129             :     void    removeControlById( ControlIdentifier _nId );
     130             : 
     131             :     /** replaces a control from the list with another one
     132             :         @param _nId
     133             :             The identifier of the control to replace
     134             :         @param _rxNewControl
     135             :             the new control to put into the list
     136             :     */
     137             :     void    replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl );
     138             : 
     139             : private:
     140             :     /** adds a control
     141             :     @param _rxControl
     142             :         the control to add to the container
     143             :     @param _pName
     144             :         pointer to the name of the control. Might be <NULL/>, in this case, a name is generated.
     145             :     @return
     146             :         the identifier of the newly inserted control
     147             :     */
     148             :     ControlIdentifier impl_addControl(
     149             :         const uno::Reference< awt::XControl >& _rxControl,
     150             :         const OUString*  _pName
     151             :     );
     152             : 
     153             :     /** finds a free identifier
     154             :         @throw uno::RuntimeException
     155             :             if no free identifier can be found
     156             :     */
     157             :     ControlIdentifier impl_getFreeIdentifier_throw();
     158             : 
     159             :     /** finds a free name
     160             :         @throw uno::RuntimeException
     161             :             if no free name can be found
     162             :     */
     163             :     OUString impl_getFreeName_throw();
     164             : };
     165             : 
     166             : 
     167        2222 : UnoControlHolderList::UnoControlHolderList()
     168             : {
     169        2222 : }
     170             : 
     171             : 
     172        2214 : UnoControlHolderList::~UnoControlHolderList()
     173             : {
     174        2214 : }
     175             : 
     176             : 
     177         242 : UnoControlHolderList::ControlIdentifier UnoControlHolderList::addControl( const uno::Reference< awt::XControl >& _rxControl, const OUString* _pName )
     178             : {
     179         242 :     return impl_addControl( _rxControl, _pName );
     180             : }
     181             : 
     182             : 
     183        1242 : size_t UnoControlHolderList::getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const
     184             : {
     185        1242 :     _out_rControls.realloc( maControls.size() );
     186        1242 :     uno::Reference< awt::XControl >* pControls = _out_rControls.getArray();
     187        3975 :     for (   ControlMap::const_iterator loop = maControls.begin();
     188        2650 :             loop != maControls.end();
     189             :             ++loop, ++pControls
     190             :         )
     191          83 :         *pControls = loop->second->getControl();
     192        1242 :     return maControls.size();
     193             : }
     194             : 
     195             : 
     196           0 : size_t UnoControlHolderList::getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const
     197             : {
     198           0 :     _out_rIdentifiers.realloc( maControls.size() );
     199           0 :     sal_Int32* pIndentifiers = _out_rIdentifiers.getArray();
     200           0 :     for (   ControlMap::const_iterator loop = maControls.begin();
     201           0 :             loop != maControls.end();
     202             :             ++loop, ++pIndentifiers
     203             :         )
     204           0 :         *pIndentifiers = loop->first;
     205           0 :     return maControls.size();
     206             : }
     207             : 
     208             : 
     209         107 : uno::Reference< awt::XControl > UnoControlHolderList::getControlForName( const OUString& _rName ) const
     210             : {
     211         528 :     for (   ControlMap::const_iterator loop = maControls.begin();
     212         352 :             loop != maControls.end();
     213             :             ++loop
     214             :         )
     215         175 :         if ( loop->second->getName() == _rName )
     216         106 :             return loop->second->getControl();
     217           1 :     return uno::Reference< awt::XControl >();
     218             : }
     219             : 
     220             : 
     221         220 : UnoControlHolderList::ControlIdentifier UnoControlHolderList::getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl )
     222             : {
     223         909 :     for (   ControlMap::iterator loop = maControls.begin();
     224         606 :             loop != maControls.end();
     225             :             ++loop
     226             :         )
     227             :     {
     228         299 :         if ( loop->second->getControl().get() == _rxControl.get() )
     229         216 :             return loop->first;
     230             :     }
     231           4 :     return -1;
     232             : }
     233             : 
     234             : 
     235           0 : bool UnoControlHolderList::getControlForIdentifier( UnoControlHolderList::ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const
     236             : {
     237           0 :     ControlMap::const_iterator pos = maControls.find( _nIdentifier );
     238           0 :     if ( pos == maControls.end() )
     239           0 :         return false;
     240           0 :     _out_rxControl = pos->second->getControl();
     241           0 :     return true;
     242             : }
     243             : 
     244             : 
     245         216 : void UnoControlHolderList::removeControlById( UnoControlHolderList::ControlIdentifier _nId )
     246             : {
     247         216 :     ControlMap::iterator pos = maControls.find( _nId );
     248             :     DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::removeControlById: invalid id!" );
     249         216 :     if ( pos == maControls.end() )
     250         216 :         return;
     251             : 
     252         216 :     maControls.erase( pos );
     253             : }
     254             : 
     255             : 
     256           0 : void UnoControlHolderList::replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl )
     257             : {
     258             :     DBG_ASSERT( _rxNewControl.is(), "UnoControlHolderList::replaceControlById: invalid new control!" );
     259             : 
     260           0 :     ControlMap::iterator pos = maControls.find( _nId );
     261             :     DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::replaceControlById: invalid id!" );
     262           0 :     if ( pos == maControls.end() )
     263           0 :         return;
     264             : 
     265           0 :     pos->second.reset( new UnoControlHolder( pos->second->getName(), _rxNewControl ) );
     266             : }
     267             : 
     268             : 
     269         242 : UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const OUString* _pName )
     270             : {
     271             :     DBG_ASSERT( _rxControl.is(), "UnoControlHolderList::impl_addControl: invalid control!" );
     272             : 
     273         242 :     OUString sName = _pName ? *_pName : impl_getFreeName_throw();
     274         242 :     sal_Int32 nId = impl_getFreeIdentifier_throw();
     275             : 
     276         242 :     maControls[ nId ] = ControlInfo( new UnoControlHolder( sName, _rxControl ) );
     277         242 :     return nId;
     278             : }
     279             : 
     280             : 
     281         242 : UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_getFreeIdentifier_throw()
     282             : {
     283         350 :     for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
     284             :     {
     285         350 :         ControlMap::const_iterator existent = maControls.find( candidateId );
     286         350 :         if ( existent == maControls.end() )
     287         484 :             return candidateId;
     288             :     }
     289           0 :     throw uno::RuntimeException("out of identifiers" );
     290             : }
     291             : 
     292             : 
     293           0 : OUString UnoControlHolderList::impl_getFreeName_throw()
     294             : {
     295           0 :     OUString name( "control_" );
     296           0 :     for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
     297             :     {
     298           0 :         OUString candidateName( name + OUString::number( candidateId ) );
     299           0 :         ControlMap::const_iterator loop = maControls.begin();
     300           0 :         for ( ; loop != maControls.end(); ++loop )
     301             :         {
     302           0 :             if ( loop->second->getName() == candidateName )
     303           0 :                 break;
     304             :         }
     305           0 :         if ( loop == maControls.end() )
     306           0 :             return candidateName;
     307           0 :     }
     308           0 :     throw uno::RuntimeException("out of identifiers" );
     309             : }
     310             : 
     311             : //  Function to set the controls' visibility according
     312             : //  to the dialog's "Step" property
     313             : 
     314           4 : void implUpdateVisibility
     315             : (
     316             :     sal_Int32 nDialogStep,
     317             :     uno::Reference< awt::XControlContainer > xControlContainer
     318             : )
     319             : {
     320             :     uno::Sequence< uno::Reference< awt::XControl > >
     321           4 :         aCtrls = xControlContainer->getControls();
     322           4 :     const uno::Reference< awt::XControl >* pCtrls = aCtrls.getConstArray();
     323           4 :     sal_uInt32 nCtrls = aCtrls.getLength();
     324           4 :     bool bCompleteVisible = (nDialogStep == 0);
     325          11 :     for( sal_uInt32 n = 0; n < nCtrls; n++ )
     326             :     {
     327           7 :         uno::Reference< awt::XControl > xControl = pCtrls[ n ];
     328             : 
     329           7 :         bool bVisible = bCompleteVisible;
     330           7 :         if( !bVisible )
     331             :         {
     332           0 :             uno::Reference< awt::XControlModel > xModel( xControl->getModel() );
     333             :             uno::Reference< beans::XPropertySet > xPSet
     334           0 :                 ( xModel, uno::UNO_QUERY );
     335             :             uno::Reference< beans::XPropertySetInfo >
     336           0 :                 xInfo = xPSet->getPropertySetInfo();
     337           0 :             OUString aPropName( "Step" );
     338           0 :             sal_Int32 nControlStep = 0;
     339           0 :             if ( xInfo->hasPropertyByName( aPropName ) )
     340             :             {
     341           0 :                 uno::Any aVal = xPSet->getPropertyValue( aPropName );
     342           0 :                 aVal >>= nControlStep;
     343             :             }
     344           0 :             bVisible = (nControlStep == 0) || (nControlStep == nDialogStep);
     345             :         }
     346             : 
     347             :         uno::Reference< awt::XWindow> xWindow
     348          14 :             ( xControl, uno::UNO_QUERY );
     349           7 :         if( xWindow.is() )
     350           7 :             xWindow->setVisible( bVisible );
     351          11 :     }
     352           4 : }
     353             : 
     354             : 
     355             : 
     356             : //  class DialogStepChangedListener
     357             : 
     358             : typedef ::cppu::WeakImplHelper1< beans::XPropertyChangeListener > PropertyChangeListenerHelper;
     359             : 
     360           2 : class DialogStepChangedListener: public PropertyChangeListenerHelper
     361             : {
     362             : private:
     363             :     uno::Reference< awt::XControlContainer > mxControlContainer;
     364             : 
     365             : public:
     366           4 :     explicit DialogStepChangedListener( uno::Reference< awt::XControlContainer > xControlContainer )
     367           4 :         : mxControlContainer( xControlContainer ) {}
     368             : 
     369             :     // XEventListener
     370             :     virtual void SAL_CALL disposing( const  lang::EventObject& Source ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
     371             : 
     372             :     // XPropertyChangeListener
     373             :     virtual void SAL_CALL propertyChange( const  beans::PropertyChangeEvent& evt ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
     374             : 
     375             : };
     376             : 
     377           1 : void SAL_CALL DialogStepChangedListener::disposing( const  lang::EventObject& /*_rSource*/)
     378             :     throw( uno::RuntimeException, std::exception)
     379             : {
     380           1 :     mxControlContainer.clear();
     381           1 : }
     382             : 
     383           0 : void SAL_CALL DialogStepChangedListener::propertyChange( const  beans::PropertyChangeEvent& evt )
     384             :     throw( uno::RuntimeException, std::exception)
     385             : {
     386             :     // evt.PropertyName HAS to be "Step" because we only use the listener for that
     387           0 :     sal_Int32 nDialogStep = 0;
     388           0 :     evt.NewValue >>= nDialogStep;
     389           0 :     implUpdateVisibility( nDialogStep, mxControlContainer );
     390           0 : }
     391             : 
     392             : 
     393             : //  class UnoControlContainer
     394             : 
     395          87 : UnoControlContainer::UnoControlContainer()
     396             :     :UnoControlContainer_Base()
     397          87 :     ,maCListeners( *this )
     398             : {
     399          87 :     mpControls = new UnoControlHolderList;
     400          87 : }
     401             : 
     402        1026 : UnoControlContainer::UnoControlContainer(const uno::Reference< awt::XWindowPeer >& xP )
     403             :     :UnoControlContainer_Base()
     404        1026 :     ,maCListeners( *this )
     405             : {
     406        1026 :     setPeer( xP );
     407        1026 :     mbDisposePeer = false;
     408        1026 :     mpControls = new UnoControlHolderList;
     409        1026 : }
     410             : 
     411        3312 : UnoControlContainer::~UnoControlContainer()
     412             : {
     413        1105 :     DELETEZ( mpControls );
     414        2207 : }
     415             : 
     416         218 : void UnoControlContainer::ImplActivateTabControllers()
     417             : {
     418         218 :     sal_uInt32 nCount = maTabControllers.getLength();
     419         223 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     420             :     {
     421           5 :         maTabControllers.getArray()[n]->setContainer( this );
     422           5 :         maTabControllers.getArray()[n]->activateTabOrder();
     423             :     }
     424         218 : }
     425             : 
     426             : // lang::XComponent
     427        1109 : void UnoControlContainer::dispose(  ) throw(uno::RuntimeException, std::exception)
     428             : {
     429        1109 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     430             : 
     431        2218 :     lang::EventObject aDisposeEvent;
     432        1109 :     aDisposeEvent.Source = static_cast< uno::XAggregation* >( this );
     433             : 
     434             :     // Notify listeners about disposal of this Container (This is much faster if they
     435             :     // listen on the controls and the container).
     436        1109 :     maDisposeListeners.disposeAndClear( aDisposeEvent );
     437        1109 :     maCListeners.disposeAndClear( aDisposeEvent );
     438             : 
     439             : 
     440        2218 :     uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls();
     441        1109 :     uno::Reference< awt::XControl >* pCtrls = aCtrls.getArray();
     442        1109 :     uno::Reference< awt::XControl >* pCtrlsEnd = pCtrls + aCtrls.getLength();
     443             : 
     444        1129 :     for( ; pCtrls < pCtrlsEnd; ++pCtrls )
     445             :     {
     446          20 :         removingControl( *pCtrls );
     447             :         // Delete control
     448          20 :         (*pCtrls)->dispose();
     449             :     }
     450             : 
     451             : 
     452             :     // Delete all structures
     453        1109 :     DELETEZ( mpControls );
     454        1109 :     mpControls = new UnoControlHolderList;
     455             : 
     456        2218 :     UnoControlBase::dispose();
     457        1109 : }
     458             : 
     459             : // lang::XEventListener
     460         212 : void UnoControlContainer::disposing( const lang::EventObject& _rEvt ) throw(uno::RuntimeException, std::exception)
     461             : {
     462         212 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     463             : 
     464         424 :     uno::Reference< awt::XControl >  xControl( _rEvt.Source, uno::UNO_QUERY );
     465         212 :     if ( xControl.is() )
     466         209 :         removeControl( xControl );
     467             : 
     468         424 :     UnoControlBase::disposing( _rEvt );
     469         212 : }
     470             : 
     471             : // container::XContainer
     472         874 : void UnoControlContainer::addContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException, std::exception)
     473             : {
     474         874 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     475             : 
     476         874 :     maCListeners.addInterface( rxListener );
     477         874 : }
     478             : 
     479         873 : void UnoControlContainer::removeContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException, std::exception)
     480             : {
     481         873 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     482             : 
     483         873 :     maCListeners.removeInterface( rxListener );
     484         873 : }
     485             : 
     486             : 
     487           0 : ::sal_Int32 SAL_CALL UnoControlContainer::insert( const uno::Any& _rElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     488             : {
     489           0 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     490             : 
     491           0 :     uno::Reference< awt::XControl > xControl;
     492           0 :     if ( !( _rElement >>= xControl ) || !xControl.is() )
     493             :         throw lang::IllegalArgumentException(
     494             :             OUString( "Elements must support the XControl interface." ),
     495             :             *this,
     496             :             1
     497           0 :         );
     498             : 
     499           0 :     return impl_addControl( xControl, NULL );
     500             : }
     501             : 
     502           0 : void SAL_CALL UnoControlContainer::removeByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     503             : {
     504           0 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     505             : 
     506           0 :     uno::Reference< awt::XControl > xControl;
     507           0 :     if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
     508             :         throw container::NoSuchElementException(
     509             :             OUString( "There is no element with the given identifier." ),
     510             :             *this
     511           0 :         );
     512             : 
     513           0 :     impl_removeControl( _nIdentifier, xControl, NULL );
     514           0 : }
     515             : 
     516           0 : void SAL_CALL UnoControlContainer::replaceByIdentifer( ::sal_Int32 _nIdentifier, const uno::Any& _rElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     517             : {
     518           0 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     519             : 
     520           0 :     uno::Reference< awt::XControl > xExistentControl;
     521           0 :     if ( !mpControls->getControlForIdentifier( _nIdentifier, xExistentControl ) )
     522             :         throw container::NoSuchElementException(
     523             :             OUString( "There is no element with the given identifier." ),
     524             :             *this
     525           0 :         );
     526             : 
     527           0 :     uno::Reference< awt::XControl > xNewControl;
     528           0 :     if ( !( _rElement >>= xNewControl ) )
     529             :         throw lang::IllegalArgumentException(
     530             :             OUString( "Elements must support the XControl interface." ),
     531             :             *this,
     532             :             1
     533           0 :         );
     534             : 
     535           0 :     removingControl( xExistentControl );
     536             : 
     537           0 :     mpControls->replaceControlById( _nIdentifier, xNewControl );
     538             : 
     539           0 :     addingControl( xNewControl );
     540             : 
     541           0 :     impl_createControlPeerIfNecessary( xNewControl );
     542             : 
     543           0 :     if ( maCListeners.getLength() )
     544             :     {
     545           0 :         container::ContainerEvent aEvent;
     546           0 :         aEvent.Source = *this;
     547           0 :         aEvent.Accessor <<= _nIdentifier;
     548           0 :         aEvent.Element <<= xNewControl;
     549           0 :         aEvent.ReplacedElement <<= xExistentControl;
     550           0 :         maCListeners.elementReplaced( aEvent );
     551           0 :     }
     552           0 : }
     553             : 
     554           0 : uno::Any SAL_CALL UnoControlContainer::getByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     555             : {
     556           0 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     557             : 
     558           0 :     uno::Reference< awt::XControl > xControl;
     559           0 :     if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
     560           0 :         throw container::NoSuchElementException();
     561           0 :     return uno::makeAny( xControl );
     562             : }
     563             : 
     564           0 : uno::Sequence< ::sal_Int32 > SAL_CALL UnoControlContainer::getIdentifiers(  ) throw (uno::RuntimeException, std::exception)
     565             : {
     566           0 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     567             : 
     568           0 :     uno::Sequence< ::sal_Int32 > aIdentifiers;
     569           0 :     mpControls->getIdentifiers( aIdentifiers );
     570           0 :     return aIdentifiers;
     571             : }
     572             : 
     573             : // container::XElementAccess
     574           0 : uno::Type SAL_CALL UnoControlContainer::getElementType(  ) throw (uno::RuntimeException, std::exception)
     575             : {
     576           0 :     return cppu::UnoType<awt::XControlModel>::get();
     577             : }
     578             : 
     579           0 : sal_Bool SAL_CALL UnoControlContainer::hasElements(  ) throw (uno::RuntimeException, std::exception)
     580             : {
     581           0 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     582           0 :     return !mpControls->empty();
     583             : }
     584             : 
     585             : // awt::XControlContainer
     586           1 : void UnoControlContainer::setStatusText( const OUString& rStatusText ) throw(uno::RuntimeException, std::exception)
     587             : {
     588           1 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     589             : 
     590             :     // Descend the parent hierarchy
     591           2 :     uno::Reference< awt::XControlContainer >  xContainer( mxContext, uno::UNO_QUERY );
     592           1 :     if( xContainer.is() )
     593           1 :         xContainer->setStatusText( rStatusText );
     594           1 : }
     595             : 
     596        1242 : uno::Sequence< uno::Reference< awt::XControl > > UnoControlContainer::getControls(  ) throw(uno::RuntimeException, std::exception)
     597             : {
     598        1242 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     599        1242 :     uno::Sequence< uno::Reference< awt::XControl > > aControls;
     600        1242 :     mpControls->getControls( aControls );
     601        1242 :     return aControls;
     602             : }
     603             : 
     604         107 : uno::Reference< awt::XControl > UnoControlContainer::getControl( const OUString& rName ) throw(uno::RuntimeException, std::exception)
     605             : {
     606         107 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     607         107 :     return mpControls->getControlForName( rName );
     608             : }
     609             : 
     610         242 : void UnoControlContainer::addingControl( const uno::Reference< awt::XControl >& _rxControl )
     611             : {
     612         242 :     if ( _rxControl.is() )
     613             :     {
     614         242 :         uno::Reference< uno::XInterface > xThis;
     615         242 :         OWeakAggObject::queryInterface( cppu::UnoType<uno::XInterface>::get() ) >>= xThis;
     616             : 
     617         242 :         _rxControl->setContext( xThis );
     618         242 :         _rxControl->addEventListener( this );
     619             :     }
     620         242 : }
     621             : 
     622         242 : void UnoControlContainer::impl_createControlPeerIfNecessary( const uno::Reference< awt::XControl >& _rxControl )
     623             : {
     624             :     OSL_PRECOND( _rxControl.is(), "UnoControlContainer::impl_createControlPeerIfNecessary: invalid control, this will crash!" );
     625             : 
     626             :     // if the container already has a peer, then also create a peer for the control
     627         242 :     uno::Reference< awt::XWindowPeer > xMyPeer( getPeer() );
     628             : 
     629         242 :     if( xMyPeer.is() )
     630             :     {
     631         214 :         _rxControl->createPeer( NULL, xMyPeer );
     632         214 :         ImplActivateTabControllers();
     633         242 :     }
     634             : 
     635         242 : }
     636             : 
     637         242 : sal_Int32 UnoControlContainer::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const OUString* _pName )
     638             : {
     639         242 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     640         242 :     UnoControlHolderList::ControlIdentifier id = mpControls->addControl( _rxControl, _pName );
     641             : 
     642         242 :     addingControl( _rxControl );
     643             : 
     644         242 :     impl_createControlPeerIfNecessary( _rxControl );
     645             : 
     646         242 :     if ( maCListeners.getLength() )
     647             :     {
     648         104 :         container::ContainerEvent aEvent;
     649         104 :         aEvent.Source = *this;
     650         104 :         _pName ? ( aEvent.Accessor <<= *_pName ) : ( aEvent.Accessor <<= (sal_Int32)id );
     651         104 :         aEvent.Element <<= _rxControl;
     652         104 :         maCListeners.elementInserted( aEvent );
     653             :     }
     654             : 
     655         242 :     return id;
     656             : }
     657             : 
     658         243 : void UnoControlContainer::addControl( const OUString& rName, const uno::Reference< awt::XControl >& rControl ) throw(uno::RuntimeException, std::exception)
     659             : {
     660         243 :     if ( rControl.is() )
     661         242 :         impl_addControl( rControl, &rName );
     662         243 : }
     663             : 
     664         236 : void UnoControlContainer::removingControl( const uno::Reference< awt::XControl >& _rxControl )
     665             : {
     666         236 :     if ( _rxControl.is() )
     667             :     {
     668         236 :         _rxControl->removeEventListener( this );
     669         236 :         _rxControl->setContext( NULL );
     670             :     }
     671         236 : }
     672             : 
     673         216 : void UnoControlContainer::impl_removeControl( sal_Int32 _nId, const uno::Reference< awt::XControl >& _rxControl, const OUString* _pNameAccessor )
     674             : {
     675             : #ifdef DBG_UTIL
     676             :     {
     677             :         uno::Reference< awt::XControl > xControl;
     678             :         bool bHas = mpControls->getControlForIdentifier( _nId, xControl );
     679             :         DBG_ASSERT( bHas && xControl == _rxControl, "UnoControlContainer::impl_removeControl: inconsistency in the parameters!" );
     680             :     }
     681             : #endif
     682         216 :     removingControl( _rxControl );
     683             : 
     684         216 :     mpControls->removeControlById( _nId );
     685             : 
     686         216 :     if ( maCListeners.getLength() )
     687             :     {
     688          68 :         container::ContainerEvent aEvent;
     689          68 :         aEvent.Source = *this;
     690          68 :         _pNameAccessor ? ( aEvent.Accessor <<= *_pNameAccessor ) : ( aEvent.Accessor <<= _nId );
     691          68 :         aEvent.Element <<= _rxControl;
     692          68 :         maCListeners.elementRemoved( aEvent );
     693             :     }
     694         216 : }
     695             : 
     696         220 : void UnoControlContainer::removeControl( const uno::Reference< awt::XControl >& _rxControl ) throw(uno::RuntimeException, std::exception)
     697             : {
     698         220 :     if ( _rxControl.is() )
     699             :     {
     700         220 :         ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     701             : 
     702         220 :         UnoControlHolderList::ControlIdentifier id = mpControls->getControlIdentifier( _rxControl );
     703         220 :         if ( id != -1 )
     704         216 :             impl_removeControl( id, _rxControl, NULL );
     705             :     }
     706         220 : }
     707             : 
     708             : 
     709             : 
     710             : // awt::XUnoControlContainer
     711           1 : void UnoControlContainer::setTabControllers( const uno::Sequence< uno::Reference< awt::XTabController > >& TabControllers ) throw(uno::RuntimeException, std::exception)
     712             : {
     713           1 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     714             : 
     715           1 :     maTabControllers = TabControllers;
     716           1 : }
     717             : 
     718           7 : uno::Sequence< uno::Reference< awt::XTabController > > UnoControlContainer::getTabControllers(  ) throw(uno::RuntimeException, std::exception)
     719             : {
     720           7 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     721             : 
     722           7 :     return maTabControllers;
     723             : }
     724             : 
     725           9 : void UnoControlContainer::addTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException, std::exception)
     726             : {
     727           9 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     728             : 
     729           9 :     sal_uInt32 nCount = maTabControllers.getLength();
     730           9 :     maTabControllers.realloc( nCount + 1 );
     731           9 :     maTabControllers[ nCount ] = TabController;
     732           9 : }
     733             : 
     734           7 : void UnoControlContainer::removeTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException, std::exception)
     735             : {
     736           7 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     737             : 
     738           7 :     sal_uInt32 nCount = maTabControllers.getLength();
     739           7 :     const uno::Reference< awt::XTabController >* pLoop = maTabControllers.getConstArray();
     740           7 :     for ( sal_uInt32 n = 0; n < nCount; ++n, ++pLoop )
     741             :     {
     742           6 :         if( pLoop->get() == TabController.get() )
     743             :         {
     744           6 :             ::comphelper::removeElementAt( maTabControllers, n );
     745           6 :             break;
     746             :         }
     747           7 :     }
     748           7 : }
     749             : 
     750             : // awt::XControl
     751        1029 : void UnoControlContainer::createPeer( const uno::Reference< awt::XToolkit >& rxToolkit, const uno::Reference< awt::XWindowPeer >& rParent ) throw(uno::RuntimeException, std::exception)
     752             : {
     753        1029 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     754             : 
     755        1029 :     if( !getPeer().is() )
     756             :     {
     757           4 :         bool bVis = maComponentInfos.bVisible;
     758           4 :         if( bVis )
     759           2 :             UnoControl::setVisible( sal_False );
     760             : 
     761             :         uno::Reference< beans::XPropertySet > xTmpPropSet
     762           4 :                 ( getModel(), uno::UNO_QUERY );
     763             : 
     764             :         // Create a new peer
     765           4 :         UnoControl::createPeer( rxToolkit, rParent );
     766             : 
     767             :         // Create all children's peers
     768           4 :         if ( !mbCreatingCompatiblePeer )
     769             :         {
     770             :             // Evaluate "Step" property
     771           4 :             uno::Reference< awt::XControlModel > xModel( getModel() );
     772             :             uno::Reference< beans::XPropertySet > xPSet
     773           8 :                 ( xModel, uno::UNO_QUERY );
     774             :             uno::Reference< beans::XPropertySetInfo >
     775           8 :                 xInfo = xPSet->getPropertySetInfo();
     776           8 :             OUString aPropName( "Step" );
     777           4 :             if ( xInfo->hasPropertyByName( aPropName ) )
     778             :             {
     779           4 :                 ::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName );
     780           4 :                 sal_Int32 nDialogStep = 0;
     781           4 :                 aVal >>= nDialogStep;
     782             :                 uno::Reference< awt::XControlContainer > xContainer =
     783           8 :                     (static_cast< awt::XControlContainer* >(this));
     784           4 :                 implUpdateVisibility( nDialogStep, xContainer );
     785             : 
     786             :                 uno::Reference< beans::XPropertyChangeListener > xListener =
     787             :                     (static_cast< beans::XPropertyChangeListener* >(
     788           8 :                         new DialogStepChangedListener( xContainer ) ) );
     789           8 :                 xPSet->addPropertyChangeListener( aPropName, xListener );
     790             :             }
     791             : 
     792           8 :             uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls();
     793           4 :             sal_uInt32 nCtrls = aCtrls.getLength();
     794          11 :             for( sal_uInt32 n = 0; n < nCtrls; n++ )
     795           7 :                 aCtrls.getArray()[n]->createPeer( rxToolkit, getPeer() );
     796             : 
     797           8 :             uno::Reference< awt::XVclContainerPeer >  xC( getPeer(), uno::UNO_QUERY );
     798           4 :             if ( xC.is() )
     799           4 :                 xC->enableDialogControl( sal_True );
     800           8 :             ImplActivateTabControllers();
     801             :         }
     802             : 
     803           4 :         if( bVis && !isDesignMode() )
     804           2 :             UnoControl::setVisible( sal_True );
     805        1029 :     }
     806        1029 : }
     807             : 
     808             : 
     809             : // awt::XWindow
     810           3 : void UnoControlContainer::setVisible( sal_Bool bVisible ) throw(uno::RuntimeException, std::exception)
     811             : {
     812           3 :     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
     813             : 
     814           3 :     UnoControl::setVisible( bVisible );
     815           3 :     if( !mxContext.is() && bVisible )
     816             :         // This is a Topwindow, thus show it automatically
     817           1 :         createPeer( uno::Reference< awt::XToolkit > (), uno::Reference< awt::XWindowPeer > () );
     818           3 : }
     819             : 
     820           2 : OUString UnoControlContainer::getImplementationName()
     821             :     throw (css::uno::RuntimeException, std::exception)
     822             : {
     823           2 :     return OUString("stardiv.Toolkit.UnoControlContainer");
     824             : }
     825             : 
     826           1 : css::uno::Sequence<OUString> UnoControlContainer::getSupportedServiceNames()
     827             :     throw (css::uno::RuntimeException, std::exception)
     828             : {
     829           1 :     auto s(UnoControlBase::getSupportedServiceNames());
     830           1 :     s.realloc(s.getLength() + 2);
     831           1 :     s[s.getLength() - 2] = "com.sun.star.awt.UnoControlContainer";
     832           1 :     s[s.getLength() - 1] = "stardiv.vcl.control.ControlContainer";
     833           1 :     return s;
     834             : }
     835             : 
     836           4 : void UnoControlContainer::PrepareWindowDescriptor( ::com::sun::star::awt::WindowDescriptor& rDesc )
     837             : {
     838             :     // HACK due to the fact that we can't really use VSCROLL & HSCROLL
     839             :     // for Dialog  ( ::com::sun::star::awt::VclWindowPeerAttribute::VSCROLL
     840             :     // has the same value as
     841             :     // ::com::sun::star::awt::WindowAttribute::NODECORATION )
     842             :     // For convenience in the PropBrowse using HSCROLL and VSCROLL ensures
     843             :     // the Correct text. We exchange them here and the control knows
     844             :     // about this hack ( it sucks badly I know )
     845           4 :     if ( rDesc.WindowAttributes & ::com::sun::star::awt::VclWindowPeerAttribute::VSCROLL )
     846             :     {
     847           0 :        rDesc.WindowAttributes &= ~::com::sun::star::awt::VclWindowPeerAttribute::VSCROLL;
     848           0 :        rDesc.WindowAttributes |= ::com::sun::star::awt::VclWindowPeerAttribute::AUTOVSCROLL;
     849             :     }
     850           4 :     if ( rDesc.WindowAttributes & ::com::sun::star::awt::VclWindowPeerAttribute::HSCROLL )
     851             :     {
     852           0 :        rDesc.WindowAttributes &= ~::com::sun::star::awt::VclWindowPeerAttribute::HSCROLL;
     853           0 :        rDesc.WindowAttributes |= ::com::sun::star::awt::VclWindowPeerAttribute::AUTOHSCROLL;
     854             :     }
     855           4 : }
     856             : 
     857             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     858          77 : stardiv_Toolkit_UnoControlContainer_get_implementation(
     859             :     css::uno::XComponentContext *,
     860             :     css::uno::Sequence<css::uno::Any> const &)
     861             : {
     862          77 :     return cppu::acquire(new UnoControlContainer());
     863             : }
     864             : 
     865             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11