cid#1606940 Check of thread-shared field evades lock acquisition
[LibreOffice.git] / editeng / source / outliner / paralist.cxx
blobd25a00b18207afa3fd230c62475254a6690cf653
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 .
21 #include "paralist.hxx"
23 #include <editeng/outliner.hxx>
24 #include <editeng/numdef.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <osl/diagnose.h>
27 #include <sal/log.hxx>
28 #include <tools/debug.hxx>
29 #include <libxml/xmlwriter.h>
31 ParagraphData::ParagraphData()
32 : nDepth( -1 )
33 , mnNumberingStartValue( -1 )
34 , mbParaIsNumberingRestart( false )
38 bool ParagraphData::operator==(const ParagraphData& rCandidate) const
40 return (nDepth == rCandidate.nDepth
41 && mnNumberingStartValue == rCandidate.mnNumberingStartValue
42 && mbParaIsNumberingRestart == rCandidate.mbParaIsNumberingRestart);
45 Paragraph::Paragraph( sal_Int16 nDDepth )
46 : aBulSize( -1, -1)
49 DBG_ASSERT( ( nDDepth >= -1 ) && ( nDDepth < SVX_MAX_NUM ), "Paragraph-CTOR: nDepth invalid!" );
51 nDepth = nDDepth;
52 nFlags = ParaFlag::NONE;
53 bVisible = true;
56 Paragraph::Paragraph( const ParagraphData& rData )
57 : aBulSize( -1, -1)
58 , nFlags( ParaFlag::NONE )
59 , bVisible( true )
61 nDepth = rData.nDepth;
62 mnNumberingStartValue = rData.mnNumberingStartValue;
63 mbParaIsNumberingRestart = rData.mbParaIsNumberingRestart;
66 Paragraph::~Paragraph()
70 void Paragraph::SetNumberingStartValue( sal_Int16 nNumberingStartValue )
72 mnNumberingStartValue = nNumberingStartValue;
73 if( mnNumberingStartValue != -1 )
74 mbParaIsNumberingRestart = true;
77 void Paragraph::SetParaIsNumberingRestart( bool bParaIsNumberingRestart )
79 mbParaIsNumberingRestart = bParaIsNumberingRestart;
80 if( !mbParaIsNumberingRestart )
81 mnNumberingStartValue = -1;
84 void Paragraph::dumpAsXml(xmlTextWriterPtr pWriter) const
86 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("Paragraph"));
87 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("nDepth"), "%" SAL_PRIdINT32, static_cast<sal_Int32>(nDepth));
88 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("mnNumberingStartValue"), "%" SAL_PRIdINT32, static_cast<sal_Int32>(mnNumberingStartValue));
89 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("mbParaIsNumberingRestart"), "%" SAL_PRIdINT32, static_cast<sal_Int32>(mbParaIsNumberingRestart));
90 (void)xmlTextWriterEndElement(pWriter);
93 void ParagraphList::Clear()
95 maEntries.clear();
98 void ParagraphList::Append( std::unique_ptr<Paragraph> pPara)
100 SAL_WARN_IF( maEntries.size() >= EE_PARA_MAX, "editeng", "ParagraphList::Append - overflow");
101 maEntries.push_back(std::move(pPara));
104 void ParagraphList::Insert( std::unique_ptr<Paragraph> pPara, sal_Int32 nAbsPos)
106 SAL_WARN_IF( nAbsPos < 0 || (maEntries.size() < o3tl::make_unsigned(nAbsPos) && nAbsPos != EE_PARA_MAX),
107 "editeng", "ParagraphList::Insert - bad insert position " << nAbsPos);
108 SAL_WARN_IF( maEntries.size() >= EE_PARA_MAX, "editeng", "ParagraphList::Insert - overflow");
110 if (nAbsPos < 0 || maEntries.size() <= o3tl::make_unsigned(nAbsPos))
111 Append( std::move(pPara) );
112 else
113 maEntries.insert(maEntries.begin()+nAbsPos, std::move(pPara));
116 void ParagraphList::Remove( sal_Int32 nPara )
118 if (nPara < 0 || maEntries.size() <= o3tl::make_unsigned(nPara))
120 SAL_WARN( "editeng", "ParagraphList::Remove - out of bounds " << nPara);
121 return;
124 maEntries.erase(maEntries.begin() + nPara );
127 void ParagraphList::MoveParagraphs( sal_Int32 nStart, sal_Int32 nDest, sal_Int32 _nCount )
129 OSL_ASSERT(o3tl::make_unsigned(nStart) < maEntries.size() && o3tl::make_unsigned(nDest) < maEntries.size());
131 if ( (( nDest < nStart ) || ( nDest >= ( nStart + _nCount ) )) && nStart >= 0 && nDest >= 0 && _nCount >= 0 )
133 std::vector<std::unique_ptr<Paragraph>> aParas;
134 auto iterBeg = maEntries.begin() + nStart;
135 auto iterEnd = iterBeg + _nCount;
137 for (auto it = iterBeg; it != iterEnd; ++it)
138 aParas.push_back(std::move(*it));
140 maEntries.erase(iterBeg,iterEnd);
142 if ( nDest > nStart )
143 nDest -= _nCount;
145 for (auto & i : aParas)
147 maEntries.insert(maEntries.begin() + nDest, std::move(i));
148 ++nDest;
151 else
153 OSL_FAIL( "MoveParagraphs: Invalid Parameters" );
157 bool ParagraphList::HasChildren( Paragraph const * pParagraph ) const
159 sal_Int32 n = GetAbsPos( pParagraph );
160 Paragraph* pNext = GetParagraph( ++n );
161 return pNext && ( pNext->GetDepth() > pParagraph->GetDepth() );
164 bool ParagraphList::HasHiddenChildren( Paragraph const * pParagraph ) const
166 sal_Int32 n = GetAbsPos( pParagraph );
167 Paragraph* pNext = GetParagraph( ++n );
168 return pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && !pNext->IsVisible();
171 bool ParagraphList::HasVisibleChildren( Paragraph const * pParagraph ) const
173 sal_Int32 n = GetAbsPos( pParagraph );
174 Paragraph* pNext = GetParagraph( ++n );
175 return pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && pNext->IsVisible();
178 sal_Int32 ParagraphList::GetChildCount( Paragraph const * pParent ) const
180 sal_Int32 nChildCount = 0;
181 sal_Int32 n = GetAbsPos( pParent );
182 Paragraph* pPara = GetParagraph( ++n );
183 while ( pPara && ( pPara->GetDepth() > pParent->GetDepth() ) )
185 nChildCount++;
186 pPara = GetParagraph( ++n );
188 return nChildCount;
191 Paragraph* ParagraphList::GetParent( Paragraph const * pParagraph ) const
193 sal_Int32 n = GetAbsPos( pParagraph );
194 Paragraph* pPrev = GetParagraph( --n );
195 while ( pPrev && ( pPrev->GetDepth() >= pParagraph->GetDepth() ) )
197 pPrev = GetParagraph( --n );
200 return pPrev;
203 void ParagraphList::Expand( Paragraph const * pParent )
205 sal_Int32 nChildCount = GetChildCount( pParent );
206 sal_Int32 nPos = GetAbsPos( pParent );
208 for ( sal_Int32 n = 1; n <= nChildCount; n++ )
210 Paragraph* pPara = GetParagraph( nPos+n );
211 if ( !( pPara->IsVisible() ) )
213 pPara->bVisible = true;
214 aVisibleStateChangedHdl.Call( *pPara );
219 void ParagraphList::Collapse( Paragraph const * pParent )
221 sal_Int32 nChildCount = GetChildCount( pParent );
222 sal_Int32 nPos = GetAbsPos( pParent );
224 for ( sal_Int32 n = 1; n <= nChildCount; n++ )
226 Paragraph* pPara = GetParagraph( nPos+n );
227 if ( pPara->IsVisible() )
229 pPara->bVisible = false;
230 aVisibleStateChangedHdl.Call( *pPara );
235 sal_Int32 ParagraphList::GetAbsPos( Paragraph const * pParent ) const
237 sal_Int32 pos = 0;
238 for (auto const& entry : maEntries)
240 if (entry.get() == pParent)
241 return pos;
242 ++pos;
245 return EE_PARA_MAX;
248 void ParagraphList::dumpAsXml(xmlTextWriterPtr pWriter) const
250 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ParagraphList"));
251 for (auto const & pParagraph : maEntries)
252 pParagraph->dumpAsXml(pWriter);
253 (void)xmlTextWriterEndElement(pWriter);
256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */