1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svx.hxx" 30*cdf0e10cSrcweir #include <com/sun/star/document/EventObject.hpp> 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include "svx/unoshcol.hxx" 33*cdf0e10cSrcweir #include <svx/unoprov.hxx> 34*cdf0e10cSrcweir #include <comphelper/serviceinfohelper.hxx> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir using namespace ::cppu; 37*cdf0e10cSrcweir using namespace ::com::sun::star; 38*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 39*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 40*cdf0e10cSrcweir using namespace ::com::sun::star::container; 41*cdf0e10cSrcweir using namespace ::com::sun::star::drawing; 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir /*********************************************************************** 44*cdf0e10cSrcweir * * 45*cdf0e10cSrcweir ***********************************************************************/ 46*cdf0e10cSrcweir SvxShapeCollection::SvxShapeCollection() throw() 47*cdf0e10cSrcweir : maShapeContainer( maMutex ), mrBHelper( maMutex ) 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir } 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir //---------------------------------------------------------------------- 52*cdf0e10cSrcweir SvxShapeCollection::~SvxShapeCollection() throw() 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir } 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir //---------------------------------------------------------------------- 58*cdf0e10cSrcweir Reference< uno::XInterface > SvxShapeCollection_NewInstance() throw() 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir Reference< drawing::XShapes > xShapes( new SvxShapeCollection() ); 61*cdf0e10cSrcweir Reference< uno::XInterface > xRef( xShapes, UNO_QUERY ); 62*cdf0e10cSrcweir return xRef; 63*cdf0e10cSrcweir } 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir // XInterface 66*cdf0e10cSrcweir void SvxShapeCollection::release() throw() 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir uno::Reference< uno::XInterface > x( xDelegator ); 69*cdf0e10cSrcweir if (! x.is()) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir if (osl_decrementInterlockedCount( &m_refCount ) == 0) 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir if (! mrBHelper.bDisposed) 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir uno::Reference< uno::XInterface > xHoldAlive( (uno::XWeak*)this ); 76*cdf0e10cSrcweir // First dispose 77*cdf0e10cSrcweir try 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir dispose(); 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir catch(::com::sun::star::uno::Exception&) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir // release should not throw exceptions 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir // only the alive ref holds the object 87*cdf0e10cSrcweir OSL_ASSERT( m_refCount == 1 ); 88*cdf0e10cSrcweir // destroy the object if xHoldAlive decrement the refcount to 0 89*cdf0e10cSrcweir return; 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir // restore the reference count 93*cdf0e10cSrcweir osl_incrementInterlockedCount( &m_refCount ); 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir OWeakAggObject::release(); 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir // XComponent 99*cdf0e10cSrcweir void SvxShapeCollection::disposing() throw() 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir maShapeContainer.clear(); 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir // XComponent 105*cdf0e10cSrcweir void SvxShapeCollection::dispose() 106*cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir // An frequently programming error is to release the last 109*cdf0e10cSrcweir // reference to this object in the disposing message. 110*cdf0e10cSrcweir // Make it rubust, hold a self Reference. 111*cdf0e10cSrcweir uno::Reference< lang::XComponent > xSelf( this ); 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir // Guard dispose against multible threading 114*cdf0e10cSrcweir // Remark: It is an error to call dispose more than once 115*cdf0e10cSrcweir sal_Bool bDoDispose = sal_False; 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir osl::MutexGuard aGuard( mrBHelper.rMutex ); 118*cdf0e10cSrcweir if( !mrBHelper.bDisposed && !mrBHelper.bInDispose ) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir // only one call go into this section 121*cdf0e10cSrcweir mrBHelper.bInDispose = sal_True; 122*cdf0e10cSrcweir bDoDispose = sal_True; 123*cdf0e10cSrcweir } 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir // Do not hold the mutex because we are broadcasting 127*cdf0e10cSrcweir if( bDoDispose ) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir // Create an event with this as sender 130*cdf0e10cSrcweir try 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir uno::Reference< uno::XInterface > xSource( uno::Reference< uno::XInterface >::query( (lang::XComponent *)this ) ); 133*cdf0e10cSrcweir document::EventObject aEvt; 134*cdf0e10cSrcweir aEvt.Source = xSource; 135*cdf0e10cSrcweir // inform all listeners to release this object 136*cdf0e10cSrcweir // The listener container are automaticly cleared 137*cdf0e10cSrcweir mrBHelper.aLC.disposeAndClear( aEvt ); 138*cdf0e10cSrcweir // notify subclasses to do their dispose 139*cdf0e10cSrcweir disposing(); 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir catch(::com::sun::star::uno::Exception& e) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir // catch exception and throw again but signal that 144*cdf0e10cSrcweir // the object was disposed. Dispose should be called 145*cdf0e10cSrcweir // only once. 146*cdf0e10cSrcweir mrBHelper.bDisposed = sal_True; 147*cdf0e10cSrcweir mrBHelper.bInDispose = sal_False; 148*cdf0e10cSrcweir throw e; 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir // the values bDispose and bInDisposing must set in this order. 152*cdf0e10cSrcweir // No multithread call overcome the "!rBHelper.bDisposed && !rBHelper.bInDispose" guard. 153*cdf0e10cSrcweir mrBHelper.bDisposed = sal_True; 154*cdf0e10cSrcweir mrBHelper.bInDispose = sal_False; 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir else 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir // in a multithreaded environment, it can't be avoided, that dispose is called twice. 159*cdf0e10cSrcweir // However this condition is traced, because it MAY indicate an error. 160*cdf0e10cSrcweir OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" ); 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir // XComponent 165*cdf0e10cSrcweir void SAL_CALL SvxShapeCollection::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException) 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir mrBHelper.addListener( ::getCppuType( &aListener ) , aListener ); 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir // XComponent 171*cdf0e10cSrcweir void SAL_CALL SvxShapeCollection::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir mrBHelper.removeListener( ::getCppuType( &aListener ) , aListener ); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir // XShapes 177*cdf0e10cSrcweir //---------------------------------------------------------------------- 178*cdf0e10cSrcweir void SAL_CALL SvxShapeCollection::add( const Reference< drawing::XShape >& xShape ) throw( uno::RuntimeException ) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir maShapeContainer.addInterface( xShape ); 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir //---------------------------------------------------------------------- 184*cdf0e10cSrcweir void SAL_CALL SvxShapeCollection::remove( const uno::Reference< drawing::XShape >& xShape ) throw( uno::RuntimeException ) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir maShapeContainer.removeInterface( xShape ); 187*cdf0e10cSrcweir } 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir //---------------------------------------------------------------------- 190*cdf0e10cSrcweir sal_Int32 SAL_CALL SvxShapeCollection::getCount() throw( uno::RuntimeException ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir return maShapeContainer.getLength(); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir //---------------------------------------------------------------------- 196*cdf0e10cSrcweir uno::Any SAL_CALL SvxShapeCollection::getByIndex( sal_Int32 Index ) 197*cdf0e10cSrcweir throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException ) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir if( Index < 0 || Index >= getCount() ) 200*cdf0e10cSrcweir throw lang::IndexOutOfBoundsException(); 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir uno::Sequence< Reference< uno::XInterface> > xElements( maShapeContainer.getElements() ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir return uno::makeAny( Reference< XShape>(static_cast< drawing::XShape* >( xElements.getArray()[Index].get())) ); 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir // XElementAccess 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir //---------------------------------------------------------------------- 211*cdf0e10cSrcweir uno::Type SAL_CALL SvxShapeCollection::getElementType() throw( uno::RuntimeException ) 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir return ::getCppuType(( const Reference< drawing::XShape >*)0); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir //---------------------------------------------------------------------- 217*cdf0e10cSrcweir sal_Bool SAL_CALL SvxShapeCollection::hasElements() throw( uno::RuntimeException ) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir return getCount() != 0; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir //---------------------------------------------------------------------- 223*cdf0e10cSrcweir // XServiceInfo 224*cdf0e10cSrcweir //---------------------------------------------------------------------- 225*cdf0e10cSrcweir ::rtl::OUString SAL_CALL SvxShapeCollection::getImplementationName() 226*cdf0e10cSrcweir throw( uno::RuntimeException ) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir return getImplementationName_Static(); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir ::rtl::OUString SvxShapeCollection::getImplementationName_Static() 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.SvxShapeCollection") ); 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir sal_Bool SAL_CALL SvxShapeCollection::supportsService( const ::rtl::OUString& ServiceName ) 237*cdf0e10cSrcweir throw( uno::RuntimeException ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() ); 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > SAL_CALL SvxShapeCollection::getSupportedServiceNames() throw( uno::RuntimeException ) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir return getSupportedServiceNames_Static(); 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > SvxShapeCollection::getSupportedServiceNames_Static() 248*cdf0e10cSrcweir { 249*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > aSeq(2); 250*cdf0e10cSrcweir aSeq.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Shapes") ); 251*cdf0e10cSrcweir aSeq.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ShapeCollection") ); 252*cdf0e10cSrcweir return aSeq; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir Reference< XInterface > SAL_CALL SvxShapeCollection_createInstance( const Reference< ::com::sun::star::lang::XMultiServiceFactory >& ) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir return *( new SvxShapeCollection() ); 258*cdf0e10cSrcweir } 259