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/uno/Sequence.hxx>
22 #include <svx/svdlayer.hxx>
23 #include <svx/svdmodel.hxx>
28 bool SdrLayerIDSet::IsEmpty() const
30 for(sal_uInt8 i
: m_aData
)
39 void SdrLayerIDSet::operator&=(const SdrLayerIDSet
& r2ndSet
)
41 for(sal_uInt16
i(0); i
< 32; i
++)
43 m_aData
[i
] &= r2ndSet
.m_aData
[i
];
47 /** initialize this set with a UNO sequence of sal_Int8 (e.g. as stored in settings.xml)
49 void SdrLayerIDSet::PutValue( const css::uno::Any
& rAny
)
51 css::uno::Sequence
< sal_Int8
> aSeq
;
52 if( !(rAny
>>= aSeq
) )
55 sal_Int16 nCount
= static_cast<sal_Int16
>(aSeq
.getLength());
60 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
62 m_aData
[nIndex
] = static_cast<sal_uInt8
>(aSeq
[nIndex
]);
65 for( ; nIndex
< 32; nIndex
++ )
71 SdrLayer::SdrLayer(SdrLayerID nNewID
, OUString aNewName
) :
72 maName(std::move(aNewName
)), m_pModel(nullptr), m_nID(nNewID
)
76 mbPrintableODF
= true;
80 void SdrLayer::SetName(const OUString
& rNewName
)
82 if (rNewName
== maName
)
89 SdrHint
aHint(SdrHintKind::LayerChange
);
90 m_pModel
->Broadcast(aHint
);
91 m_pModel
->SetChanged();
95 bool SdrLayer::operator==(const SdrLayer
& rCmpLayer
) const
97 return (m_nID
== rCmpLayer
.m_nID
98 && maName
== rCmpLayer
.maName
);
101 SdrLayerAdmin::SdrLayerAdmin(SdrLayerAdmin
* pNewParent
):
102 m_pParent(pNewParent
),
104 maControlLayerName(u
"controls"_ustr
)
108 SdrLayerAdmin::SdrLayerAdmin(const SdrLayerAdmin
& rSrcLayerAdmin
):
111 maControlLayerName(u
"controls"_ustr
)
113 *this = rSrcLayerAdmin
;
116 SdrLayerAdmin::~SdrLayerAdmin()
120 void SdrLayerAdmin::ClearLayers()
125 SdrLayerAdmin
& SdrLayerAdmin::operator=(const SdrLayerAdmin
& rSrcLayerAdmin
)
127 if (this != &rSrcLayerAdmin
)
130 m_pParent
=rSrcLayerAdmin
.m_pParent
;
132 sal_uInt16 nCount
=rSrcLayerAdmin
.GetLayerCount();
133 for (i
=0; i
<nCount
; i
++) {
134 maLayers
.emplace_back(new SdrLayer(*rSrcLayerAdmin
.GetLayer(i
)));
140 void SdrLayerAdmin::SetModel(SdrModel
* pNewModelel
)
142 if (pNewModelel
!=m_pModel
) {
143 m_pModel
=pNewModelel
;
144 sal_uInt16 nCount
=GetLayerCount();
146 for (i
=0; i
<nCount
; i
++) {
147 GetLayer(i
)->SetModel(pNewModelel
);
152 void SdrLayerAdmin::Broadcast() const
154 if (m_pModel
!=nullptr) {
155 SdrHint
aHint(SdrHintKind::LayerOrderChange
);
156 m_pModel
->Broadcast(aHint
);
157 m_pModel
->SetChanged();
161 void SdrLayerAdmin::InsertLayer(std::unique_ptr
<SdrLayer
> pLayer
, sal_uInt16 nPos
)
163 pLayer
->SetModel(m_pModel
);
165 maLayers
.push_back(std::move(pLayer
));
167 maLayers
.insert(maLayers
.begin() + nPos
, std::move(pLayer
));
171 std::unique_ptr
<SdrLayer
> SdrLayerAdmin::RemoveLayer(sal_uInt16 nPos
)
173 std::unique_ptr
<SdrLayer
> pRetLayer
= std::move(maLayers
[nPos
]);
174 maLayers
.erase(maLayers
.begin()+nPos
);
179 SdrLayer
* SdrLayerAdmin::NewLayer(const OUString
& rName
, sal_uInt16 nPos
)
181 SdrLayerID nID
=GetUniqueLayerID();
182 SdrLayer
* pLay
=new SdrLayer(nID
,rName
);
183 pLay
->SetModel(m_pModel
);
185 maLayers
.push_back(std::unique_ptr
<SdrLayer
>(pLay
));
187 maLayers
.insert(maLayers
.begin() + nPos
, std::unique_ptr
<SdrLayer
>(pLay
));
192 sal_uInt16
SdrLayerAdmin::GetLayerPos(const SdrLayer
* pLayer
) const
194 sal_uInt16 nRet
=SDRLAYERPOS_NOTFOUND
;
195 if (pLayer
!=nullptr) {
196 auto it
= std::find_if(maLayers
.begin(), maLayers
.end(),
197 [&](const std::unique_ptr
<SdrLayer
> & p
) { return p
.get() == pLayer
; });
198 if (it
!=maLayers
.end()) {
199 nRet
=it
- maLayers
.begin();
205 SdrLayer
* SdrLayerAdmin::GetLayer(const OUString
& rName
)
207 return const_cast<SdrLayer
*>(const_cast<const SdrLayerAdmin
*>(this)->GetLayer(rName
));
210 const SdrLayer
* SdrLayerAdmin::GetLayer(const OUString
& rName
) const
213 const SdrLayer
* pLay
= nullptr;
215 while(i
< GetLayerCount() && !pLay
)
217 if (rName
== GetLayer(i
)->GetName())
223 if(!pLay
&& m_pParent
)
225 pLay
= m_pParent
->GetLayer(rName
);
231 SdrLayerID
SdrLayerAdmin::GetLayerID(const OUString
& rName
) const
233 SdrLayerID nRet
=SDRLAYER_NOTFOUND
;
234 const SdrLayer
* pLay
=GetLayer(rName
);
235 if (pLay
!=nullptr) nRet
=pLay
->GetID();
239 const SdrLayer
* SdrLayerAdmin::GetLayerPerID(SdrLayerID nID
) const
241 for (auto const & pLayer
: maLayers
)
242 if (pLayer
->GetID() == nID
)
247 // Global LayerIDs begin at 0 and increase,
248 // local LayerIDs begin at 254 and decrease;
249 // 255 is reserved for SDRLAYER_NOTFOUND.
251 SdrLayerID
SdrLayerAdmin::GetUniqueLayerID() const
254 for (sal_uInt16 j
=0; j
<GetLayerCount(); j
++)
256 aSet
.Set(GetLayer(j
)->GetID());
259 if (m_pParent
!= nullptr)
262 while (i
&& aSet
.IsSet(SdrLayerID(i
)))
271 while (i
<=254 && aSet
.IsSet(SdrLayerID(i
)))
277 return SdrLayerID(i
);
280 void SdrLayerAdmin::SetControlLayerName(const OUString
& rNewName
)
282 maControlLayerName
= rNewName
;
285 void SdrLayerAdmin::getVisibleLayersODF( SdrLayerIDSet
& rOutSet
) const
288 for( auto & pCurrentLayer
: maLayers
)
290 if ( pCurrentLayer
->IsVisibleODF() )
291 rOutSet
.Set( pCurrentLayer
->GetID() );
295 void SdrLayerAdmin::getPrintableLayersODF( SdrLayerIDSet
& rOutSet
) const
298 for( auto & pCurrentLayer
: maLayers
)
300 if ( pCurrentLayer
->IsPrintableODF() )
301 rOutSet
.Set( pCurrentLayer
->GetID() );
305 void SdrLayerAdmin::getLockedLayersODF( SdrLayerIDSet
& rOutSet
) const
308 for( auto& pCurrentLayer
: maLayers
)
310 if ( pCurrentLayer
->IsLockedODF() )
311 rOutSet
.Set( pCurrentLayer
->GetID() );
315 // Generates a bitfield for settings.xml from the SdrLayerIDSet.
316 // Output is a UNO sequence of BYTE (which is 'short' in API).
317 void SdrLayerAdmin::QueryValue(const SdrLayerIDSet
& rViewLayerSet
, css::uno::Any
& rAny
)
319 // tdf#119392 The SdrLayerIDSet in a view is ordered according LayerID, but in file
320 // the bitfield is interpreted in order of layers in <draw:layer-set>.
321 // First generate a new bitfield based on rViewLayerSet in the needed order.
322 sal_uInt8 aTmp
[32]; // 256 bits in settings.xml makes byte 0 to 31
323 for (auto nIndex
= 0; nIndex
<32; nIndex
++)
327 sal_uInt8 nByteIndex
= 0;
328 sal_uInt8 nBitpos
= 0;
329 sal_uInt16 nLayerPos
= 0; // Position of the layer in member aLayer and in <draw:layer-set> in file
330 sal_uInt16 nLayerIndex
= 0;
331 for( const auto& pCurrentLayer
: maLayers
)
333 SdrLayerID nCurrentID
= pCurrentLayer
->GetID();
334 if ( rViewLayerSet
.IsSet(nCurrentID
) )
336 nLayerPos
= nLayerIndex
;
337 nByteIndex
= nLayerPos
/ 8;
339 continue; // skip position, if too large for bitfield
340 nBitpos
= nLayerPos
% 8;
341 aTmp
[nByteIndex
] |= (1 << nBitpos
);
346 // Second transform the bitfield to byte sequence, same as in previous version of QueryValue
347 sal_uInt8 nNumBytesSet
= 0;
348 for( auto nIndex
= 31; nIndex
>= 0; nIndex
--)
350 if( 0 != aTmp
[nIndex
] )
352 nNumBytesSet
= nIndex
+ 1;
356 css::uno::Sequence
< sal_Int8
> aSeq( nNumBytesSet
);
357 std::transform(aTmp
, aTmp
+ nNumBytesSet
, aSeq
.getArray(),
358 [](const sal_uInt8 b
) { return static_cast<sal_Int8
>(b
); });
362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */