tdf#144694 In direct SQL dialog, activate options 'Run SQL command
[LibreOffice.git] / svx / source / svdraw / svdlayer.cxx
blobdb1ea1042a2db68bfc9c0d50322b2cb907789e9b
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>
25 #include <algorithm>
26 #include <utility>
28 bool SdrLayerIDSet::IsEmpty() const
30 for(sal_uInt8 i : m_aData)
32 if(i != 0)
33 return false;
36 return true;
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) )
53 return;
55 sal_Int16 nCount = static_cast<sal_Int16>(aSeq.getLength());
56 if( nCount > 32 )
57 nCount = 32;
59 sal_Int16 nIndex;
60 for( nIndex = 0; nIndex < nCount; nIndex++ )
62 m_aData[nIndex] = static_cast<sal_uInt8>(aSeq[nIndex]);
65 for( ; nIndex < 32; nIndex++ )
67 m_aData[nIndex] = 0;
71 SdrLayer::SdrLayer(SdrLayerID nNewID, OUString aNewName) :
72 maName(std::move(aNewName)), m_pModel(nullptr), m_nID(nNewID)
74 // ODF default values
75 mbVisibleODF = true;
76 mbPrintableODF = true;
77 mbLockedODF = false;
80 void SdrLayer::SetName(const OUString& rNewName)
82 if (rNewName == maName)
83 return;
85 maName = rNewName;
87 if (m_pModel)
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),
103 m_pModel(nullptr),
104 maControlLayerName(u"controls"_ustr)
108 SdrLayerAdmin::SdrLayerAdmin(const SdrLayerAdmin& rSrcLayerAdmin):
109 m_pParent(nullptr),
110 m_pModel(nullptr),
111 maControlLayerName(u"controls"_ustr)
113 *this = rSrcLayerAdmin;
116 SdrLayerAdmin::~SdrLayerAdmin()
120 void SdrLayerAdmin::ClearLayers()
122 maLayers.clear();
125 SdrLayerAdmin& SdrLayerAdmin::operator=(const SdrLayerAdmin& rSrcLayerAdmin)
127 if (this != &rSrcLayerAdmin)
129 maLayers.clear();
130 m_pParent=rSrcLayerAdmin.m_pParent;
131 sal_uInt16 i;
132 sal_uInt16 nCount=rSrcLayerAdmin.GetLayerCount();
133 for (i=0; i<nCount; i++) {
134 maLayers.emplace_back(new SdrLayer(*rSrcLayerAdmin.GetLayer(i)));
137 return *this;
140 void SdrLayerAdmin::SetModel(SdrModel* pNewModelel)
142 if (pNewModelel!=m_pModel) {
143 m_pModel=pNewModelel;
144 sal_uInt16 nCount=GetLayerCount();
145 sal_uInt16 i;
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);
164 if(nPos==0xFFFF)
165 maLayers.push_back(std::move(pLayer));
166 else
167 maLayers.insert(maLayers.begin() + nPos, std::move(pLayer));
168 Broadcast();
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);
175 Broadcast();
176 return pRetLayer;
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);
184 if(nPos==0xFFFF)
185 maLayers.push_back(std::unique_ptr<SdrLayer>(pLay));
186 else
187 maLayers.insert(maLayers.begin() + nPos, std::unique_ptr<SdrLayer>(pLay));
188 Broadcast();
189 return 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();
202 return nRet;
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
212 sal_uInt16 i(0);
213 const SdrLayer* pLay = nullptr;
215 while(i < GetLayerCount() && !pLay)
217 if (rName == GetLayer(i)->GetName())
218 pLay = GetLayer(i);
219 else
220 i++;
223 if(!pLay && m_pParent)
225 pLay = m_pParent->GetLayer(rName);
228 return pLay;
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();
236 return nRet;
239 const SdrLayer* SdrLayerAdmin::GetLayerPerID(SdrLayerID nID) const
241 for (auto const & pLayer : maLayers)
242 if (pLayer->GetID() == nID)
243 return pLayer.get();
244 return nullptr;
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
253 SdrLayerIDSet aSet;
254 for (sal_uInt16 j=0; j<GetLayerCount(); j++)
256 aSet.Set(GetLayer(j)->GetID());
258 sal_uInt8 i;
259 if (m_pParent != nullptr)
261 i = 254;
262 while (i && aSet.IsSet(SdrLayerID(i)))
263 --i;
264 assert(i != 0);
265 if (i == 0)
266 i = 254;
268 else
270 i = 0;
271 while (i<=254 && aSet.IsSet(SdrLayerID(i)))
272 i++;
273 assert(i <= 254);
274 if (i>254)
275 i = 0;
277 return SdrLayerID(i);
280 void SdrLayerAdmin::SetControlLayerName(const OUString& rNewName)
282 maControlLayerName = rNewName;
285 void SdrLayerAdmin::getVisibleLayersODF( SdrLayerIDSet& rOutSet) const
287 rOutSet.ClearAll();
288 for( auto & pCurrentLayer : maLayers )
290 if ( pCurrentLayer->IsVisibleODF() )
291 rOutSet.Set( pCurrentLayer->GetID() );
295 void SdrLayerAdmin::getPrintableLayersODF( SdrLayerIDSet& rOutSet) const
297 rOutSet.ClearAll();
298 for( auto & pCurrentLayer : maLayers )
300 if ( pCurrentLayer->IsPrintableODF() )
301 rOutSet.Set( pCurrentLayer->GetID() );
305 void SdrLayerAdmin::getLockedLayersODF( SdrLayerIDSet& rOutSet) const
307 rOutSet.ClearAll();
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++)
325 aTmp[nIndex] = 0;
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;
338 if (nByteIndex > 31)
339 continue; // skip position, if too large for bitfield
340 nBitpos = nLayerPos % 8;
341 aTmp[nByteIndex] |= (1 << nBitpos);
343 ++nLayerIndex;
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;
353 break;
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); });
359 rAny <<= aSeq;
362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */