1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/lang/DisposedException.hpp>
21 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include "unolayer.hxx"
25 #include <comphelper/extract.hxx>
26 #include <editeng/unoipset.hxx>
27 #include <osl/diagnose.h>
28 #include <svl/itemprop.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svx/svdobj.hxx>
31 #include <cppuhelper/supportsservice.hxx>
33 // following ones for InsertSdPage()
34 #include <svx/svdlayer.hxx>
36 #include <DrawDocShell.hxx>
37 #include <drawdoc.hxx>
38 #include <unomodel.hxx>
39 #include <unoprnms.hxx>
40 #include <com/sun/star/lang/NoSupportException.hpp>
41 #include <svx/svdpool.hxx>
42 #include <FrameView.hxx>
43 #include <DrawViewShell.hxx>
45 #include <ViewShell.hxx>
46 #include <strings.hrc>
47 #include <sdresid.hxx>
49 #include "unowcntr.hxx"
50 #include <vcl/svapp.hxx>
52 using namespace ::com::sun::star
;
55 #define WID_LAYER_LOCKED 1
56 #define WID_LAYER_PRINTABLE 2
57 #define WID_LAYER_VISIBLE 3
58 #define WID_LAYER_NAME 4
59 #define WID_LAYER_TITLE 5
60 #define WID_LAYER_DESC 6
62 static const SvxItemPropertySet
* ImplGetSdLayerPropertySet()
64 static const SfxItemPropertyMapEntry aSdLayerPropertyMap_Impl
[] =
66 { u
"" UNO_NAME_LAYER_LOCKED
""_ustr
, WID_LAYER_LOCKED
, cppu::UnoType
<bool>::get(), 0, 0 },
67 { u
"" UNO_NAME_LAYER_PRINTABLE
""_ustr
, WID_LAYER_PRINTABLE
,cppu::UnoType
<bool>::get(), 0, 0 },
68 { u
"" UNO_NAME_LAYER_VISIBLE
""_ustr
, WID_LAYER_VISIBLE
, cppu::UnoType
<bool>::get(), 0, 0 },
69 { u
"" UNO_NAME_LAYER_NAME
""_ustr
, WID_LAYER_NAME
, ::cppu::UnoType
<OUString
>::get(), 0, 0 },
70 { u
"Title"_ustr
, WID_LAYER_TITLE
, ::cppu::UnoType
<OUString
>::get(), 0, 0 },
71 { u
"Description"_ustr
, WID_LAYER_DESC
, ::cppu::UnoType
<OUString
>::get(), 0, 0 },
73 static SvxItemPropertySet
aSDLayerPropertySet_Impl( aSdLayerPropertyMap_Impl
, SdrObject::GetGlobalDrawObjectItemPool() );
74 return &aSDLayerPropertySet_Impl
;
77 SdLayer::SdLayer(SdLayerManager
* pLayerManager_
, SdrLayer
* pSdrLayer_
)
78 : mxLayerManager(pLayerManager_
)
80 , pPropSet(ImplGetSdLayerPropertySet())
82 // no defaults possible yet, a "set" would overwrite existing information
83 // in view, which is currently needed for saving, because pLayer is not updated
87 SdLayer::~SdLayer() noexcept
92 OUString SAL_CALL
SdLayer::getImplementationName()
94 return u
"SdUnoLayer"_ustr
;
97 sal_Bool SAL_CALL
SdLayer::supportsService( const OUString
& ServiceName
)
99 return cppu::supportsService( this, ServiceName
);
102 uno::Sequence
< OUString
> SAL_CALL
SdLayer::getSupportedServiceNames()
104 return { u
"com.sun.star.drawing.Layer"_ustr
};
107 // beans::XPropertySet
108 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
SdLayer::getPropertySetInfo( )
110 SolarMutexGuard aGuard
;
111 return pPropSet
->getPropertySetInfo();
114 void SAL_CALL
SdLayer::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
116 SolarMutexGuard aGuard
;
118 if(pLayer
== nullptr || mxLayerManager
== nullptr)
119 throw lang::DisposedException();
121 const SfxItemPropertyMapEntry
* pEntry
= pPropSet
->getPropertyMapEntry(aPropertyName
);
123 switch( pEntry
? pEntry
->nWID
: -1 )
125 case WID_LAYER_LOCKED
:
127 pLayer
->SetLockedODF( cppu::any2bool(aValue
) );
128 set(LOCKED
, cppu::any2bool(aValue
)); // changes the View, if any exists
131 case WID_LAYER_PRINTABLE
:
133 pLayer
->SetPrintableODF( cppu::any2bool(aValue
) );
134 set(PRINTABLE
, cppu::any2bool(aValue
)); // changes the View, if any exists
137 case WID_LAYER_VISIBLE
:
139 pLayer
->SetVisibleODF( cppu::any2bool(aValue
) );
140 set(VISIBLE
, cppu::any2bool(aValue
)); // changes the View, if any exists
146 if(!(aValue
>>= aName
))
147 throw lang::IllegalArgumentException();
149 pLayer
->SetName(aName
);
150 mxLayerManager
->UpdateLayerView();
154 case WID_LAYER_TITLE
:
157 if(!(aValue
>>= sTitle
))
158 throw lang::IllegalArgumentException();
160 pLayer
->SetTitle(sTitle
);
166 OUString sDescription
;
167 if(!(aValue
>>= sDescription
))
168 throw lang::IllegalArgumentException();
170 pLayer
->SetDescription(sDescription
);
175 throw beans::UnknownPropertyException( aPropertyName
, static_cast<cppu::OWeakObject
*>(this));
178 if( mxLayerManager
->GetDocShell() )
179 mxLayerManager
->GetDocShell()->SetModified();
182 uno::Any SAL_CALL
SdLayer::getPropertyValue( const OUString
& PropertyName
)
184 SolarMutexGuard aGuard
;
186 if(pLayer
== nullptr || mxLayerManager
== nullptr)
187 throw lang::DisposedException();
189 const SfxItemPropertyMapEntry
* pEntry
= pPropSet
->getPropertyMapEntry(PropertyName
);
193 switch( pEntry
? pEntry
->nWID
: -1 )
195 case WID_LAYER_LOCKED
:
196 aValue
<<= get( LOCKED
);
198 case WID_LAYER_PRINTABLE
:
199 aValue
<<= get( PRINTABLE
);
201 case WID_LAYER_VISIBLE
:
202 aValue
<<= get( VISIBLE
);
206 OUString
aRet(pLayer
->GetName());
210 case WID_LAYER_TITLE
:
211 aValue
<<= pLayer
->GetTitle();
214 aValue
<<= pLayer
->GetDescription();
217 throw beans::UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
223 void SAL_CALL
SdLayer::addPropertyChangeListener( const OUString
& , const uno::Reference
< beans::XPropertyChangeListener
>& ) {}
224 void SAL_CALL
SdLayer::removePropertyChangeListener( const OUString
& , const uno::Reference
< beans::XPropertyChangeListener
>& ) {}
225 void SAL_CALL
SdLayer::addVetoableChangeListener( const OUString
& , const uno::Reference
< beans::XVetoableChangeListener
>& ) {}
226 void SAL_CALL
SdLayer::removeVetoableChangeListener( const OUString
& , const uno::Reference
< beans::XVetoableChangeListener
>& ) {}
228 bool SdLayer::get( LayerAttribute what
) noexcept
230 if(pLayer
&& mxLayerManager
.is())
232 // Try 1. is an arbitrary page open?
233 ::sd::View
*pView
= mxLayerManager
->GetView();
234 SdrPageView
* pSdrPageView
= nullptr;
236 pSdrPageView
= pView
->GetSdrPageView();
240 OUString aLayerName
= pLayer
->GetName();
243 case VISIBLE
: return pSdrPageView
->IsLayerVisible(aLayerName
);
244 case PRINTABLE
: return pSdrPageView
->IsLayerPrintable(aLayerName
);
245 case LOCKED
: return pSdrPageView
->IsLayerLocked(aLayerName
);
249 // Try 2. get info from FrameView
250 if(mxLayerManager
->GetDocShell())
252 ::sd::FrameView
*pFrameView
= mxLayerManager
->GetDocShell()->GetFrameView();
256 case VISIBLE
: return pFrameView
->GetVisibleLayers().IsSet(pLayer
->GetID());
257 case PRINTABLE
: return pFrameView
->GetPrintableLayers().IsSet(pLayer
->GetID());
258 case LOCKED
: return pFrameView
->GetLockedLayers().IsSet(pLayer
->GetID());
262 // no view at all, e.g. Draw embedded as OLE in text document, ODF default values
265 case VISIBLE
: return true;
266 case PRINTABLE
: return true;
267 case LOCKED
: return false;
271 return false; //TODO: uno::Exception?
274 void SdLayer::set( LayerAttribute what
, bool flag
) noexcept
276 if(!(pLayer
&& mxLayerManager
.is()))
279 // Try 1. is an arbitrary page open?
280 ::sd::View
*pView
= mxLayerManager
->GetView();
281 SdrPageView
* pSdrPageView
= nullptr;
283 pSdrPageView
= pView
->GetSdrPageView();
287 OUString
aLayerName(pLayer
->GetName());
290 case VISIBLE
: pSdrPageView
->SetLayerVisible(aLayerName
,flag
);
292 case PRINTABLE
: pSdrPageView
->SetLayerPrintable(aLayerName
,flag
);
294 case LOCKED
: pSdrPageView
->SetLayerLocked(aLayerName
,flag
);
299 // Try 2. get info from FrameView
300 if(!mxLayerManager
->GetDocShell())
303 ::sd::FrameView
*pFrameView
= mxLayerManager
->GetDocShell()->GetFrameView();
308 SdrLayerIDSet aNewLayers
;
311 case VISIBLE
: aNewLayers
= pFrameView
->GetVisibleLayers();
313 case PRINTABLE
: aNewLayers
= pFrameView
->GetPrintableLayers();
315 case LOCKED
: aNewLayers
= pFrameView
->GetLockedLayers();
319 aNewLayers
.Set(pLayer
->GetID(),flag
);
323 case VISIBLE
: pFrameView
->SetVisibleLayers(aNewLayers
);
325 case PRINTABLE
: pFrameView
->SetPrintableLayers(aNewLayers
);
327 case LOCKED
: pFrameView
->SetLockedLayers(aNewLayers
);
331 //TODO: uno::Exception?
334 // css::container::XChild
335 uno::Reference
<uno::XInterface
> SAL_CALL
SdLayer::getParent()
337 SolarMutexGuard aGuard
;
339 if( !mxLayerManager
.is() )
340 throw lang::DisposedException();
342 return uno::Reference
<uno::XInterface
> (static_cast<cppu::OWeakObject
*>(mxLayerManager
.get()), uno::UNO_QUERY
);
345 void SAL_CALL
SdLayer::setParent (const uno::Reference
<uno::XInterface
>& )
347 throw lang::NoSupportException ();
351 void SAL_CALL
SdLayer::dispose( )
353 mxLayerManager
.clear();
357 void SAL_CALL
SdLayer::addEventListener( const uno::Reference
< lang::XEventListener
>& )
359 OSL_FAIL("not implemented!");
362 void SAL_CALL
SdLayer::removeEventListener( const uno::Reference
< lang::XEventListener
>& )
364 OSL_FAIL("not implemented!");
367 // class SdLayerManager
368 SdLayerManager::SdLayerManager( SdXImpressDocument
& rMyModel
) noexcept
371 mpLayers
.reset(new SvUnoWeakContainer
);
374 SdLayerManager::~SdLayerManager() noexcept
380 void SAL_CALL
SdLayerManager::dispose( )
390 void SAL_CALL
SdLayerManager::addEventListener( const uno::Reference
< lang::XEventListener
>& )
392 OSL_FAIL("not implemented!");
395 void SAL_CALL
SdLayerManager::removeEventListener( const uno::Reference
< lang::XEventListener
>& )
397 OSL_FAIL("not implemented!");
401 OUString SAL_CALL
SdLayerManager::getImplementationName()
403 return u
"SdUnoLayerManager"_ustr
;
406 sal_Bool SAL_CALL
SdLayerManager::supportsService( const OUString
& ServiceName
)
408 return cppu::supportsService( this, ServiceName
);
411 uno::Sequence
< OUString
> SAL_CALL
SdLayerManager::getSupportedServiceNames()
413 return {u
"com.sun.star.drawing.LayerManager"_ustr
};
417 uno::Reference
< drawing::XLayer
> SAL_CALL
SdLayerManager::insertNewByIndex( sal_Int32 nIndex
)
419 SolarMutexGuard aGuard
;
421 if( mpModel
== nullptr )
422 throw lang::DisposedException();
424 uno::Reference
< drawing::XLayer
> xLayer
;
428 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
429 sal_uInt16 nLayerCnt
= rLayerAdmin
.GetLayerCount();
430 sal_Int32 nLayer
= nLayerCnt
- 2 + 1;
433 // Test for existing names
434 while( aLayerName
.isEmpty() || rLayerAdmin
.GetLayer( aLayerName
) )
436 aLayerName
= SdResId(STR_LAYER
) + OUString::number(nLayer
);
440 SdrLayerAdmin
& rLA
=mpModel
->mpDoc
->GetLayerAdmin();
441 const sal_Int32 nMax
=rLA
.GetLayerCount();
442 if (nIndex
>nMax
) nIndex
=nMax
;
443 xLayer
= GetLayer (rLA
.NewLayer(aLayerName
,static_cast<sal_uInt16
>(nIndex
)));
444 mpModel
->SetModified();
449 void SAL_CALL
SdLayerManager::remove( const uno::Reference
< drawing::XLayer
>& xLayer
)
451 SolarMutexGuard aGuard
;
453 if( mpModel
== nullptr )
454 throw lang::DisposedException();
456 SdLayer
* pSdLayer
= dynamic_cast<SdLayer
*>(xLayer
.get());
458 if(pSdLayer
&& GetView())
460 const SdrLayer
* pSdrLayer
= pSdLayer
->GetSdrLayer();
461 GetView()->DeleteLayer( pSdrLayer
->GetName() );
466 mpModel
->SetModified();
469 void SAL_CALL
SdLayerManager::attachShapeToLayer( const uno::Reference
< drawing::XShape
>& xShape
, const uno::Reference
< drawing::XLayer
>& xLayer
)
471 SolarMutexGuard aGuard
;
473 if( mpModel
== nullptr )
474 throw lang::DisposedException();
476 SdLayer
* pSdLayer
= dynamic_cast<SdLayer
*>(xLayer
.get());
477 if(pSdLayer
==nullptr)
479 SdrLayer
* pSdrLayer
= pSdLayer
->GetSdrLayer();
480 if(pSdrLayer
==nullptr)
483 SdrObject
* pSdrObject
= SdrObject::getSdrObjectFromXShape( xShape
);
486 pSdrObject
->SetLayer(pSdrLayer
->GetID());
488 mpModel
->SetModified();
491 uno::Reference
< drawing::XLayer
> SAL_CALL
SdLayerManager::getLayerForShape( const uno::Reference
< drawing::XShape
>& xShape
)
493 SolarMutexGuard aGuard
;
495 if( mpModel
== nullptr )
496 throw lang::DisposedException();
498 uno::Reference
< drawing::XLayer
> xLayer
;
502 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape( xShape
);
505 SdrLayerID aId
= pObj
->GetLayer();
506 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
507 xLayer
= GetLayer (rLayerAdmin
.GetLayerPerID(aId
));
514 sal_Int32 SAL_CALL
SdLayerManager::getCount()
516 SolarMutexGuard aGuard
;
518 if( mpModel
== nullptr )
519 throw lang::DisposedException();
523 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
524 return rLayerAdmin
.GetLayerCount();
530 uno::Any SAL_CALL
SdLayerManager::getByIndex( sal_Int32 nLayer
)
532 SolarMutexGuard aGuard
;
534 if( mpModel
== nullptr )
535 throw lang::DisposedException();
537 if( nLayer
>= getCount() || nLayer
< 0 )
538 throw lang::IndexOutOfBoundsException();
544 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
545 uno::Reference
<drawing::XLayer
> xLayer (GetLayer (rLayerAdmin
.GetLayer(static_cast<sal_uInt16
>(nLayer
))));
552 uno::Any SAL_CALL
SdLayerManager::getByName( const OUString
& aName
)
554 SolarMutexGuard aGuard
;
556 if( (mpModel
== nullptr) || (mpModel
->mpDoc
== nullptr ) )
557 throw lang::DisposedException();
559 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
560 SdrLayer
* pLayer
= rLayerAdmin
.GetLayer(aName
);
561 if( pLayer
== nullptr )
562 throw container::NoSuchElementException();
564 return uno::Any( css::uno::Reference
< css::drawing::XLayer
>(GetLayer(pLayer
)) );
567 uno::Sequence
< OUString
> SAL_CALL
SdLayerManager::getElementNames()
569 SolarMutexGuard aGuard
;
571 if( mpModel
== nullptr )
572 throw lang::DisposedException();
574 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
575 const sal_uInt16 nLayerCount
= rLayerAdmin
.GetLayerCount();
577 uno::Sequence
< OUString
> aSeq( nLayerCount
);
579 OUString
* pStrings
= aSeq
.getArray();
581 for( sal_uInt16 nLayer
= 0; nLayer
< nLayerCount
; nLayer
++ )
583 SdrLayer
* pLayer
= rLayerAdmin
.GetLayer( nLayer
);
585 *pStrings
++ = pLayer
->GetName();
591 sal_Bool SAL_CALL
SdLayerManager::hasByName( const OUString
& aName
)
593 SolarMutexGuard aGuard
;
595 if( mpModel
== nullptr )
596 throw lang::DisposedException();
598 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
600 return nullptr != rLayerAdmin
.GetLayer(aName
);
604 uno::Type SAL_CALL
SdLayerManager::getElementType()
606 return cppu::UnoType
<drawing::XLayer
>::get();
609 sal_Bool SAL_CALL
SdLayerManager::hasElements()
611 return getCount() > 0;
615 * If something was changed at the layers, this methods takes care that the
616 * changes are made visible in sdbcx::View.
618 void SdLayerManager::UpdateLayerView() const noexcept
620 if(!mpModel
->mpDocShell
)
623 ::sd::DrawViewShell
* pDrViewSh
= dynamic_cast< ::sd::DrawViewShell
* >( mpModel
->mpDocShell
->GetViewShell());
627 bool bLayerMode
= pDrViewSh
->IsLayerModeActive();
628 pDrViewSh
->ChangeEditMode(pDrViewSh
->GetEditMode(), !bLayerMode
);
629 pDrViewSh
->ChangeEditMode(pDrViewSh
->GetEditMode(), bLayerMode
);
632 mpModel
->mpDoc
->SetChanged();
636 ::sd::View
* SdLayerManager::GetView() const noexcept
638 if( mpModel
->mpDocShell
)
640 ::sd::ViewShell
* pViewSh
= mpModel
->mpDocShell
->GetViewShell();
642 return pViewSh
->GetView();
647 /** Use the <member>mpLayers</member> container of weak references to either
648 retrieve and return a previously created <type>XLayer</type> object for
649 the given <type>SdrLayer</type> object or create and remember a new one.
651 rtl::Reference
<SdLayer
> SdLayerManager::GetLayer (SdrLayer
* pLayer
)
653 rtl::Reference
<SdLayer
> xLayer
;
655 // Search existing xLayer for the given pLayer.
656 if (mpLayers
->findRef(xLayer
, pLayer
))
659 // Create the xLayer if necessary.
660 xLayer
= new SdLayer (this, pLayer
);
662 // Remember the new xLayer for future calls.
663 mpLayers
->insert(xLayer
);
668 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */