LCOV - code coverage report
Current view: top level - svx/source/unodraw - unoshcol.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 66 76 86.8 %
Date: 2015-06-13 12:38:46 Functions: 18 20 90.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             : #include <com/sun/star/document/EventObject.hpp>
      21             : #include <com/sun/star/drawing/XShapes.hpp>
      22             : #include <com/sun/star/lang/XComponent.hpp>
      23             : #include <com/sun/star/lang/XServiceInfo.hpp>
      24             : #include <com/sun/star/uno/XComponentContext.hpp>
      25             : 
      26             : #include <cppuhelper/implbase3.hxx>
      27             : #include <cppuhelper/interfacecontainer.hxx>
      28             : #include <cppuhelper/supportsservice.hxx>
      29             : #include <osl/mutex.hxx>
      30             : #include <rtl/ref.hxx>
      31             : #include <svx/unoprov.hxx>
      32             : 
      33             : using namespace ::com::sun::star;
      34             : using namespace ::com::sun::star::uno;
      35             : 
      36             : namespace {
      37             : 
      38          90 : class SvxShapeCollectionMutex
      39             : {
      40             : public:
      41             :     ::osl::Mutex maMutex;
      42             : };
      43             : 
      44             : class SvxShapeCollection :
      45             :     public cppu::WeakAggImplHelper3<drawing::XShapes, lang::XServiceInfo, lang::XComponent>,
      46             :     public SvxShapeCollectionMutex
      47             : {
      48             : private:
      49             :     cppu::OInterfaceContainerHelper maShapeContainer;
      50             : 
      51             :     cppu::OBroadcastHelper mrBHelper;
      52             : 
      53             :     void disposing() throw();
      54             : 
      55             : public:
      56             :     SvxShapeCollection() throw();
      57             :     virtual ~SvxShapeCollection() throw();
      58             : 
      59             :     // XInterface
      60             :     virtual void SAL_CALL release() throw() SAL_OVERRIDE;
      61             : 
      62             :     // XComponent
      63             :     virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      64             :     virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      65             :     virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      66             : 
      67             :     // XIndexAccess
      68             :     virtual sal_Int32 SAL_CALL getCount() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE ;
      69             :     virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      70             : 
      71             :     // XElementAccess
      72             :     virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      73             :     virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      74             : 
      75             :     // XShapes
      76             :     virtual void SAL_CALL add( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      77             :     virtual void SAL_CALL remove( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      78             : 
      79             :     // XServiceInfo
      80             :     virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      81             :     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      82             :     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      83             : };
      84             : 
      85          49 : SvxShapeCollection::SvxShapeCollection() throw()
      86          49 : : maShapeContainer( maMutex ), mrBHelper( maMutex )
      87             : {
      88          49 : }
      89             : 
      90             : 
      91          82 : SvxShapeCollection::~SvxShapeCollection() throw()
      92             : {
      93          82 : }
      94             : 
      95             : // XInterface
      96         428 : void SvxShapeCollection::release() throw()
      97             : {
      98         428 :     uno::Reference< uno::XInterface > x( xDelegator );
      99         428 :     if (! x.is())
     100             :     {
     101         428 :         if (osl_atomic_decrement( &m_refCount ) == 0)
     102             :         {
     103          81 :             if (! mrBHelper.bDisposed)
     104             :             {
     105          40 :                 uno::Reference< uno::XInterface > xHoldAlive( static_cast<uno::XWeak*>(this) );
     106             :                 // First dispose
     107             :                 try
     108             :                 {
     109          40 :                     dispose();
     110             :                 }
     111           0 :                 catch(::com::sun::star::uno::Exception&)
     112             :                 {
     113             :                     // release should not throw exceptions
     114             :                 }
     115             : 
     116             :                 // only the alive ref holds the object
     117             :                 OSL_ASSERT( m_refCount == 1 );
     118             :                 // destroy the object if xHoldAlive decrement the refcount to 0
     119         468 :                 return;
     120             :             }
     121             :         }
     122             :         // restore the reference count
     123         388 :         osl_atomic_increment( &m_refCount );
     124             :     }
     125         388 :     OWeakAggObject::release();
     126             : }
     127             : 
     128             : // XComponent
     129          41 : void SvxShapeCollection::disposing() throw()
     130             : {
     131          41 :     maShapeContainer.clear();
     132          41 : }
     133             : 
     134             : // XComponent
     135          41 : void SvxShapeCollection::dispose()
     136             :     throw(::com::sun::star::uno::RuntimeException, std::exception)
     137             : {
     138             :     // An frequently programming error is to release the last
     139             :     // reference to this object in the disposing message.
     140             :     // Make it rubust, hold a self Reference.
     141          41 :     uno::Reference< lang::XComponent > xSelf( this );
     142             : 
     143             :     // Guard dispose against multible threading
     144             :     // Remark: It is an error to call dispose more than once
     145          41 :     bool bDoDispose = false;
     146             :     {
     147          41 :     osl::MutexGuard aGuard( mrBHelper.rMutex );
     148          41 :     if( !mrBHelper.bDisposed && !mrBHelper.bInDispose )
     149             :     {
     150             :         // only one call go into this section
     151          41 :         mrBHelper.bInDispose = sal_True;
     152          41 :         bDoDispose = true;
     153          41 :     }
     154             :     }
     155             : 
     156             :     // Do not hold the mutex because we are broadcasting
     157          41 :     if( bDoDispose )
     158             :     {
     159             :         // Create an event with this as sender
     160             :         try
     161             :         {
     162          41 :             uno::Reference< uno::XInterface > xSource( uno::Reference< uno::XInterface >::query( static_cast<lang::XComponent *>(this) ) );
     163          82 :             document::EventObject aEvt;
     164          41 :             aEvt.Source = xSource;
     165             :             // inform all listeners to release this object
     166             :             // The listener container are automatically cleared
     167          41 :             mrBHelper.aLC.disposeAndClear( aEvt );
     168             :             // notify subclasses to do their dispose
     169          82 :             disposing();
     170             :         }
     171           0 :         catch(const ::com::sun::star::uno::Exception&)
     172             :         {
     173             :             // catch exception and throw again but signal that
     174             :             // the object was disposed. Dispose should be called
     175             :             // only once.
     176           0 :             mrBHelper.bDisposed = sal_True;
     177           0 :             mrBHelper.bInDispose = sal_False;
     178           0 :             throw;
     179             :         }
     180             : 
     181             :         // the values bDispose and bInDisposing must set in this order.
     182             :         // No multithread call overcome the "!rBHelper.bDisposed && !rBHelper.bInDispose" guard.
     183          41 :         mrBHelper.bDisposed = sal_True;
     184          41 :         mrBHelper.bInDispose = sal_False;
     185             :     }
     186             :     else
     187             :     {
     188             :         // in a multithreaded environment, it can't be avoided, that dispose is called twice.
     189             :         // However this condition is traced, because it MAY indicate an error.
     190             :         OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" );
     191          41 :     }
     192          41 : }
     193             : 
     194             : // XComponent
     195          15 : void SAL_CALL SvxShapeCollection::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception)
     196             : {
     197          15 :     mrBHelper.addListener( cppu::UnoType<decltype(aListener)>::get() , aListener );
     198          15 : }
     199             : 
     200             : // XComponent
     201           0 : void SAL_CALL SvxShapeCollection::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception)
     202             : {
     203           0 :     mrBHelper.removeListener( cppu::UnoType<decltype(aListener)>::get() , aListener );
     204           0 : }
     205             : 
     206             : // XShapes
     207             : 
     208         145 : void SAL_CALL SvxShapeCollection::add( const Reference< drawing::XShape >& xShape ) throw( uno::RuntimeException, std::exception )
     209             : {
     210         145 :     maShapeContainer.addInterface( xShape );
     211         145 : }
     212             : 
     213             : 
     214           1 : void SAL_CALL SvxShapeCollection::remove( const uno::Reference< drawing::XShape >& xShape ) throw( uno::RuntimeException, std::exception )
     215             : {
     216           1 :     maShapeContainer.removeInterface( xShape );
     217           1 : }
     218             : 
     219             : 
     220         162 : sal_Int32 SAL_CALL SvxShapeCollection::getCount() throw( uno::RuntimeException, std::exception )
     221             : {
     222         162 :     return maShapeContainer.getLength();
     223             : }
     224             : 
     225             : 
     226         125 : uno::Any SAL_CALL SvxShapeCollection::getByIndex( sal_Int32 Index )
     227             :     throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
     228             : {
     229         125 :     if( Index < 0 || Index >= getCount() )
     230           1 :         throw lang::IndexOutOfBoundsException();
     231             : 
     232         124 :     uno::Sequence< Reference< uno::XInterface> > xElements( maShapeContainer.getElements() );
     233             : 
     234             : 
     235         124 :     return uno::makeAny( Reference< drawing::XShape>(static_cast< drawing::XShape* >( xElements.getArray()[Index].get())) );
     236             : }
     237             : 
     238             : // XElementAccess
     239           1 : uno::Type SAL_CALL SvxShapeCollection::getElementType() throw( uno::RuntimeException, std::exception )
     240             : {
     241           1 :     return cppu::UnoType<drawing::XShape>::get();
     242             : }
     243             : 
     244           1 : sal_Bool SAL_CALL SvxShapeCollection::hasElements() throw( uno::RuntimeException, std::exception )
     245             : {
     246           1 :     return getCount() != 0;
     247             : }
     248             : 
     249             : // XServiceInfo
     250           4 : OUString SAL_CALL SvxShapeCollection::getImplementationName()
     251             :     throw( uno::RuntimeException, std::exception )
     252             : {
     253           4 :     return OUString("com.sun.star.drawing.SvxShapeCollection");
     254             : }
     255             : 
     256           0 : sal_Bool SAL_CALL SvxShapeCollection::supportsService( const OUString& ServiceName )
     257             :     throw( uno::RuntimeException, std::exception )
     258             : {
     259           0 :     return cppu::supportsService( this, ServiceName);
     260             : }
     261             : 
     262           1 : uno::Sequence< OUString > SAL_CALL SvxShapeCollection::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
     263             : {
     264           1 :     uno::Sequence< OUString > aSeq(2);
     265           1 :     aSeq.getArray()[0] = "com.sun.star.drawing.Shapes";
     266           1 :     aSeq.getArray()[1] = "com.sun.star.drawing.ShapeCollection";
     267           1 :     return aSeq;
     268             : }
     269             : 
     270             : }
     271             : 
     272             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     273          49 : com_sun_star_drawing_SvxShapeCollection_get_implementation(
     274             :     css::uno::XComponentContext *,
     275             :     css::uno::Sequence<css::uno::Any> const &)
     276             : {
     277          49 :     return cppu::acquire(new SvxShapeCollection);
     278             : }
     279             : 
     280             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11