LibreOffice Module sw (master) 1
list.cxx
Go to the documentation of this file.
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#include <list.hxx>
21
22#include <numrule.hxx>
23#include <ndarr.hxx>
24#include <node.hxx>
25#include <utility>
26
27SwList::SwList( OUString sListId,
28 SwNumRule& rDefaultListStyle,
29 const SwNodes& rNodes )
30 : msListId( std::move(sListId) ),
31 msDefaultListStyleName( rDefaultListStyle.GetName() ),
32 mnMarkedListLevel( MAXLEVEL )
33{
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);
37 do
38 {
39 SwNodeOffset nIndex = pNode->GetIndex();
40 if (aVisited[static_cast<sal_Int32>(nIndex)])
41 {
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");
46 }
47 aVisited[static_cast<sal_Int32>(nIndex)] = true;
48 SwPaM aPam( *pNode, *pNode->EndOfSectionNode() );
49
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()) ));
55
56 pNode = pNode->EndOfSectionNode();
57 if (pNode != &rNodes.GetEndOfContent())
58 {
59 nIndex = pNode->GetIndex();
60 nIndex++;
61 pNode = rNodes[nIndex];
62 }
63 }
64 while ( pNode != &rNodes.GetEndOfContent() );
65}
66
67SwList::~SwList() COVERITY_NOEXCEPT_FALSE
68{
69 for ( auto& rNumberTree : maListTrees )
70 {
72 SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree.pRootRLHidden));
73 SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree.pRootOrigText));
74 }
75}
76
77bool SwList::HasNodes() const
78{
79 for (auto const& rNumberTree : maListTrees)
80 {
81 if (rNumberTree.pRoot->GetChildCount() != 0)
82 {
83 return true;
84 }
85 }
86 return false;
87}
88
89void SwList::InsertListItem(SwNodeNum& rNodeNum, SwListRedlineType const eRedline,
90 const int nLevel, const SwDoc& rDoc)
91{
92 const SwPosition aPosOfNodeNum( rNodeNum.GetPosition() );
93 const SwNodes* pNodesOfNodeNum = &(aPosOfNodeNum.GetNode().GetNodes());
94
95 for ( const auto& rNumberTree : maListTrees )
96 {
97 auto [pStart, pEnd] = rNumberTree.pSection->StartEnd(); // SwPosition*
98 const SwNodes* pRangeNodes = &(pStart->GetNode().GetNodes());
99
100 if ( pRangeNodes == pNodesOfNodeNum &&
101 *pStart <= aPosOfNodeNum && aPosOfNodeNum <= *pEnd)
102 {
103 auto const& pRoot(SwListRedlineType::HIDDEN == eRedline
104 ? rNumberTree.pRootRLHidden
105 : SwListRedlineType::SHOW == eRedline
106 ? rNumberTree.pRoot
107 : rNumberTree.pRootOrigText);
108 pRoot->AddChild(&rNodeNum, nLevel, rDoc);
109 break;
110 }
111 }
112}
113
114void SwList::RemoveListItem(SwNodeNum& rNodeNum, const SwDoc& rDoc)
115{
116 rNodeNum.RemoveMe(rDoc);
117}
118
120{
121 for ( const auto& rNumberTree : maListTrees )
122 {
123 rNumberTree.pRoot->InvalidateTree();
124 rNumberTree.pRootRLHidden->InvalidateTree();
125 rNumberTree.pRootOrigText->InvalidateTree();
126 }
127}
128
130{
131 for ( auto& rNumberTree : maListTrees )
132 {
133 rNumberTree.pRoot->NotifyInvalidChildren(rDoc);
134 rNumberTree.pRootRLHidden->NotifyInvalidChildren(rDoc);
135 rNumberTree.pRootOrigText->NotifyInvalidChildren(rDoc);
136 }
137}
138
139void SwList::MarkListLevel( const int nListLevel,
140 const bool bValue )
141{
142 if ( bValue )
143 {
144 if ( nListLevel != mnMarkedListLevel )
145 {
147 {
148 // notify former marked list nodes
150 }
151
152 mnMarkedListLevel = nListLevel;
153
154 // notify new marked list nodes
156 }
157 }
158 else
159 {
161 {
162 // notify former marked list nodes
164 }
165
167 }
168}
169
170bool SwList::IsListLevelMarked( const int nListLevel ) const
171{
172 return nListLevel == mnMarkedListLevel;
173}
174
175void SwList::NotifyItemsOnListLevel( const int nLevel )
176{
177 for ( auto& rNumberTree : maListTrees )
178 {
179 rNumberTree.pRoot->NotifyNodesOnListLevel( nLevel );
180 rNumberTree.pRootRLHidden->NotifyNodesOnListLevel( nLevel );
181 rNumberTree.pRootOrigText->NotifyNodesOnListLevel( nLevel );
182 }
183}
184
185void SwList::SetDefaultListStyleName(OUString const& rNew)
186{
188}
189
190/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: doc.hxx:197
void InsertListItem(SwNodeNum &rNodeNum, SwListRedlineType eRedlines, const int nLevel, const SwDoc &rDoc)
Definition: list.cxx:89
bool HasNodes() const
Definition: list.cxx:77
int mnMarkedListLevel
Definition: list.hxx:111
static void RemoveListItem(SwNodeNum &rNodeNum, const SwDoc &rDoc)
Definition: list.cxx:114
void InvalidateListTree()
Definition: list.cxx:119
void NotifyItemsOnListLevel(const int nLevel)
Definition: list.cxx:175
OUString msDefaultListStyleName
Definition: list.hxx:78
bool IsListLevelMarked(const int nListLevel) const
Definition: list.cxx:170
void ValidateListTree(const SwDoc &rDoc)
Definition: list.cxx:129
void MarkListLevel(const int nListLevel, const bool bValue)
Definition: list.cxx:139
std::vector< tListTreeForRange > maListTrees
Definition: list.hxx:109
SwList(OUString sListId, SwNumRule &rDefaultListStyle, const SwNodes &rNodes)
Definition: list.cxx:27
void SetDefaultListStyleName(OUString const &)
Definition: list.cxx:185
~SwList() COVERITY_NOEXCEPT_FALSE
Definition: list.cxx:67
SwPosition GetPosition() const
Definition: SwNodeNum.cxx:64
static void HandleNumberTreeRootNodeDelete(SwNodeNum &rNodeNum)
Definition: SwNodeNum.cxx:291
Base class of the Writer document model elements.
Definition: node.hxx:98
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:695
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
SwNodeOffset Count() const
Definition: ndarr.hxx:142
void RemoveMe(const SwDoc &rDoc)
Remove this child from the tree.
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
virtual OUString GetName() const override
sal_Int32 nIndex
SwListRedlineType
Definition: list.hxx:33
#define SAL_WARN(area, stream)
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
Marks a position in the document model.
Definition: pam.hxx:38
SwNode & GetNode() const
Definition: pam.hxx:81
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92