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>
24 #include <svx/dialmgr.hxx>
25 #include <svx/strings.hrc>
27 bool SdrLayerIDSet::IsEmpty() const
29 for(sal_uInt8 i
: aData
)
38 void SdrLayerIDSet::operator&=(const SdrLayerIDSet
& r2ndSet
)
40 for(sal_uInt16
i(0); i
< 32; i
++)
42 aData
[i
] &= r2ndSet
.aData
[i
];
46 /** initialize this set with a UNO sequence of sal_Int8 (e.g. as stored in settings.xml)
48 void SdrLayerIDSet::PutValue( const css::uno::Any
& rAny
)
50 css::uno::Sequence
< sal_Int8
> aSeq
;
53 sal_Int16 nCount
= static_cast<sal_Int16
>(aSeq
.getLength());
58 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
60 aData
[nIndex
] = static_cast<sal_uInt8
>(aSeq
[nIndex
]);
63 for( ; nIndex
< 32; nIndex
++ )
70 SdrLayer::SdrLayer(SdrLayerID nNewID
, const OUString
& rNewName
) :
71 maName(rNewName
), pModel(nullptr), nID(nNewID
)
75 mbPrintableODF
= true;
79 void SdrLayer::SetName(const OUString
& rNewName
)
81 if (rNewName
== maName
)
88 SdrHint
aHint(SdrHintKind::LayerChange
);
89 pModel
->Broadcast(aHint
);
94 bool SdrLayer::operator==(const SdrLayer
& rCmpLayer
) const
96 return (nID
== rCmpLayer
.nID
97 && maName
== rCmpLayer
.maName
);
100 SdrLayerAdmin::SdrLayerAdmin(SdrLayerAdmin
* pNewParent
):
103 maControlLayerName("controls")
107 SdrLayerAdmin::SdrLayerAdmin(const SdrLayerAdmin
& rSrcLayerAdmin
):
110 maControlLayerName("controls")
112 *this = rSrcLayerAdmin
;
115 SdrLayerAdmin::~SdrLayerAdmin()
119 void SdrLayerAdmin::ClearLayers()
124 SdrLayerAdmin
& SdrLayerAdmin::operator=(const SdrLayerAdmin
& rSrcLayerAdmin
)
126 if (this != &rSrcLayerAdmin
)
129 pParent
=rSrcLayerAdmin
.pParent
;
131 sal_uInt16 nCount
=rSrcLayerAdmin
.GetLayerCount();
132 for (i
=0; i
<nCount
; i
++) {
133 maLayers
.emplace_back(new SdrLayer(*rSrcLayerAdmin
.GetLayer(i
)));
139 void SdrLayerAdmin::SetModel(SdrModel
* pNewModelel
)
141 if (pNewModelel
!=pModel
) {
143 sal_uInt16 nCount
=GetLayerCount();
145 for (i
=0; i
<nCount
; i
++) {
146 GetLayer(i
)->SetModel(pNewModelel
);
151 void SdrLayerAdmin::Broadcast() const
153 if (pModel
!=nullptr) {
154 SdrHint
aHint(SdrHintKind::LayerOrderChange
);
155 pModel
->Broadcast(aHint
);
156 pModel
->SetChanged();
160 void SdrLayerAdmin::InsertLayer(std::unique_ptr
<SdrLayer
> pLayer
, sal_uInt16 nPos
)
162 pLayer
->SetModel(pModel
);
164 maLayers
.push_back(std::move(pLayer
));
166 maLayers
.insert(maLayers
.begin() + nPos
, std::move(pLayer
));
170 std::unique_ptr
<SdrLayer
> SdrLayerAdmin::RemoveLayer(sal_uInt16 nPos
)
172 std::unique_ptr
<SdrLayer
> pRetLayer
= std::move(maLayers
[nPos
]);
173 maLayers
.erase(maLayers
.begin()+nPos
);
178 SdrLayer
* SdrLayerAdmin::NewLayer(const OUString
& rName
, sal_uInt16 nPos
)
180 SdrLayerID nID
=GetUniqueLayerID();
181 SdrLayer
* pLay
=new SdrLayer(nID
,rName
);
182 pLay
->SetModel(pModel
);
184 maLayers
.push_back(std::unique_ptr
<SdrLayer
>(pLay
));
186 maLayers
.insert(maLayers
.begin() + nPos
, std::unique_ptr
<SdrLayer
>(pLay
));
191 sal_uInt16
SdrLayerAdmin::GetLayerPos(const SdrLayer
* pLayer
) const
193 sal_uInt16 nRet
=SDRLAYERPOS_NOTFOUND
;
194 if (pLayer
!=nullptr) {
195 auto it
= std::find_if(maLayers
.begin(), maLayers
.end(),
196 [&](const std::unique_ptr
<SdrLayer
> & p
) { return p
.get() == pLayer
; });
197 if (it
!=maLayers
.end()) {
198 nRet
=it
- maLayers
.begin();
204 SdrLayer
* SdrLayerAdmin::GetLayer(const OUString
& rName
)
206 return const_cast<SdrLayer
*>(const_cast<const SdrLayerAdmin
*>(this)->GetLayer(rName
));
209 const SdrLayer
* SdrLayerAdmin::GetLayer(const OUString
& rName
) const
212 const SdrLayer
* pLay
= nullptr;
214 while(i
< GetLayerCount() && !pLay
)
216 if (rName
== GetLayer(i
)->GetName())
224 pLay
= pParent
->GetLayer(rName
);
230 SdrLayerID
SdrLayerAdmin::GetLayerID(const OUString
& rName
) const
232 SdrLayerID nRet
=SDRLAYER_NOTFOUND
;
233 const SdrLayer
* pLay
=GetLayer(rName
);
234 if (pLay
!=nullptr) nRet
=pLay
->GetID();
238 const SdrLayer
* SdrLayerAdmin::GetLayerPerID(SdrLayerID nID
) const
240 for (auto const & pLayer
: maLayers
)
241 if (pLayer
->GetID() == nID
)
246 // Global LayerIDs begin at 0 and increase,
247 // local LayerIDs begin at 254 and decrease;
248 // 255 is reserved for SDRLAYER_NOTFOUND.
250 SdrLayerID
SdrLayerAdmin::GetUniqueLayerID() const
253 for (sal_uInt16 j
=0; j
<GetLayerCount(); j
++)
255 aSet
.Set(GetLayer(j
)->GetID());
258 if (pParent
!= nullptr)
261 while (i
&& aSet
.IsSet(SdrLayerID(i
)))
270 while (i
<=254 && aSet
.IsSet(SdrLayerID(i
)))
276 return SdrLayerID(i
);
279 void SdrLayerAdmin::SetControlLayerName(const OUString
& rNewName
)
281 maControlLayerName
= rNewName
;
284 void SdrLayerAdmin::getVisibleLayersODF( SdrLayerIDSet
& rOutSet
) const
287 for( auto & pCurrentLayer
: maLayers
)
289 if ( pCurrentLayer
->IsVisibleODF() )
290 rOutSet
.Set( pCurrentLayer
->GetID() );
294 void SdrLayerAdmin::getPrintableLayersODF( SdrLayerIDSet
& rOutSet
) const
297 for( auto & pCurrentLayer
: maLayers
)
299 if ( pCurrentLayer
->IsPrintableODF() )
300 rOutSet
.Set( pCurrentLayer
->GetID() );
304 void SdrLayerAdmin::getLockedLayersODF( SdrLayerIDSet
& rOutSet
) const
307 for( auto& pCurrentLayer
: maLayers
)
309 if ( pCurrentLayer
->IsLockedODF() )
310 rOutSet
.Set( pCurrentLayer
->GetID() );
314 // Generates a bitfield for settings.xml from the SdrLayerIDSet.
315 // Output is a UNO sequence of BYTE (which is 'short' in API).
316 void SdrLayerAdmin::QueryValue(const SdrLayerIDSet
& rViewLayerSet
, css::uno::Any
& rAny
)
318 // tdf#119392 The SdrLayerIDSet in a view is ordered according LayerID, but in file
319 // the bitfield is interpreted in order of layers in <draw:layer-set>.
320 // First generate a new bitfield based on rViewLayerSet in the needed order.
321 sal_uInt8 aTmp
[32]; // 256 bits in settings.xml makes byte 0 to 31
322 for (auto nIndex
= 0; nIndex
<32; nIndex
++)
326 sal_uInt8 nByteIndex
= 0;
327 sal_uInt8 nBitpos
= 0;
328 sal_uInt16 nLayerPos
= 0; // Position of the layer in member aLayer and in <draw:layer-set> in file
329 sal_uInt16 nLayerIndex
= 0;
330 for( const auto& pCurrentLayer
: maLayers
)
332 SdrLayerID nCurrentID
= pCurrentLayer
->GetID();
333 if ( rViewLayerSet
.IsSet(nCurrentID
) )
335 nLayerPos
= nLayerIndex
;
336 nByteIndex
= nLayerPos
/ 8;
338 continue; // skip position, if too large for bitfield
339 nBitpos
= nLayerPos
% 8;
340 aTmp
[nByteIndex
] |= (1 << nBitpos
);
345 // Second transform the bitfield to byte sequence, same as in previous version of QueryValue
346 sal_uInt8 nNumBytesSet
= 0;
347 for( auto nIndex
= 31; nIndex
>= 0; nIndex
--)
349 if( 0 != aTmp
[nIndex
] )
351 nNumBytesSet
= nIndex
+ 1;
355 css::uno::Sequence
< sal_Int8
> aSeq( nNumBytesSet
);
356 for( auto nIndex
= 0; nIndex
< nNumBytesSet
; nIndex
++ )
358 aSeq
[nIndex
] = static_cast<sal_Int8
>(aTmp
[nIndex
]);
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */