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 <svx/svdpagv.hxx>
27 #include <svx/unoshape.hxx>
28 #include <svx/svdobj.hxx>
29 #include <cppuhelper/supportsservice.hxx>
31 // following ones for InsertSdPage()
32 #include <svx/svdlayer.hxx>
34 #include <DrawDocShell.hxx>
35 #include <drawdoc.hxx>
36 #include <unomodel.hxx>
37 #include <unoprnms.hxx>
38 #include <com/sun/star/lang/NoSupportException.hpp>
39 #include <svx/svdpool.hxx>
40 #include <FrameView.hxx>
41 #include <DrawViewShell.hxx>
43 #include <ViewShell.hxx>
45 #include <strings.hrc>
46 #include <sdresid.hxx>
48 #include <unokywds.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 { OUString(UNO_NAME_LAYER_LOCKED
), WID_LAYER_LOCKED
, cppu::UnoType
<bool>::get(), 0, 0 },
67 { OUString(UNO_NAME_LAYER_PRINTABLE
), WID_LAYER_PRINTABLE
,cppu::UnoType
<bool>::get(), 0, 0 },
68 { OUString(UNO_NAME_LAYER_VISIBLE
), WID_LAYER_VISIBLE
, cppu::UnoType
<bool>::get(), 0, 0 },
69 { OUString(UNO_NAME_LAYER_NAME
), WID_LAYER_NAME
, ::cppu::UnoType
<OUString
>::get(), 0, 0 },
70 { OUString("Title"), WID_LAYER_TITLE
, ::cppu::UnoType
<OUString
>::get(), 0, 0 },
71 { OUString("Description"), WID_LAYER_DESC
, ::cppu::UnoType
<OUString
>::get(), 0, 0 },
72 { OUString(), 0, css::uno::Type(), 0, 0 }
74 static SvxItemPropertySet
aSDLayerPropertySet_Impl( aSdLayerPropertyMap_Impl
, SdrObject::GetGlobalDrawObjectItemPool() );
75 return &aSDLayerPropertySet_Impl
;
78 SdLayer::SdLayer(SdLayerManager
* pLayerManager_
, SdrLayer
* pSdrLayer_
)
79 : mxLayerManager(pLayerManager_
)
81 , pPropSet(ImplGetSdLayerPropertySet())
83 // no defaults possible yet, a "set" would overwrite existing information
84 // in view, which is currently needed for saving, because pLayer is not updated
88 SdLayer::~SdLayer() throw()
93 UNO3_GETIMPLEMENTATION_IMPL( SdLayer
);
96 OUString SAL_CALL
SdLayer::getImplementationName()
98 return OUString("SdUnoLayer");
101 sal_Bool SAL_CALL
SdLayer::supportsService( const OUString
& ServiceName
)
103 return cppu::supportsService( this, ServiceName
);
106 uno::Sequence
< OUString
> SAL_CALL
SdLayer::getSupportedServiceNames()
108 OUString
aServiceName("com.sun.star.drawing.Layer");
109 uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
113 // beans::XPropertySet
114 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
SdLayer::getPropertySetInfo( )
116 SolarMutexGuard aGuard
;
117 return pPropSet
->getPropertySetInfo();
120 void SAL_CALL
SdLayer::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
122 SolarMutexGuard aGuard
;
124 if(pLayer
== nullptr || mxLayerManager
== nullptr)
125 throw lang::DisposedException();
127 const SfxItemPropertySimpleEntry
* pEntry
= pPropSet
->getPropertyMapEntry(aPropertyName
);
129 switch( pEntry
? pEntry
->nWID
: -1 )
131 case WID_LAYER_LOCKED
:
133 pLayer
->SetLockedODF( cppu::any2bool(aValue
) );
134 set(LOCKED
, cppu::any2bool(aValue
)); // changes the View, if any exists
137 case WID_LAYER_PRINTABLE
:
139 pLayer
->SetPrintableODF( cppu::any2bool(aValue
) );
140 set(PRINTABLE
, cppu::any2bool(aValue
)); // changes the View, if any exists
143 case WID_LAYER_VISIBLE
:
145 pLayer
->SetVisibleODF( cppu::any2bool(aValue
) );
146 set(VISIBLE
, cppu::any2bool(aValue
)); // changes the View, if any exists
152 if(!(aValue
>>= aName
))
153 throw lang::IllegalArgumentException();
155 pLayer
->SetName(aName
);
156 mxLayerManager
->UpdateLayerView();
160 case WID_LAYER_TITLE
:
163 if(!(aValue
>>= sTitle
))
164 throw lang::IllegalArgumentException();
166 pLayer
->SetTitle(sTitle
);
172 OUString sDescription
;
173 if(!(aValue
>>= sDescription
))
174 throw lang::IllegalArgumentException();
176 pLayer
->SetDescription(sDescription
);
181 throw beans::UnknownPropertyException( aPropertyName
, static_cast<cppu::OWeakObject
*>(this));
184 if( mxLayerManager
->GetDocShell() )
185 mxLayerManager
->GetDocShell()->SetModified();
188 uno::Any SAL_CALL
SdLayer::getPropertyValue( const OUString
& PropertyName
)
190 SolarMutexGuard aGuard
;
192 if(pLayer
== nullptr || mxLayerManager
== nullptr)
193 throw lang::DisposedException();
195 const SfxItemPropertySimpleEntry
* pEntry
= pPropSet
->getPropertyMapEntry(PropertyName
);
199 switch( pEntry
? pEntry
->nWID
: -1 )
201 case WID_LAYER_LOCKED
:
202 aValue
<<= get( LOCKED
);
204 case WID_LAYER_PRINTABLE
:
205 aValue
<<= get( PRINTABLE
);
207 case WID_LAYER_VISIBLE
:
208 aValue
<<= get( VISIBLE
);
212 OUString
aRet(pLayer
->GetName());
216 case WID_LAYER_TITLE
:
217 aValue
<<= pLayer
->GetTitle();
220 aValue
<<= pLayer
->GetDescription();
223 throw beans::UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
229 void SAL_CALL
SdLayer::addPropertyChangeListener( const OUString
& , const uno::Reference
< beans::XPropertyChangeListener
>& ) {}
230 void SAL_CALL
SdLayer::removePropertyChangeListener( const OUString
& , const uno::Reference
< beans::XPropertyChangeListener
>& ) {}
231 void SAL_CALL
SdLayer::addVetoableChangeListener( const OUString
& , const uno::Reference
< beans::XVetoableChangeListener
>& ) {}
232 void SAL_CALL
SdLayer::removeVetoableChangeListener( const OUString
& , const uno::Reference
< beans::XVetoableChangeListener
>& ) {}
234 bool SdLayer::get( LayerAttribute what
) throw()
236 if(pLayer
&& mxLayerManager
.is())
238 // Try 1. is an arbitrary page open?
239 ::sd::View
*pView
= mxLayerManager
->GetView();
240 SdrPageView
* pSdrPageView
= nullptr;
242 pSdrPageView
= pView
->GetSdrPageView();
246 OUString aLayerName
= pLayer
->GetName();
249 case VISIBLE
: return pSdrPageView
->IsLayerVisible(aLayerName
);
250 case PRINTABLE
: return pSdrPageView
->IsLayerPrintable(aLayerName
);
251 case LOCKED
: return pSdrPageView
->IsLayerLocked(aLayerName
);
255 // Try 2. get info from FrameView
256 if(mxLayerManager
->GetDocShell())
258 ::sd::FrameView
*pFrameView
= mxLayerManager
->GetDocShell()->GetFrameView();
262 case VISIBLE
: return pFrameView
->GetVisibleLayers().IsSet(pLayer
->GetID());
263 case PRINTABLE
: return pFrameView
->GetPrintableLayers().IsSet(pLayer
->GetID());
264 case LOCKED
: return pFrameView
->GetLockedLayers().IsSet(pLayer
->GetID());
268 return false; //TODO: uno::Exception?
271 void SdLayer::set( LayerAttribute what
, bool flag
) throw()
273 if(!(pLayer
&& mxLayerManager
.is()))
276 // Try 1. is an arbitrary page open?
277 ::sd::View
*pView
= mxLayerManager
->GetView();
278 SdrPageView
* pSdrPageView
= nullptr;
280 pSdrPageView
= pView
->GetSdrPageView();
284 OUString
aLayerName(pLayer
->GetName());
287 case VISIBLE
: pSdrPageView
->SetLayerVisible(aLayerName
,flag
);
289 case PRINTABLE
: pSdrPageView
->SetLayerPrintable(aLayerName
,flag
);
291 case LOCKED
: pSdrPageView
->SetLayerLocked(aLayerName
,flag
);
296 // Try 2. get info from FrameView
297 if(!mxLayerManager
->GetDocShell())
300 ::sd::FrameView
*pFrameView
= mxLayerManager
->GetDocShell()->GetFrameView();
305 SdrLayerIDSet aNewLayers
;
308 case VISIBLE
: aNewLayers
= pFrameView
->GetVisibleLayers();
310 case PRINTABLE
: aNewLayers
= pFrameView
->GetPrintableLayers();
312 case LOCKED
: aNewLayers
= pFrameView
->GetLockedLayers();
316 aNewLayers
.Set(pLayer
->GetID(),flag
);
320 case VISIBLE
: pFrameView
->SetVisibleLayers(aNewLayers
);
322 case PRINTABLE
: pFrameView
->SetPrintableLayers(aNewLayers
);
324 case LOCKED
: pFrameView
->SetLockedLayers(aNewLayers
);
328 //TODO: uno::Exception?
331 // css::container::XChild
332 uno::Reference
<uno::XInterface
> SAL_CALL
SdLayer::getParent()
334 SolarMutexGuard aGuard
;
336 if( !mxLayerManager
.is() )
337 throw lang::DisposedException();
339 return uno::Reference
<uno::XInterface
> (static_cast<cppu::OWeakObject
*>(mxLayerManager
.get()), uno::UNO_QUERY
);
342 void SAL_CALL
SdLayer::setParent (const uno::Reference
<uno::XInterface
>& )
344 throw lang::NoSupportException ();
348 void SAL_CALL
SdLayer::dispose( )
350 mxLayerManager
.clear();
354 void SAL_CALL
SdLayer::addEventListener( const uno::Reference
< lang::XEventListener
>& )
356 OSL_FAIL("not implemented!");
359 void SAL_CALL
SdLayer::removeEventListener( const uno::Reference
< lang::XEventListener
>& )
361 OSL_FAIL("not implemented!");
364 // class SdLayerManager
365 SdLayerManager::SdLayerManager( SdXImpressDocument
& rMyModel
) throw()
368 mpLayers
.reset(new SvUnoWeakContainer
);
371 SdLayerManager::~SdLayerManager() throw()
377 UNO3_GETIMPLEMENTATION_IMPL( SdLayerManager
);
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 OUString("SdUnoLayerManager");
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 uno::Sequence
< OUString
> aSeq
{ "com.sun.star.drawing.LayerManager" };
418 uno::Reference
< drawing::XLayer
> SAL_CALL
SdLayerManager::insertNewByIndex( sal_Int32 nIndex
)
420 SolarMutexGuard aGuard
;
422 if( mpModel
== nullptr )
423 throw lang::DisposedException();
425 uno::Reference
< drawing::XLayer
> xLayer
;
429 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
430 sal_uInt16 nLayerCnt
= rLayerAdmin
.GetLayerCount();
431 sal_Int32 nLayer
= nLayerCnt
- 2 + 1;
434 // Test for existing names
435 while( aLayerName
.isEmpty() || rLayerAdmin
.GetLayer( aLayerName
) )
437 aLayerName
= SdResId(STR_LAYER
) + OUString::number(nLayer
);
441 SdrLayerAdmin
& rLA
=mpModel
->mpDoc
->GetLayerAdmin();
442 const sal_Int32 nMax
=rLA
.GetLayerCount();
443 if (nIndex
>nMax
) nIndex
=nMax
;
444 xLayer
= GetLayer (rLA
.NewLayer(aLayerName
,static_cast<sal_uInt16
>(nIndex
)));
445 mpModel
->SetModified();
450 void SAL_CALL
SdLayerManager::remove( const uno::Reference
< drawing::XLayer
>& xLayer
)
452 SolarMutexGuard aGuard
;
454 if( mpModel
== nullptr )
455 throw lang::DisposedException();
457 SdLayer
* pSdLayer
= SdLayer::getImplementation(xLayer
);
459 if(pSdLayer
&& GetView())
461 const SdrLayer
* pSdrLayer
= pSdLayer
->GetSdrLayer();
462 GetView()->DeleteLayer( pSdrLayer
->GetName() );
467 mpModel
->SetModified();
470 void SAL_CALL
SdLayerManager::attachShapeToLayer( const uno::Reference
< drawing::XShape
>& xShape
, const uno::Reference
< drawing::XLayer
>& xLayer
)
472 SolarMutexGuard aGuard
;
474 if( mpModel
== nullptr )
475 throw lang::DisposedException();
477 SdLayer
* pSdLayer
= SdLayer::getImplementation(xLayer
);
478 SdrLayer
* pSdrLayer
= pSdLayer
?pSdLayer
->GetSdrLayer():nullptr;
479 if(pSdrLayer
==nullptr)
482 SvxShape
* pShape
= SvxShape::getImplementation( xShape
);
483 SdrObject
* pSdrObject
= pShape
?pShape
->GetSdrObject():nullptr;
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 SvxShape
* pShape
= SvxShape::getImplementation( xShape
);
503 SdrObject
* pObj
= pShape
?pShape
->GetSdrObject():nullptr;
506 SdrLayerID aId
= pObj
->GetLayer();
507 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
508 xLayer
= GetLayer (rLayerAdmin
.GetLayerPerID(aId
));
515 sal_Int32 SAL_CALL
SdLayerManager::getCount()
517 SolarMutexGuard aGuard
;
519 if( mpModel
== nullptr )
520 throw lang::DisposedException();
524 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
525 return rLayerAdmin
.GetLayerCount();
531 uno::Any SAL_CALL
SdLayerManager::getByIndex( sal_Int32 nLayer
)
533 SolarMutexGuard aGuard
;
535 if( mpModel
== nullptr )
536 throw lang::DisposedException();
538 if( nLayer
>= getCount() || nLayer
< 0 )
539 throw lang::IndexOutOfBoundsException();
545 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
546 uno::Reference
<drawing::XLayer
> xLayer (GetLayer (rLayerAdmin
.GetLayer(static_cast<sal_uInt16
>(nLayer
))));
553 uno::Any SAL_CALL
SdLayerManager::getByName( const OUString
& aName
)
555 SolarMutexGuard aGuard
;
557 if( (mpModel
== nullptr) || (mpModel
->mpDoc
== nullptr ) )
558 throw lang::DisposedException();
560 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
561 SdrLayer
* pLayer
= rLayerAdmin
.GetLayer(aName
);
562 if( pLayer
== nullptr )
563 throw container::NoSuchElementException();
565 return uno::Any( GetLayer (pLayer
) );
568 uno::Sequence
< OUString
> SAL_CALL
SdLayerManager::getElementNames()
570 SolarMutexGuard aGuard
;
572 if( mpModel
== nullptr )
573 throw lang::DisposedException();
575 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
576 const sal_uInt16 nLayerCount
= rLayerAdmin
.GetLayerCount();
578 uno::Sequence
< OUString
> aSeq( nLayerCount
);
580 OUString
* pStrings
= aSeq
.getArray();
582 for( sal_uInt16 nLayer
= 0; nLayer
< nLayerCount
; nLayer
++ )
584 SdrLayer
* pLayer
= rLayerAdmin
.GetLayer( nLayer
);
586 *pStrings
++ = pLayer
->GetName();
592 sal_Bool SAL_CALL
SdLayerManager::hasByName( const OUString
& aName
)
594 SolarMutexGuard aGuard
;
596 if( mpModel
== nullptr )
597 throw lang::DisposedException();
599 SdrLayerAdmin
& rLayerAdmin
= mpModel
->mpDoc
->GetLayerAdmin();
601 return nullptr != rLayerAdmin
.GetLayer(aName
);
605 uno::Type SAL_CALL
SdLayerManager::getElementType()
607 return cppu::UnoType
<drawing::XLayer
>::get();
610 sal_Bool SAL_CALL
SdLayerManager::hasElements()
612 return getCount() > 0;
616 * If something was changed at the layers, this methods takes care that the
617 * changes are made visible in sdbcx::View.
619 void SdLayerManager::UpdateLayerView() const throw()
621 if(!mpModel
->mpDocShell
)
624 ::sd::DrawViewShell
* pDrViewSh
= dynamic_cast< ::sd::DrawViewShell
* >( mpModel
->mpDocShell
->GetViewShell());
628 bool bLayerMode
= pDrViewSh
->IsLayerModeActive();
629 pDrViewSh
->ChangeEditMode(pDrViewSh
->GetEditMode(), !bLayerMode
);
630 pDrViewSh
->ChangeEditMode(pDrViewSh
->GetEditMode(), bLayerMode
);
633 mpModel
->mpDoc
->SetChanged();
637 ::sd::View
* SdLayerManager::GetView() const throw()
639 if( mpModel
->mpDocShell
)
641 ::sd::ViewShell
* pViewSh
= mpModel
->mpDocShell
->GetViewShell();
643 return pViewSh
->GetView();
650 /** Compare two pointers to <type>SdrLayer</type> objects.
652 The implementing SdLayer class provides the first pointer by the
653 <member>SdLayer::GetSdrLayer</member> method.
655 This void pointer is the second pointer to an <type>SdrLayer</type>
658 Return </True> if both pointers point to the same object.
660 bool compare_layers (const uno::WeakReference
<uno::XInterface
>& xRef
, void const * pSearchData
)
662 uno::Reference
<uno::XInterface
> xLayer (xRef
);
665 SdLayer
* pSdLayer
= SdLayer::getImplementation (xRef
);
666 if (pSdLayer
!= nullptr)
668 SdrLayer
* pSdrLayer
= pSdLayer
->GetSdrLayer ();
669 if (pSdrLayer
== static_cast<SdrLayer
const *>(pSearchData
))
677 /** Use the <member>mpLayers</member> container of weak references to either
678 retrieve and return a previously created <type>XLayer</type> object for
679 the given <type>SdrLayer</type> object or create and remember a new one.
681 uno::Reference
<drawing::XLayer
> SdLayerManager::GetLayer (SdrLayer
* pLayer
)
683 uno::WeakReference
<uno::XInterface
> xRef
;
684 uno::Reference
<drawing::XLayer
> xLayer
;
686 // Search existing xLayer for the given pLayer.
687 if (mpLayers
->findRef (xRef
, static_cast<void*>(pLayer
), compare_layers
))
688 xLayer
.set(xRef
, uno::UNO_QUERY
);
690 // Create the xLayer if necessary.
693 xLayer
= new SdLayer (this, pLayer
);
695 // Remember the new xLayer for future calls.
696 uno::WeakReference
<uno::XInterface
> wRef(xLayer
);
697 mpLayers
->insert(wRef
);
703 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */