Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */