/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include bool SdrLayerIDSet::IsEmpty() const { for(sal_uInt8 i : m_aData) { if(i != 0) return false; } return true; } void SdrLayerIDSet::operator&=(const SdrLayerIDSet& r2ndSet) { for(sal_uInt16 i(0); i < 32; i++) { m_aData[i] &= r2ndSet.m_aData[i]; } } /** initialize this set with a UNO sequence of sal_Int8 (e.g. as stored in settings.xml) */ void SdrLayerIDSet::PutValue( const css::uno::Any & rAny ) { css::uno::Sequence< sal_Int8 > aSeq; if( !(rAny >>= aSeq) ) return; sal_Int16 nCount = static_cast(aSeq.getLength()); if( nCount > 32 ) nCount = 32; sal_Int16 nIndex; for( nIndex = 0; nIndex < nCount; nIndex++ ) { m_aData[nIndex] = static_cast(aSeq[nIndex]); } for( ; nIndex < 32; nIndex++ ) { m_aData[nIndex] = 0; } } SdrLayer::SdrLayer(SdrLayerID nNewID, OUString aNewName) : maName(std::move(aNewName)), m_pModel(nullptr), m_nID(nNewID) { // ODF default values mbVisibleODF = true; mbPrintableODF = true; mbLockedODF = false; } void SdrLayer::SetName(const OUString& rNewName) { if (rNewName == maName) return; maName = rNewName; if (m_pModel) { SdrHint aHint(SdrHintKind::LayerChange); m_pModel->Broadcast(aHint); m_pModel->SetChanged(); } } bool SdrLayer::operator==(const SdrLayer& rCmpLayer) const { return (m_nID == rCmpLayer.m_nID && maName == rCmpLayer.maName); } SdrLayerAdmin::SdrLayerAdmin(SdrLayerAdmin* pNewParent): m_pParent(pNewParent), m_pModel(nullptr), maControlLayerName(u"controls"_ustr) { } SdrLayerAdmin::SdrLayerAdmin(const SdrLayerAdmin& rSrcLayerAdmin): m_pParent(nullptr), m_pModel(nullptr), maControlLayerName(u"controls"_ustr) { *this = rSrcLayerAdmin; } SdrLayerAdmin::~SdrLayerAdmin() { } void SdrLayerAdmin::ClearLayers() { maLayers.clear(); } SdrLayerAdmin& SdrLayerAdmin::operator=(const SdrLayerAdmin& rSrcLayerAdmin) { if (this != &rSrcLayerAdmin) { maLayers.clear(); m_pParent=rSrcLayerAdmin.m_pParent; sal_uInt16 i; sal_uInt16 nCount=rSrcLayerAdmin.GetLayerCount(); for (i=0; iSetModel(pNewModelel); } } } void SdrLayerAdmin::Broadcast() const { if (m_pModel!=nullptr) { SdrHint aHint(SdrHintKind::LayerOrderChange); m_pModel->Broadcast(aHint); m_pModel->SetChanged(); } } void SdrLayerAdmin::InsertLayer(std::unique_ptr pLayer, sal_uInt16 nPos) { pLayer->SetModel(m_pModel); if(nPos==0xFFFF) maLayers.push_back(std::move(pLayer)); else maLayers.insert(maLayers.begin() + nPos, std::move(pLayer)); Broadcast(); } std::unique_ptr SdrLayerAdmin::RemoveLayer(sal_uInt16 nPos) { std::unique_ptr pRetLayer = std::move(maLayers[nPos]); maLayers.erase(maLayers.begin()+nPos); Broadcast(); return pRetLayer; } SdrLayer* SdrLayerAdmin::NewLayer(const OUString& rName, sal_uInt16 nPos) { SdrLayerID nID=GetUniqueLayerID(); SdrLayer* pLay=new SdrLayer(nID,rName); pLay->SetModel(m_pModel); if(nPos==0xFFFF) maLayers.push_back(std::unique_ptr(pLay)); else maLayers.insert(maLayers.begin() + nPos, std::unique_ptr(pLay)); Broadcast(); return pLay; } sal_uInt16 SdrLayerAdmin::GetLayerPos(const SdrLayer* pLayer) const { sal_uInt16 nRet=SDRLAYERPOS_NOTFOUND; if (pLayer!=nullptr) { auto it = std::find_if(maLayers.begin(), maLayers.end(), [&](const std::unique_ptr & p) { return p.get() == pLayer; }); if (it!=maLayers.end()) { nRet=it - maLayers.begin(); } } return nRet; } SdrLayer* SdrLayerAdmin::GetLayer(const OUString& rName) { return const_cast(const_cast(this)->GetLayer(rName)); } const SdrLayer* SdrLayerAdmin::GetLayer(const OUString& rName) const { sal_uInt16 i(0); const SdrLayer* pLay = nullptr; while(i < GetLayerCount() && !pLay) { if (rName == GetLayer(i)->GetName()) pLay = GetLayer(i); else i++; } if(!pLay && m_pParent) { pLay = m_pParent->GetLayer(rName); } return pLay; } SdrLayerID SdrLayerAdmin::GetLayerID(const OUString& rName) const { SdrLayerID nRet=SDRLAYER_NOTFOUND; const SdrLayer* pLay=GetLayer(rName); if (pLay!=nullptr) nRet=pLay->GetID(); return nRet; } const SdrLayer* SdrLayerAdmin::GetLayerPerID(SdrLayerID nID) const { for (auto const & pLayer : maLayers) if (pLayer->GetID() == nID) return pLayer.get(); return nullptr; } // Global LayerIDs begin at 0 and increase, // local LayerIDs begin at 254 and decrease; // 255 is reserved for SDRLAYER_NOTFOUND. SdrLayerID SdrLayerAdmin::GetUniqueLayerID() const { SdrLayerIDSet aSet; for (sal_uInt16 j=0; jGetID()); } sal_uInt8 i; if (m_pParent != nullptr) { i = 254; while (i && aSet.IsSet(SdrLayerID(i))) --i; assert(i != 0); if (i == 0) i = 254; } else { i = 0; while (i<=254 && aSet.IsSet(SdrLayerID(i))) i++; assert(i <= 254); if (i>254) i = 0; } return SdrLayerID(i); } void SdrLayerAdmin::SetControlLayerName(const OUString& rNewName) { maControlLayerName = rNewName; } void SdrLayerAdmin::getVisibleLayersODF( SdrLayerIDSet& rOutSet) const { rOutSet.ClearAll(); for( auto & pCurrentLayer : maLayers ) { if ( pCurrentLayer->IsVisibleODF() ) rOutSet.Set( pCurrentLayer->GetID() ); } } void SdrLayerAdmin::getPrintableLayersODF( SdrLayerIDSet& rOutSet) const { rOutSet.ClearAll(); for( auto & pCurrentLayer : maLayers ) { if ( pCurrentLayer->IsPrintableODF() ) rOutSet.Set( pCurrentLayer->GetID() ); } } void SdrLayerAdmin::getLockedLayersODF( SdrLayerIDSet& rOutSet) const { rOutSet.ClearAll(); for( auto& pCurrentLayer : maLayers ) { if ( pCurrentLayer->IsLockedODF() ) rOutSet.Set( pCurrentLayer->GetID() ); } } // Generates a bitfield for settings.xml from the SdrLayerIDSet. // Output is a UNO sequence of BYTE (which is 'short' in API). void SdrLayerAdmin::QueryValue(const SdrLayerIDSet& rViewLayerSet, css::uno::Any& rAny) { // tdf#119392 The SdrLayerIDSet in a view is ordered according LayerID, but in file // the bitfield is interpreted in order of layers in . // First generate a new bitfield based on rViewLayerSet in the needed order. sal_uInt8 aTmp[32]; // 256 bits in settings.xml makes byte 0 to 31 for (auto nIndex = 0; nIndex <32; nIndex++) { aTmp[nIndex] = 0; } sal_uInt8 nByteIndex = 0; sal_uInt8 nBitpos = 0; sal_uInt16 nLayerPos = 0; // Position of the layer in member aLayer and in in file sal_uInt16 nLayerIndex = 0; for( const auto& pCurrentLayer : maLayers ) { SdrLayerID nCurrentID = pCurrentLayer->GetID(); if ( rViewLayerSet.IsSet(nCurrentID) ) { nLayerPos = nLayerIndex; nByteIndex = nLayerPos / 8; if (nByteIndex > 31) continue; // skip position, if too large for bitfield nBitpos = nLayerPos % 8; aTmp[nByteIndex] |= (1 << nBitpos); } ++nLayerIndex; } // Second transform the bitfield to byte sequence, same as in previous version of QueryValue sal_uInt8 nNumBytesSet = 0; for( auto nIndex = 31; nIndex >= 0; nIndex--) { if( 0 != aTmp[nIndex] ) { nNumBytesSet = nIndex + 1; break; } } css::uno::Sequence< sal_Int8 > aSeq( nNumBytesSet ); std::transform(aTmp, aTmp + nNumBytesSet, aSeq.getArray(), [](const sal_uInt8 b) { return static_cast(b); }); rAny <<= aSeq; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */