Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/unoidl/unocpres.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 <algorithm>
21
22
#include <com/sun/star/lang/DisposedException.hpp>
23
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
24
#include <o3tl/safeint.hxx>
25
#include <vcl/svapp.hxx>
26
#include <svx/svdpage.hxx>
27
#include <cppuhelper/supportsservice.hxx>
28
29
#include <createunocustomshow.hxx>
30
#include <unomodel.hxx>
31
#include <drawdoc.hxx>
32
#include "unocpres.hxx"
33
#include <cusshow.hxx>
34
#include <unopage.hxx>
35
#include <customshowlist.hxx>
36
37
using namespace ::com::sun::star;
38
39
uno::Reference< uno::XInterface > createUnoCustomShow( SdCustomShow* pShow )
40
0
{
41
0
    return static_cast<cppu::OWeakObject*>(new SdXCustomPresentation( pShow ));
42
0
}
43
44
SdXCustomPresentation::SdXCustomPresentation() noexcept
45
0
:   mpSdCustomShow(nullptr), mpModel(nullptr),
46
0
    bDisposing( false )
47
0
{
48
0
}
49
50
SdXCustomPresentation::SdXCustomPresentation( SdCustomShow* pShow) noexcept
51
0
:   mpSdCustomShow(pShow), mpModel(nullptr),
52
0
    bDisposing( false )
53
0
{
54
0
}
55
56
SdXCustomPresentation::~SdXCustomPresentation() noexcept
57
0
{
58
0
}
59
60
// XServiceInfo
61
OUString SAL_CALL SdXCustomPresentation::getImplementationName()
62
0
{
63
0
    return u"SdXCustomPresentation"_ustr ;
64
0
}
65
66
sal_Bool SAL_CALL SdXCustomPresentation::supportsService( const OUString& ServiceName )
67
0
{
68
0
    return cppu::supportsService( this, ServiceName );
69
0
}
70
71
uno::Sequence< OUString > SAL_CALL SdXCustomPresentation::getSupportedServiceNames()
72
0
{
73
0
    return { u"com.sun.star.presentation.CustomPresentation"_ustr };
74
0
}
75
76
// XIndexContainer
77
void SAL_CALL SdXCustomPresentation::insertByIndex( sal_Int32 Index, const uno::Any& Element )
78
0
{
79
0
    SolarMutexGuard aGuard;
80
81
0
    if( bDisposing )
82
0
        throw lang::DisposedException();
83
84
0
    if( Index < 0 || o3tl::make_unsigned(Index) > ( mpSdCustomShow ? mpSdCustomShow->PagesVector().size() : 0 ) )
85
0
        throw lang::IndexOutOfBoundsException();
86
87
0
    uno::Reference< drawing::XDrawPage > xPage;
88
0
    Element >>= xPage;
89
90
0
    if(!xPage.is())
91
0
        throw lang::IllegalArgumentException();
92
93
0
    SdDrawPage* pPage = comphelper::getFromUnoTunnel<SdDrawPage>( xPage );
94
95
0
    if(pPage)
96
0
    {
97
0
        if (!mpModel)
98
0
            mpModel = pPage->GetModel();
99
100
0
        if (!mpSdCustomShow)
101
0
            mpSdCustomShow = new SdCustomShow;
102
103
0
        mpSdCustomShow->PagesVector().insert(mpSdCustomShow->PagesVector().begin() + Index,
104
0
            static_cast<SdPage*>(pPage->GetSdrPage()));
105
0
    }
106
107
0
    if( mpModel )
108
0
        mpModel->SetModified();
109
0
}
110
111
void SAL_CALL SdXCustomPresentation::removeByIndex( sal_Int32 Index )
112
0
{
113
0
    SolarMutexGuard aGuard;
114
115
0
    if( bDisposing )
116
0
        throw lang::DisposedException();
117
118
0
    if(mpSdCustomShow)
119
0
    {
120
0
        uno::Reference< drawing::XDrawPage > xPage;
121
0
        getByIndex( Index ) >>= xPage;
122
123
0
        if( xPage.is() )
124
0
        {
125
0
            SvxDrawPage* pPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage );
126
0
            if(pPage)
127
0
            {
128
0
                SdCustomShow::PageVec::iterator it = std::find(
129
0
                    mpSdCustomShow->PagesVector().begin(),
130
0
                    mpSdCustomShow->PagesVector().end(),
131
0
                    pPage->GetSdrPage());
132
0
                if (it != mpSdCustomShow->PagesVector().end())
133
0
                    mpSdCustomShow->PagesVector().erase(it);
134
0
            }
135
0
        }
136
0
    }
137
138
0
    if( mpModel )
139
0
        mpModel->SetModified();
140
0
}
141
142
// XIndexReplace
143
void SAL_CALL SdXCustomPresentation::replaceByIndex( sal_Int32 Index, const uno::Any& Element )
144
0
{
145
0
    removeByIndex( Index );
146
0
    insertByIndex( Index, Element );
147
0
}
148
149
// XElementAccess
150
uno::Type SAL_CALL SdXCustomPresentation::getElementType()
151
0
{
152
0
    return cppu::UnoType<drawing::XDrawPage>::get();
153
0
}
154
155
sal_Bool SAL_CALL SdXCustomPresentation::hasElements()
156
0
{
157
0
    SolarMutexGuard aGuard;
158
159
0
    if( bDisposing )
160
0
        throw lang::DisposedException();
161
162
0
    return getCount() > 0;
163
0
}
164
165
// XIndexAccess
166
sal_Int32 SAL_CALL SdXCustomPresentation::getCount()
167
0
{
168
0
    SolarMutexGuard aGuard;
169
0
    if( bDisposing )
170
0
        throw lang::DisposedException();
171
172
0
    return mpSdCustomShow ? mpSdCustomShow->PagesVector().size() : 0;
173
0
}
174
175
uno::Any SAL_CALL SdXCustomPresentation::getByIndex( sal_Int32 Index )
176
0
{
177
0
    SolarMutexGuard aGuard;
178
179
0
    if( bDisposing )
180
0
        throw lang::DisposedException();
181
182
0
    if (Index < 0 || !mpSdCustomShow || o3tl::make_unsigned(Index) >= mpSdCustomShow->PagesVector().size())
183
0
        throw lang::IndexOutOfBoundsException();
184
185
0
    uno::Any aAny;
186
0
    SdrPage * pPage = const_cast<SdPage *>(mpSdCustomShow->PagesVector()[Index]);
187
188
0
    if( pPage )
189
0
    {
190
0
        uno::Reference< drawing::XDrawPage > xRef( pPage->getUnoPage(), uno::UNO_QUERY );
191
0
        aAny <<= xRef;
192
0
    }
193
194
0
    return aAny;
195
0
}
196
197
// XNamed
198
OUString SAL_CALL SdXCustomPresentation::getName()
199
0
{
200
0
    SolarMutexGuard aGuard;
201
202
0
    if( bDisposing )
203
0
        throw lang::DisposedException();
204
205
0
    if(mpSdCustomShow)
206
0
        return mpSdCustomShow->GetName();
207
208
0
    return OUString();
209
0
}
210
211
void SAL_CALL SdXCustomPresentation::setName( const OUString& aName )
212
0
{
213
0
    SolarMutexGuard aGuard;
214
215
0
    if( bDisposing )
216
0
        throw lang::DisposedException();
217
218
0
    if(mpSdCustomShow)
219
0
        mpSdCustomShow->SetName( aName );
220
0
}
221
222
// XComponent
223
void SAL_CALL SdXCustomPresentation::dispose()
224
0
{
225
0
    SolarMutexGuard aGuard;
226
227
0
    if( bDisposing )
228
0
        return; // caught a recursion
229
230
0
    bDisposing = true;
231
232
0
    uno::Reference< uno::XInterface > xSource( static_cast<cppu::OWeakObject*>(this) );
233
234
0
    std::unique_lock aGuard2(aDisposeContainerMutex);
235
0
    lang::EventObject aEvt;
236
0
    aEvt.Source = std::move(xSource);
237
0
    aDisposeListeners.disposeAndClear(aGuard2, aEvt);
238
239
0
    mpSdCustomShow = nullptr;
240
0
}
241
242
void SAL_CALL SdXCustomPresentation::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
243
0
{
244
0
    if( bDisposing )
245
0
        throw lang::DisposedException();
246
247
0
    std::unique_lock aGuard(aDisposeContainerMutex);
248
0
    aDisposeListeners.addInterface(aGuard, xListener);
249
0
}
250
251
void SAL_CALL SdXCustomPresentation::removeEventListener( const uno::Reference< lang::XEventListener >& aListener )
252
0
{
253
0
    if( !bDisposing )
254
0
    {
255
0
        std::unique_lock aGuard(aDisposeContainerMutex);
256
0
        aDisposeListeners.removeInterface(aGuard, aListener);
257
0
    }
258
0
}
259
260
/*===========================================================================*
261
 *  class SdXCustomPresentationAccess : public XCustomPresentationAccess,    *
262
 *                                      public UsrObject                     *
263
 *===========================================================================*/
264
265
SdXCustomPresentationAccess::SdXCustomPresentationAccess(SdXImpressDocument& rMyModel) noexcept
266
2
: mrModel(rMyModel)
267
2
{
268
2
}
269
270
SdXCustomPresentationAccess::~SdXCustomPresentationAccess() noexcept
271
2
{
272
2
}
273
274
// XServiceInfo
275
OUString SAL_CALL SdXCustomPresentationAccess::getImplementationName()
276
0
{
277
0
    return u"SdXCustomPresentationAccess"_ustr;
278
0
}
279
280
sal_Bool SAL_CALL SdXCustomPresentationAccess::supportsService( const OUString& ServiceName )
281
0
{
282
0
    return cppu::supportsService( this, ServiceName );
283
0
}
284
285
uno::Sequence< OUString > SAL_CALL SdXCustomPresentationAccess::getSupportedServiceNames()
286
0
{
287
0
    return { u"com.sun.star.presentation.CustomPresentationAccess"_ustr };
288
0
}
289
290
// XSingleServiceFactory
291
uno::Reference< uno::XInterface > SAL_CALL SdXCustomPresentationAccess::createInstance()
292
0
{
293
0
    uno::Reference< uno::XInterface >  xRef( static_cast<cppu::OWeakObject*>(new SdXCustomPresentation()) );
294
0
    return xRef;
295
0
}
296
297
uno::Reference< uno::XInterface > SAL_CALL SdXCustomPresentationAccess::createInstanceWithArguments( const uno::Sequence< uno::Any >& )
298
0
{
299
0
    return createInstance();
300
0
}
301
302
// XNameContainer
303
void SAL_CALL SdXCustomPresentationAccess::insertByName( const OUString& aName, const uno::Any& aElement )
304
0
{
305
0
    SolarMutexGuard aGuard;
306
307
    // get the documents custom show list
308
0
    SdCustomShowList* pList = nullptr;
309
0
    if(mrModel.GetDoc())
310
0
        pList = mrModel.GetDoc()->GetCustomShowList(true);
311
312
    // no list, no cookies
313
0
    if( nullptr == pList)
314
0
        throw uno::RuntimeException();
315
316
    // do we have a container::XIndexContainer?
317
0
    SdXCustomPresentation* pXShow = nullptr;
318
319
0
    uno::Reference< container::XIndexContainer > xContainer;
320
0
    if( (aElement >>= xContainer) && xContainer.is() )
321
0
        pXShow = dynamic_cast<SdXCustomPresentation*>(xContainer.get());
322
323
0
    if( nullptr == pXShow )
324
0
        throw lang::IllegalArgumentException();
325
326
    // get the internal custom show from the api wrapper
327
0
    SdCustomShow* pShow = pXShow->GetSdCustomShow();
328
0
    if( nullptr == pShow )
329
0
    {
330
0
        pShow = new SdCustomShow( xContainer );
331
0
        pXShow->SetSdCustomShow( pShow );
332
0
    }
333
0
    else
334
0
    {
335
0
        if( nullptr == pXShow->GetModel() || *pXShow->GetModel() != mrModel )
336
0
            throw lang::IllegalArgumentException();
337
0
    }
338
339
    // give it a name
340
0
    pShow->SetName( aName);
341
342
    // check if this or another customshow with the same name already exists
343
0
    for( SdCustomShow* pCompare = pList->First();
344
0
         pCompare;
345
0
         pCompare = pList->Next() )
346
0
    {
347
0
        if( pCompare == pShow || pCompare->GetName() == pShow->GetName() )
348
0
            throw container::ElementExistException();
349
0
    }
350
351
0
    pList->push_back(std::unique_ptr<SdCustomShow>(pShow));
352
353
0
    mrModel.SetModified();
354
0
}
355
356
void SAL_CALL SdXCustomPresentationAccess::removeByName( const OUString& Name )
357
0
{
358
0
    SolarMutexGuard aGuard;
359
360
0
    SdCustomShow* pShow = getSdCustomShow(Name);
361
362
0
    SdCustomShowList* pList = GetCustomShowList();
363
0
    if(!pList || !pShow)
364
0
        throw container::NoSuchElementException();
365
366
0
    pList->erase( pShow );
367
368
0
    mrModel.SetModified();
369
0
}
370
371
// XNameReplace
372
void SAL_CALL SdXCustomPresentationAccess::replaceByName( const OUString& aName, const uno::Any& aElement )
373
0
{
374
0
    removeByName( aName );
375
0
    insertByName( aName, aElement );
376
0
}
377
378
// XNameAccess
379
uno::Any SAL_CALL SdXCustomPresentationAccess::getByName( const OUString& aName )
380
0
{
381
0
    SolarMutexGuard aGuard;
382
383
0
    SdCustomShow* pShow = getSdCustomShow(aName);
384
0
    if(!pShow)
385
0
    {
386
0
        throw container::NoSuchElementException();
387
0
    }
388
389
0
    uno::Reference< container::XIndexContainer >  xRef( pShow->getUnoCustomShow(), uno::UNO_QUERY );
390
0
    return uno::Any(xRef);
391
0
}
392
393
uno::Sequence< OUString > SAL_CALL SdXCustomPresentationAccess::getElementNames()
394
0
{
395
0
    SolarMutexGuard aGuard;
396
397
0
    SdCustomShowList* pList = GetCustomShowList();
398
0
    const sal_uInt32 nCount = pList ? pList->size() : 0;
399
400
0
    uno::Sequence< OUString > aSequence( nCount );
401
0
    OUString* pStringList = aSequence.getArray();
402
403
0
    sal_uInt32 nIdx = 0;
404
0
    while( nIdx < nCount )
405
0
    {
406
0
        const SdCustomShow* pShow = (*pList)[nIdx].get();
407
0
        pStringList[nIdx] = pShow->GetName();
408
0
        nIdx++;
409
0
    }
410
411
0
    return aSequence;
412
0
}
413
414
sal_Bool SAL_CALL SdXCustomPresentationAccess::hasByName( const OUString& aName )
415
0
{
416
0
    SolarMutexGuard aGuard;
417
0
    return getSdCustomShow(aName) != nullptr;
418
0
}
419
420
// XElementAccess
421
uno::Type SAL_CALL SdXCustomPresentationAccess::getElementType()
422
0
{
423
0
    return cppu::UnoType<container::XIndexContainer>::get();
424
0
}
425
426
sal_Bool SAL_CALL SdXCustomPresentationAccess::hasElements()
427
0
{
428
0
    SolarMutexGuard aGuard;
429
430
0
    SdCustomShowList* pList = GetCustomShowList();
431
0
    return pList && !pList->empty();
432
0
}
433
434
SdCustomShow * SdXCustomPresentationAccess::getSdCustomShow( std::u16string_view rName ) const noexcept
435
0
{
436
0
    sal_uInt32 nIdx = 0;
437
438
0
    SdCustomShowList* pList = GetCustomShowList();
439
0
    const sal_uInt32 nCount = pList ? pList->size() : 0;
440
441
0
    while( nIdx < nCount )
442
0
    {
443
0
        SdCustomShow* pShow = (*pList)[nIdx].get();
444
0
        if( pShow->GetName() == rName )
445
0
            return pShow;
446
0
        nIdx++;
447
0
    }
448
0
    return nullptr;
449
0
}
450
451
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */