Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/unodraw/unoshcol.cxx
Line
Count
Source
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/lang/IndexOutOfBoundsException.hpp>
22
#include <com/sun/star/uno/XComponentContext.hpp>
23
24
#include <cppuhelper/supportsservice.hxx>
25
#include <osl/diagnose.h>
26
#include <sal/log.hxx>
27
#include <shapecollection.hxx>
28
29
using namespace ::com::sun::star;
30
using namespace ::com::sun::star::uno;
31
32
SvxShapeCollection::SvxShapeCollection() noexcept
33
2.45k
{
34
2.45k
}
35
36
// XInterface
37
void SvxShapeCollection::release() noexcept
38
12.2k
{
39
12.2k
    uno::Reference< uno::XInterface > x( xDelegator );
40
12.2k
    if (! x.is())
41
12.2k
    {
42
12.2k
        if (osl_atomic_decrement( &m_refCount ) == 0)
43
4.91k
        {
44
4.91k
            if (! bDisposed)
45
2.45k
            {
46
2.45k
                uno::Reference< uno::XInterface > xHoldAlive( getXWeak() );
47
                // First dispose
48
2.45k
                try
49
2.45k
                {
50
2.45k
                    dispose();
51
2.45k
                }
52
2.45k
                catch(css::uno::Exception&)
53
2.45k
                {
54
                    // release should not throw exceptions
55
0
                }
56
57
                // only the alive ref holds the object
58
2.45k
                OSL_ASSERT( m_refCount == 1 );
59
                // destroy the object if xHoldAlive decrement the refcount to 0
60
2.45k
                return;
61
2.45k
            }
62
4.91k
        }
63
        // restore the reference count
64
9.82k
        osl_atomic_increment( &m_refCount );
65
9.82k
    }
66
9.82k
    OWeakAggObject::release();
67
9.82k
}
68
69
// XComponent
70
void SvxShapeCollection::dispose()
71
2.45k
{
72
    // An frequently programming error is to release the last
73
    // reference to this object in the disposing message.
74
    // Make it robust, hold a self Reference.
75
2.45k
    uno::Reference< lang::XComponent > xSelf( this );
76
77
    // Guard dispose against multiple threading
78
    // Remark: It is an error to call dispose more than once
79
2.45k
    {
80
2.45k
        std::unique_lock aGuard( m_aMutex );
81
2.45k
        if( bDisposed || bInDispose )
82
0
            return;
83
        // only one call go into this section
84
2.45k
        bInDispose = true;
85
2.45k
    }
86
87
    // Do not hold the mutex because we are broadcasting
88
    // Create an event with this as sender
89
0
    try
90
2.45k
    {
91
2.45k
        document::EventObject aEvt;
92
2.45k
        aEvt.Source = uno::Reference< uno::XInterface >::query( static_cast<lang::XComponent *>(this) );
93
        // inform all listeners to release this object
94
        // The listener container are automatically cleared
95
2.45k
        std::unique_lock g(m_aMutex);
96
2.45k
        maEventListeners.disposeAndClear( g, aEvt );
97
2.45k
        maShapeContainer.clear();
98
99
        // bDisposed and bInDispose must be set in this order.
100
2.45k
        bDisposed = true;
101
2.45k
        bInDispose = false;
102
2.45k
    }
103
2.45k
    catch(const css::uno::Exception&)
104
2.45k
    {
105
        // catch exception and throw again but signal that
106
        // the object was disposed. Dispose should be called
107
        // only once.
108
0
        bDisposed = true;
109
0
        bInDispose = false;
110
0
        throw;
111
0
    }
112
2.45k
}
113
114
// XComponent
115
void SAL_CALL SvxShapeCollection::addEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
116
0
{
117
0
    std::unique_lock g(m_aMutex);
118
0
    maEventListeners.addInterface( g, aListener );
119
0
}
120
121
// XComponent
122
void SAL_CALL SvxShapeCollection::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
123
0
{
124
0
    std::unique_lock g(m_aMutex);
125
0
    maEventListeners.removeInterface( g, aListener );
126
0
}
127
128
// XShapes
129
130
void SAL_CALL SvxShapeCollection::add( const Reference< drawing::XShape >& xShape )
131
0
{
132
0
    std::unique_lock g(m_aMutex);
133
0
    maShapeContainer.push_back( xShape );
134
0
}
135
136
137
void SAL_CALL SvxShapeCollection::remove( const uno::Reference< drawing::XShape >& xShape )
138
0
{
139
0
    std::unique_lock g(m_aMutex);
140
0
    std::erase(maShapeContainer, xShape);
141
0
}
142
143
144
sal_Int32 SAL_CALL SvxShapeCollection::getCount()
145
2.45k
{
146
2.45k
    std::unique_lock g(m_aMutex);
147
2.45k
    return maShapeContainer.size();
148
2.45k
}
149
150
uno::Any SAL_CALL SvxShapeCollection::getByIndex( sal_Int32 Index )
151
0
{
152
0
    if( Index < 0 || Index >= getCount() )
153
0
        throw lang::IndexOutOfBoundsException();
154
155
0
    std::unique_lock g(m_aMutex);
156
0
    Reference<drawing::XShape> xShape = maShapeContainer[Index];
157
0
    return uno::Any( xShape );
158
0
}
159
160
std::vector<css::uno::Reference<css::drawing::XShape>> SvxShapeCollection::getAllShapes() const
161
0
{
162
0
    std::unique_lock g(m_aMutex);
163
0
    return maShapeContainer;
164
0
}
165
166
// XElementAccess
167
uno::Type SAL_CALL SvxShapeCollection::getElementType()
168
0
{
169
0
    return cppu::UnoType<drawing::XShape>::get();
170
0
}
171
172
sal_Bool SAL_CALL SvxShapeCollection::hasElements()
173
0
{
174
0
    return getCount() != 0;
175
0
}
176
177
// XServiceInfo
178
OUString SAL_CALL SvxShapeCollection::getImplementationName()
179
0
{
180
0
    return u"com.sun.star.drawing.SvxShapeCollection"_ustr;
181
0
}
182
183
sal_Bool SAL_CALL SvxShapeCollection::supportsService( const OUString& ServiceName )
184
0
{
185
0
    return cppu::supportsService( this, ServiceName);
186
0
}
187
188
uno::Sequence< OUString > SAL_CALL SvxShapeCollection::getSupportedServiceNames()
189
0
{
190
0
    return { u"com.sun.star.drawing.Shapes"_ustr, u"com.sun.star.drawing.ShapeCollection"_ustr };
191
0
}
192
193
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
194
com_sun_star_drawing_SvxShapeCollection_get_implementation(
195
    css::uno::XComponentContext *,
196
    css::uno::Sequence<css::uno::Any> const &)
197
2.45k
{
198
2.45k
    return cppu::acquire(new SvxShapeCollection);
199
2.45k
}
200
201
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */