LibreOffice Module svx (master) 1
unoshcol.cxx
Go to the documentation of this file.
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/IndexOutOfBoundsException.hpp>
23#include <com/sun/star/lang/XComponent.hpp>
24#include <com/sun/star/lang/XServiceInfo.hpp>
25#include <com/sun/star/uno/XComponentContext.hpp>
26
32#include <osl/mutex.hxx>
33#include <sal/log.hxx>
34
35using namespace ::com::sun::star;
36using namespace ::com::sun::star::uno;
37
38namespace {
39
40class SvxShapeCollection :
41 public cppu::BaseMutex,
42 public cppu::WeakAggImplHelper3<drawing::XShapes, lang::XServiceInfo, lang::XComponent>
43{
44private:
46
47 cppu::OBroadcastHelper mrBHelper;
48
49public:
50 SvxShapeCollection() noexcept;
51
52 // XInterface
53 virtual void SAL_CALL release() noexcept override;
54
55 // XComponent
56 virtual void SAL_CALL dispose() override;
57 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override;
58 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override;
59
60 // XIndexAccess
61 virtual sal_Int32 SAL_CALL getCount() override ;
62 virtual css::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override;
63
64 // XElementAccess
65 virtual css::uno::Type SAL_CALL getElementType() override;
66 virtual sal_Bool SAL_CALL hasElements() override;
67
68 // XShapes
69 virtual void SAL_CALL add( const css::uno::Reference< css::drawing::XShape >& xShape ) override;
70 virtual void SAL_CALL remove( const css::uno::Reference< css::drawing::XShape >& xShape ) override;
71
72 // XServiceInfo
73 virtual OUString SAL_CALL getImplementationName() override;
74 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
75 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
76};
77
78SvxShapeCollection::SvxShapeCollection() noexcept
79: maShapeContainer( m_aMutex ), mrBHelper( m_aMutex )
80{
81}
82
83// XInterface
84void SvxShapeCollection::release() noexcept
85{
86 uno::Reference< uno::XInterface > x( xDelegator );
87 if (! x.is())
88 {
89 if (osl_atomic_decrement( &m_refCount ) == 0)
90 {
91 if (! mrBHelper.bDisposed)
92 {
93 uno::Reference< uno::XInterface > xHoldAlive( static_cast<uno::XWeak*>(this) );
94 // First dispose
95 try
96 {
97 dispose();
98 }
99 catch(css::uno::Exception&)
100 {
101 // release should not throw exceptions
102 }
103
104 // only the alive ref holds the object
105 OSL_ASSERT( m_refCount == 1 );
106 // destroy the object if xHoldAlive decrement the refcount to 0
107 return;
108 }
109 }
110 // restore the reference count
111 osl_atomic_increment( &m_refCount );
112 }
114}
115
116// XComponent
117void SvxShapeCollection::dispose()
118{
119 // An frequently programming error is to release the last
120 // reference to this object in the disposing message.
121 // Make it robust, hold a self Reference.
122 uno::Reference< lang::XComponent > xSelf( this );
123
124 // Guard dispose against multiple threading
125 // Remark: It is an error to call dispose more than once
126 bool bDoDispose = false;
127 {
128 osl::MutexGuard aGuard( mrBHelper.rMutex );
129 if( !mrBHelper.bDisposed && !mrBHelper.bInDispose )
130 {
131 // only one call go into this section
132 mrBHelper.bInDispose = true;
133 bDoDispose = true;
134 }
135 }
136
137 // Do not hold the mutex because we are broadcasting
138 if( bDoDispose )
139 {
140 // Create an event with this as sender
141 try
142 {
143 uno::Reference< uno::XInterface > xSource( uno::Reference< uno::XInterface >::query( static_cast<lang::XComponent *>(this) ) );
144 document::EventObject aEvt;
145 aEvt.Source = xSource;
146 // inform all listeners to release this object
147 // The listener container are automatically cleared
148 mrBHelper.aLC.disposeAndClear( aEvt );
149 maShapeContainer.clear();
150 }
151 catch(const css::uno::Exception&)
152 {
153 // catch exception and throw again but signal that
154 // the object was disposed. Dispose should be called
155 // only once.
156 mrBHelper.bDisposed = true;
157 mrBHelper.bInDispose = false;
158 throw;
159 }
160
161 // the values bDispose and bInDisposing must set in this order.
162 // No multithread call overcome the "!rBHelper.bDisposed && !rBHelper.bInDispose" guard.
163 mrBHelper.bDisposed = true;
164 mrBHelper.bInDispose = false;
165 }
166 else
167 {
168 // in a multithreaded environment, it can't be avoided, that dispose is called twice.
169 // However this condition is traced, because it MAY indicate an error.
170 SAL_INFO("svx", "dispose called twice" );
171 }
172}
173
174// XComponent
175void SAL_CALL SvxShapeCollection::addEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
176{
177 mrBHelper.addListener( cppu::UnoType<decltype(aListener)>::get() , aListener );
178}
179
180// XComponent
181void SAL_CALL SvxShapeCollection::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
182{
183 mrBHelper.removeListener( cppu::UnoType<decltype(aListener)>::get() , aListener );
184}
185
186// XShapes
187
188void SAL_CALL SvxShapeCollection::add( const Reference< drawing::XShape >& xShape )
189{
190 maShapeContainer.addInterface( xShape );
191}
192
193
194void SAL_CALL SvxShapeCollection::remove( const uno::Reference< drawing::XShape >& xShape )
195{
196 maShapeContainer.removeInterface( xShape );
197}
198
199
200sal_Int32 SAL_CALL SvxShapeCollection::getCount()
201{
202 return maShapeContainer.getLength();
203}
204
205
206uno::Any SAL_CALL SvxShapeCollection::getByIndex( sal_Int32 Index )
207{
208 if( Index < 0 || Index >= getCount() )
209 throw lang::IndexOutOfBoundsException();
210
211 Reference<drawing::XShape> xShape = maShapeContainer.getInterface(Index);
212 return uno::Any( xShape );
213}
214
215// XElementAccess
216uno::Type SAL_CALL SvxShapeCollection::getElementType()
217{
219}
220
221sal_Bool SAL_CALL SvxShapeCollection::hasElements()
222{
223 return getCount() != 0;
224}
225
226// XServiceInfo
227OUString SAL_CALL SvxShapeCollection::getImplementationName()
228{
229 return "com.sun.star.drawing.SvxShapeCollection";
230}
231
232sal_Bool SAL_CALL SvxShapeCollection::supportsService( const OUString& ServiceName )
233{
234 return cppu::supportsService( this, ServiceName);
235}
236
237uno::Sequence< OUString > SAL_CALL SvxShapeCollection::getSupportedServiceNames()
238{
239 return { "com.sun.star.drawing.Shapes", "com.sun.star.drawing.ShapeCollection" };
240}
241
242}
243
244extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
246 css::uno::XComponentContext *,
247 css::uno::Sequence<css::uno::Any> const &)
248{
249 return cppu::acquire(new SvxShapeCollection);
250}
251
252/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOIndex Index
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
const css::uno::Reference< ListenerT > & getInterface(sal_Int32 nIndex) const
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
css::uno::Type const & get()
float x
#define SAL_INFO(area, stream)
Type
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
void dispose()
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
unsigned char sal_Bool
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_drawing_SvxShapeCollection_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Definition: unoshcol.cxx:245