1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <numrule.hxx>
27 SwList::SwList( OUString sListId
,
28 SwNumRule
& rDefaultListStyle
,
29 const SwNodes
& rNodes
)
30 : msListId( std::move(sListId
) ),
31 msDefaultListStyleName( rDefaultListStyle
.GetName() ),
32 mnMarkedListLevel( MAXLEVEL
)
34 // create empty list trees for the document ranges
35 const SwNode
* pNode
= rNodes
[SwNodeOffset(0)];
36 std::vector
<bool> aVisited(static_cast<sal_Int32
>(rNodes
.Count()), false);
39 SwNodeOffset nIndex
= pNode
->GetIndex();
40 if (aVisited
[static_cast<sal_Int32
>(nIndex
)])
42 // crashtesting ooo84576-1.odt, which manages to trigger a broken document structure
43 // in our code. This is just a workaround to prevent an infinite loop leading to OOM.
44 SAL_WARN("sw.core", "corrupt document structure, bailing out of infinite loop");
45 throw css::uno::RuntimeException("corrupt document structure, bailing out of infinite loop");
47 aVisited
[static_cast<sal_Int32
>(nIndex
)] = true;
48 SwPaM
aPam( *pNode
, *pNode
->EndOfSectionNode() );
50 maListTrees
.emplace_back(
51 std::make_unique
<SwNodeNum
>( &rDefaultListStyle
),
52 std::make_unique
<SwNodeNum
>( &rDefaultListStyle
),
53 std::make_unique
<SwNodeNum
>( &rDefaultListStyle
),
54 std::make_unique
<SwPaM
>( *(aPam
.Start()), *(aPam
.End()) ));
56 pNode
= pNode
->EndOfSectionNode();
57 if (pNode
!= &rNodes
.GetEndOfContent())
59 nIndex
= pNode
->GetIndex();
61 pNode
= rNodes
[nIndex
];
64 while ( pNode
!= &rNodes
.GetEndOfContent() );
67 SwList::~SwList() COVERITY_NOEXCEPT_FALSE
69 for ( auto& rNumberTree
: maListTrees
)
71 SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree
.pRoot
));
72 SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree
.pRootRLHidden
));
73 SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree
.pRootOrigText
));
77 bool SwList::HasNodes() const
79 for (auto const& rNumberTree
: maListTrees
)
81 if (rNumberTree
.pRoot
->GetChildCount() != 0)
89 void SwList::InsertListItem(SwNodeNum
& rNodeNum
, SwListRedlineType
const eRedline
,
90 const int nLevel
, const SwDoc
& rDoc
)
92 const SwPosition
aPosOfNodeNum( rNodeNum
.GetPosition() );
93 const SwNodes
* pNodesOfNodeNum
= &(aPosOfNodeNum
.GetNode().GetNodes());
95 for ( const auto& rNumberTree
: maListTrees
)
97 auto [pStart
, pEnd
] = rNumberTree
.pSection
->StartEnd(); // SwPosition*
98 const SwNodes
* pRangeNodes
= &(pStart
->GetNode().GetNodes());
100 if ( pRangeNodes
== pNodesOfNodeNum
&&
101 *pStart
<= aPosOfNodeNum
&& aPosOfNodeNum
<= *pEnd
)
103 auto const& pRoot(SwListRedlineType::HIDDEN
== eRedline
104 ? rNumberTree
.pRootRLHidden
105 : SwListRedlineType::SHOW
== eRedline
107 : rNumberTree
.pRootOrigText
);
108 pRoot
->AddChild(&rNodeNum
, nLevel
, rDoc
);
114 void SwList::RemoveListItem(SwNodeNum
& rNodeNum
, const SwDoc
& rDoc
)
116 rNodeNum
.RemoveMe(rDoc
);
119 void SwList::InvalidateListTree()
121 for ( const auto& rNumberTree
: maListTrees
)
123 rNumberTree
.pRoot
->InvalidateTree();
124 rNumberTree
.pRootRLHidden
->InvalidateTree();
125 rNumberTree
.pRootOrigText
->InvalidateTree();
129 void SwList::ValidateListTree(const SwDoc
& rDoc
)
131 for ( auto& rNumberTree
: maListTrees
)
133 rNumberTree
.pRoot
->NotifyInvalidChildren(rDoc
);
134 rNumberTree
.pRootRLHidden
->NotifyInvalidChildren(rDoc
);
135 rNumberTree
.pRootOrigText
->NotifyInvalidChildren(rDoc
);
139 void SwList::MarkListLevel( const int nListLevel
,
144 if ( nListLevel
!= mnMarkedListLevel
)
146 if ( mnMarkedListLevel
!= MAXLEVEL
)
148 // notify former marked list nodes
149 NotifyItemsOnListLevel( mnMarkedListLevel
);
152 mnMarkedListLevel
= nListLevel
;
154 // notify new marked list nodes
155 NotifyItemsOnListLevel( mnMarkedListLevel
);
160 if ( mnMarkedListLevel
!= MAXLEVEL
)
162 // notify former marked list nodes
163 NotifyItemsOnListLevel( mnMarkedListLevel
);
166 mnMarkedListLevel
= MAXLEVEL
;
170 bool SwList::IsListLevelMarked( const int nListLevel
) const
172 return nListLevel
== mnMarkedListLevel
;
175 void SwList::NotifyItemsOnListLevel( const int nLevel
)
177 for ( auto& rNumberTree
: maListTrees
)
179 rNumberTree
.pRoot
->NotifyNodesOnListLevel( nLevel
);
180 rNumberTree
.pRootRLHidden
->NotifyNodesOnListLevel( nLevel
);
181 rNumberTree
.pRootOrigText
->NotifyNodesOnListLevel( nLevel
);
185 void SwList::SetDefaultListStyleName(OUString
const& rNew
)
187 msDefaultListStyleName
= rNew
;
190 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */