Bump version to 6.4.7.2.M8
[LibreOffice.git] / svx / source / svdraw / svdlayer.cxx
blob04c868e8815b3f64f801a339a01ba49ce8062eb6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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)
31 if(i != 0)
32 return false;
35 return true;
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;
51 if( rAny >>= aSeq )
53 sal_Int16 nCount = static_cast<sal_Int16>(aSeq.getLength());
54 if( nCount > 32 )
55 nCount = 32;
57 sal_Int16 nIndex;
58 for( nIndex = 0; nIndex < nCount; nIndex++ )
60 aData[nIndex] = static_cast<sal_uInt8>(aSeq[nIndex]);
63 for( ; nIndex < 32; nIndex++ )
65 aData[nIndex] = 0;
70 SdrLayer::SdrLayer(SdrLayerID nNewID, const OUString& rNewName) :
71 maName(rNewName), pModel(nullptr), nID(nNewID)
73 // ODF default values
74 mbVisibleODF = true;
75 mbPrintableODF = true;
76 mbLockedODF = false;
79 void SdrLayer::SetName(const OUString& rNewName)
81 if (rNewName == maName)
82 return;
84 maName = rNewName;
86 if (pModel)
88 SdrHint aHint(SdrHintKind::LayerChange);
89 pModel->Broadcast(aHint);
90 pModel->SetChanged();
94 bool SdrLayer::operator==(const SdrLayer& rCmpLayer) const
96 return (nID == rCmpLayer.nID
97 && maName == rCmpLayer.maName);
100 SdrLayerAdmin::SdrLayerAdmin(SdrLayerAdmin* pNewParent):
101 pParent(pNewParent),
102 pModel(nullptr),
103 maControlLayerName("controls")
107 SdrLayerAdmin::SdrLayerAdmin(const SdrLayerAdmin& rSrcLayerAdmin):
108 pParent(nullptr),
109 pModel(nullptr),
110 maControlLayerName("controls")
112 *this = rSrcLayerAdmin;
115 SdrLayerAdmin::~SdrLayerAdmin()
119 void SdrLayerAdmin::ClearLayers()
121 maLayers.clear();
124 SdrLayerAdmin& SdrLayerAdmin::operator=(const SdrLayerAdmin& rSrcLayerAdmin)
126 if (this != &rSrcLayerAdmin)
128 maLayers.clear();
129 pParent=rSrcLayerAdmin.pParent;
130 sal_uInt16 i;
131 sal_uInt16 nCount=rSrcLayerAdmin.GetLayerCount();
132 for (i=0; i<nCount; i++) {
133 maLayers.emplace_back(new SdrLayer(*rSrcLayerAdmin.GetLayer(i)));
136 return *this;
139 void SdrLayerAdmin::SetModel(SdrModel* pNewModelel)
141 if (pNewModelel!=pModel) {
142 pModel=pNewModelel;
143 sal_uInt16 nCount=GetLayerCount();
144 sal_uInt16 i;
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);
163 if(nPos==0xFFFF)
164 maLayers.push_back(std::move(pLayer));
165 else
166 maLayers.insert(maLayers.begin() + nPos, std::move(pLayer));
167 Broadcast();
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);
174 Broadcast();
175 return pRetLayer;
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);
183 if(nPos==0xFFFF)
184 maLayers.push_back(std::unique_ptr<SdrLayer>(pLay));
185 else
186 maLayers.insert(maLayers.begin() + nPos, std::unique_ptr<SdrLayer>(pLay));
187 Broadcast();
188 return 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();
201 return nRet;
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
211 sal_uInt16 i(0);
212 const SdrLayer* pLay = nullptr;
214 while(i < GetLayerCount() && !pLay)
216 if (rName == GetLayer(i)->GetName())
217 pLay = GetLayer(i);
218 else
219 i++;
222 if(!pLay && pParent)
224 pLay = pParent->GetLayer(rName);
227 return pLay;
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();
235 return nRet;
238 const SdrLayer* SdrLayerAdmin::GetLayerPerID(SdrLayerID nID) const
240 for (auto const & pLayer : maLayers)
241 if (pLayer->GetID() == nID)
242 return pLayer.get();
243 return nullptr;
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
252 SdrLayerIDSet aSet;
253 for (sal_uInt16 j=0; j<GetLayerCount(); j++)
255 aSet.Set(GetLayer(j)->GetID());
257 sal_uInt8 i;
258 if (pParent != nullptr)
260 i = 254;
261 while (i && aSet.IsSet(SdrLayerID(i)))
262 --i;
263 assert(i != 0);
264 if (i == 0)
265 i = 254;
267 else
269 i = 0;
270 while (i<=254 && aSet.IsSet(SdrLayerID(i)))
271 i++;
272 assert(i <= 254);
273 if (i>254)
274 i = 0;
276 return SdrLayerID(i);
279 void SdrLayerAdmin::SetControlLayerName(const OUString& rNewName)
281 maControlLayerName = rNewName;
284 void SdrLayerAdmin::getVisibleLayersODF( SdrLayerIDSet& rOutSet) const
286 rOutSet.ClearAll();
287 for( auto & pCurrentLayer : maLayers )
289 if ( pCurrentLayer->IsVisibleODF() )
290 rOutSet.Set( pCurrentLayer->GetID() );
294 void SdrLayerAdmin::getPrintableLayersODF( SdrLayerIDSet& rOutSet) const
296 rOutSet.ClearAll();
297 for( auto & pCurrentLayer : maLayers )
299 if ( pCurrentLayer->IsPrintableODF() )
300 rOutSet.Set( pCurrentLayer->GetID() );
304 void SdrLayerAdmin::getLockedLayersODF( SdrLayerIDSet& rOutSet) const
306 rOutSet.ClearAll();
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++)
324 aTmp[nIndex] = 0;
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;
337 if (nByteIndex > 31)
338 continue; // skip position, if too large for bitfield
339 nBitpos = nLayerPos % 8;
340 aTmp[nByteIndex] |= (1 << nBitpos);
342 ++nLayerIndex;
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;
352 break;
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]);
360 rAny <<= aSeq;
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */