/src/libreoffice/editeng/source/outliner/paralist.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | |
21 | | #include "paralist.hxx" |
22 | | |
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> |
30 | | |
31 | | ParagraphData::ParagraphData() |
32 | 22.3M | : nDepth( -1 ) |
33 | 22.3M | , mnNumberingStartValue( -1 ) |
34 | 22.3M | , mbParaIsNumberingRestart( false ) |
35 | 22.3M | { |
36 | 22.3M | } |
37 | | |
38 | | bool ParagraphData::operator==(const ParagraphData& rCandidate) const |
39 | 0 | { |
40 | 0 | return (nDepth == rCandidate.nDepth |
41 | 0 | && mnNumberingStartValue == rCandidate.mnNumberingStartValue |
42 | 0 | && mbParaIsNumberingRestart == rCandidate.mbParaIsNumberingRestart); |
43 | 0 | } |
44 | | |
45 | | Paragraph::Paragraph( sal_Int16 nDDepth ) |
46 | 4.95M | : aBulSize( -1, -1) |
47 | 4.95M | { |
48 | | |
49 | 4.95M | DBG_ASSERT( ( nDDepth >= -1 ) && ( nDDepth < SVX_MAX_NUM ), "Paragraph-CTOR: nDepth invalid!" ); |
50 | | |
51 | 4.95M | nDepth = nDDepth; |
52 | 4.95M | nFlags = ParaFlag::NONE; |
53 | 4.95M | bVisible = true; |
54 | 4.95M | } |
55 | | |
56 | | Paragraph::Paragraph( const ParagraphData& rData ) |
57 | 4.19M | : aBulSize( -1, -1) |
58 | 4.19M | , nFlags( ParaFlag::NONE ) |
59 | 4.19M | , bVisible( true ) |
60 | 4.19M | { |
61 | 4.19M | nDepth = rData.nDepth; |
62 | 4.19M | mnNumberingStartValue = rData.mnNumberingStartValue; |
63 | 4.19M | mbParaIsNumberingRestart = rData.mbParaIsNumberingRestart; |
64 | 4.19M | } |
65 | | |
66 | | Paragraph::~Paragraph() |
67 | 9.14M | { |
68 | 9.14M | } |
69 | | |
70 | | void Paragraph::SetNumberingStartValue( sal_Int16 nNumberingStartValue ) |
71 | 0 | { |
72 | 0 | mnNumberingStartValue = nNumberingStartValue; |
73 | 0 | if( mnNumberingStartValue != -1 ) |
74 | 0 | mbParaIsNumberingRestart = true; |
75 | 0 | } |
76 | | |
77 | | void Paragraph::SetParaIsNumberingRestart( bool bParaIsNumberingRestart ) |
78 | 50 | { |
79 | 50 | mbParaIsNumberingRestart = bParaIsNumberingRestart; |
80 | 50 | if( !mbParaIsNumberingRestart ) |
81 | 0 | mnNumberingStartValue = -1; |
82 | 50 | } |
83 | | |
84 | | void Paragraph::dumpAsXml(xmlTextWriterPtr pWriter) const |
85 | 0 | { |
86 | 0 | (void)xmlTextWriterStartElement(pWriter, BAD_CAST("Paragraph")); |
87 | 0 | (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("nDepth"), "%" SAL_PRIdINT32, static_cast<sal_Int32>(nDepth)); |
88 | 0 | (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("mnNumberingStartValue"), "%" SAL_PRIdINT32, static_cast<sal_Int32>(mnNumberingStartValue)); |
89 | 0 | (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("mbParaIsNumberingRestart"), "%" SAL_PRIdINT32, static_cast<sal_Int32>(mbParaIsNumberingRestart)); |
90 | 0 | (void)xmlTextWriterEndElement(pWriter); |
91 | 0 | } |
92 | | |
93 | | void ParagraphList::Clear() |
94 | 6.18M | { |
95 | 6.18M | maEntries.clear(); |
96 | 6.18M | } |
97 | | |
98 | | void ParagraphList::Append( std::unique_ptr<Paragraph> pPara) |
99 | 9.13M | { |
100 | 9.13M | SAL_WARN_IF( maEntries.size() >= EE_PARA_MAX, "editeng", "ParagraphList::Append - overflow"); |
101 | 9.13M | maEntries.push_back(std::move(pPara)); |
102 | 9.13M | } |
103 | | |
104 | | void ParagraphList::Insert( std::unique_ptr<Paragraph> pPara, sal_Int32 nAbsPos) |
105 | 776k | { |
106 | 776k | SAL_WARN_IF( nAbsPos < 0 || (maEntries.size() < o3tl::make_unsigned(nAbsPos) && nAbsPos != EE_PARA_MAX), |
107 | 776k | "editeng", "ParagraphList::Insert - bad insert position " << nAbsPos); |
108 | 776k | SAL_WARN_IF( maEntries.size() >= EE_PARA_MAX, "editeng", "ParagraphList::Insert - overflow"); |
109 | | |
110 | 776k | if (nAbsPos < 0 || maEntries.size() <= o3tl::make_unsigned(nAbsPos)) |
111 | 759k | Append( std::move(pPara) ); |
112 | 17.3k | else |
113 | 17.3k | maEntries.insert(maEntries.begin()+nAbsPos, std::move(pPara)); |
114 | 776k | } |
115 | | |
116 | | void ParagraphList::Remove( sal_Int32 nPara ) |
117 | 82.1k | { |
118 | 82.1k | if (nPara < 0 || maEntries.size() <= o3tl::make_unsigned(nPara)) |
119 | 0 | { |
120 | 0 | SAL_WARN( "editeng", "ParagraphList::Remove - out of bounds " << nPara); |
121 | 0 | return; |
122 | 0 | } |
123 | | |
124 | 82.1k | maEntries.erase(maEntries.begin() + nPara ); |
125 | 82.1k | } |
126 | | |
127 | | void ParagraphList::MoveParagraphs( sal_Int32 nStart, sal_Int32 nDest, sal_Int32 _nCount ) |
128 | 0 | { |
129 | 0 | OSL_ASSERT(o3tl::make_unsigned(nStart) < maEntries.size() && o3tl::make_unsigned(nDest) < maEntries.size()); |
130 | |
|
131 | 0 | if ( (( nDest < nStart ) || ( nDest >= ( nStart + _nCount ) )) && nStart >= 0 && nDest >= 0 && _nCount >= 0 ) |
132 | 0 | { |
133 | 0 | std::vector<std::unique_ptr<Paragraph>> aParas; |
134 | 0 | auto iterBeg = maEntries.begin() + nStart; |
135 | 0 | auto iterEnd = iterBeg + _nCount; |
136 | |
|
137 | 0 | for (auto it = iterBeg; it != iterEnd; ++it) |
138 | 0 | aParas.push_back(std::move(*it)); |
139 | |
|
140 | 0 | maEntries.erase(iterBeg,iterEnd); |
141 | |
|
142 | 0 | if ( nDest > nStart ) |
143 | 0 | nDest -= _nCount; |
144 | |
|
145 | 0 | for (auto & i : aParas) |
146 | 0 | { |
147 | 0 | maEntries.insert(maEntries.begin() + nDest, std::move(i)); |
148 | 0 | ++nDest; |
149 | 0 | } |
150 | 0 | } |
151 | 0 | else |
152 | 0 | { |
153 | 0 | OSL_FAIL( "MoveParagraphs: Invalid Parameters" ); |
154 | 0 | } |
155 | 0 | } |
156 | | |
157 | | bool ParagraphList::HasChildren( Paragraph const * pParagraph ) const |
158 | 0 | { |
159 | 0 | sal_Int32 n = GetAbsPos( pParagraph ); |
160 | 0 | Paragraph* pNext = GetParagraph( ++n ); |
161 | 0 | return pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ); |
162 | 0 | } |
163 | | |
164 | | bool ParagraphList::HasHiddenChildren( Paragraph const * pParagraph ) const |
165 | 0 | { |
166 | 0 | sal_Int32 n = GetAbsPos( pParagraph ); |
167 | 0 | Paragraph* pNext = GetParagraph( ++n ); |
168 | 0 | return pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && !pNext->IsVisible(); |
169 | 0 | } |
170 | | |
171 | | bool ParagraphList::HasVisibleChildren( Paragraph const * pParagraph ) const |
172 | 0 | { |
173 | 0 | sal_Int32 n = GetAbsPos( pParagraph ); |
174 | 0 | Paragraph* pNext = GetParagraph( ++n ); |
175 | 0 | return pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && pNext->IsVisible(); |
176 | 0 | } |
177 | | |
178 | | sal_Int32 ParagraphList::GetChildCount( Paragraph const * pParent ) const |
179 | 0 | { |
180 | 0 | sal_Int32 nChildCount = 0; |
181 | 0 | sal_Int32 n = GetAbsPos( pParent ); |
182 | 0 | Paragraph* pPara = GetParagraph( ++n ); |
183 | 0 | while ( pPara && ( pPara->GetDepth() > pParent->GetDepth() ) ) |
184 | 0 | { |
185 | 0 | nChildCount++; |
186 | 0 | pPara = GetParagraph( ++n ); |
187 | 0 | } |
188 | 0 | return nChildCount; |
189 | 0 | } |
190 | | |
191 | | Paragraph* ParagraphList::GetParent( Paragraph const * pParagraph ) const |
192 | 0 | { |
193 | 0 | sal_Int32 n = GetAbsPos( pParagraph ); |
194 | 0 | Paragraph* pPrev = GetParagraph( --n ); |
195 | 0 | while ( pPrev && ( pPrev->GetDepth() >= pParagraph->GetDepth() ) ) |
196 | 0 | { |
197 | 0 | pPrev = GetParagraph( --n ); |
198 | 0 | } |
199 | |
|
200 | 0 | return pPrev; |
201 | 0 | } |
202 | | |
203 | | void ParagraphList::Expand( Paragraph const * pParent ) |
204 | 0 | { |
205 | 0 | sal_Int32 nChildCount = GetChildCount( pParent ); |
206 | 0 | sal_Int32 nPos = GetAbsPos( pParent ); |
207 | |
|
208 | 0 | for ( sal_Int32 n = 1; n <= nChildCount; n++ ) |
209 | 0 | { |
210 | 0 | Paragraph* pPara = GetParagraph( nPos+n ); |
211 | 0 | if ( !( pPara->IsVisible() ) ) |
212 | 0 | { |
213 | 0 | pPara->bVisible = true; |
214 | 0 | aVisibleStateChangedHdl.Call( *pPara ); |
215 | 0 | } |
216 | 0 | } |
217 | 0 | } |
218 | | |
219 | | void ParagraphList::Collapse( Paragraph const * pParent ) |
220 | 0 | { |
221 | 0 | sal_Int32 nChildCount = GetChildCount( pParent ); |
222 | 0 | sal_Int32 nPos = GetAbsPos( pParent ); |
223 | |
|
224 | 0 | for ( sal_Int32 n = 1; n <= nChildCount; n++ ) |
225 | 0 | { |
226 | 0 | Paragraph* pPara = GetParagraph( nPos+n ); |
227 | 0 | if ( pPara->IsVisible() ) |
228 | 0 | { |
229 | 0 | pPara->bVisible = false; |
230 | 0 | aVisibleStateChangedHdl.Call( *pPara ); |
231 | 0 | } |
232 | 0 | } |
233 | 0 | } |
234 | | |
235 | | sal_Int32 ParagraphList::GetAbsPos( Paragraph const * pParent ) const |
236 | 1.30M | { |
237 | 1.30M | sal_Int32 pos = 0; |
238 | 1.30M | for (auto const& entry : maEntries) |
239 | 14.0M | { |
240 | 14.0M | if (entry.get() == pParent) |
241 | 1.30M | return pos; |
242 | 12.7M | ++pos; |
243 | 12.7M | } |
244 | | |
245 | 0 | return EE_PARA_MAX; |
246 | 1.30M | } |
247 | | |
248 | | void ParagraphList::dumpAsXml(xmlTextWriterPtr pWriter) const |
249 | 0 | { |
250 | 0 | (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ParagraphList")); |
251 | 0 | for (auto const & pParagraph : maEntries) |
252 | 0 | pParagraph->dumpAsXml(pWriter); |
253 | 0 | (void)xmlTextWriterEndElement(pWriter); |
254 | 0 | } |
255 | | |
256 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |