/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: */ |