xref: /trunk/main/sw/source/core/doc/list.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "precompiled_sw.hxx"
29 
30 #include <list.hxx>
31 
32 #include <vector>
33 #include <numrule.hxx>
34 #include <ndarr.hxx>
35 #include <node.hxx>
36 #include <pam.hxx>
37 #include <SwNodeNum.hxx>
38 
39 // ----------------------------------------------------------------------------
40 // SwListImpl
41 // implementation class for SwList
42 // ----------------------------------------------------------------------------
43 class SwListImpl
44 {
45     public:
46         SwListImpl( const String sListId,
47                     SwNumRule& rDefaultListStyle,
48                     const SwNodes& rNodes );
49         ~SwListImpl();
50 
51         const String GetListId() const;
52 
53         const String GetDefaultListStyleName() const;
54 
55         void InsertListItem( SwNodeNum& rNodeNum,
56                              const int nLevel );
57         void RemoveListItem( SwNodeNum& rNodeNum );
58 
59         void InvalidateListTree();
60         void ValidateListTree();
61 
62         void MarkListLevel( const int nListLevel,
63                             const sal_Bool bValue );
64 
65         bool IsListLevelMarked( const int nListLevel ) const;
66 
67     private:
68         // unique identifier of the list
69         const String msListId;
70         // default list style for the list items, identified by the list style name
71         String msDefaultListStyleName;
72 
73         // list trees for certain document ranges
74         typedef std::pair<SwNodeNum*, SwPaM*> tListTreeForRange;
75         typedef std::vector<tListTreeForRange> tListTrees;
76         tListTrees maListTrees;
77 
78         int mnMarkedListLevel;
79 
80         void NotifyItemsOnListLevel( const int nLevel );
81 };
82 
83 SwListImpl::SwListImpl( const String sListId,
84                         SwNumRule& rDefaultListStyle,
85                         const SwNodes& rNodes )
86     : msListId( sListId ),
87       msDefaultListStyleName( rDefaultListStyle.GetName() ),
88       maListTrees(),
89       mnMarkedListLevel( MAXLEVEL )
90 {
91     // create empty list trees for the document ranges
92     const SwNode* pNode = rNodes[0];
93     do
94     {
95         SwPaM aPam( *pNode, *pNode->EndOfSectionNode() );
96 
97         SwNodeNum* pNumberTreeRootNode = new SwNodeNum( &rDefaultListStyle );
98         SwPaM* pPam = new SwPaM( *(aPam.Start()), *(aPam.End()) );
99         tListTreeForRange aListTreeForRange( pNumberTreeRootNode, pPam );
100         maListTrees.push_back( aListTreeForRange );
101 
102         pNode = pNode->EndOfSectionNode();
103         if (pNode != &rNodes.GetEndOfContent())
104         {
105             sal_uLong nIndex = pNode->GetIndex();
106             nIndex++;
107             pNode = rNodes[nIndex];
108         }
109     }
110     while ( pNode != &rNodes.GetEndOfContent() );
111 }
112 
113 SwListImpl::~SwListImpl()
114 {
115     tListTrees::iterator aNumberTreeIter;
116     for ( aNumberTreeIter = maListTrees.begin();
117           aNumberTreeIter != maListTrees.end();
118           ++aNumberTreeIter )
119     {
120         SwNodeNum::HandleNumberTreeRootNodeDelete( *((*aNumberTreeIter).first) );
121         delete (*aNumberTreeIter).first;
122         delete (*aNumberTreeIter).second;
123     }
124 }
125 
126 const String SwListImpl::GetListId() const
127 {
128     return msListId;
129 }
130 
131 const String SwListImpl::GetDefaultListStyleName() const
132 {
133     return msDefaultListStyleName;
134 }
135 
136 void SwListImpl::InsertListItem( SwNodeNum& rNodeNum,
137                                  const int nLevel )
138 {
139     const SwPosition aPosOfNodeNum( rNodeNum.GetPosition() );
140     const SwNodes* pNodesOfNodeNum = &(aPosOfNodeNum.nNode.GetNode().GetNodes());
141 
142     tListTrees::const_iterator aNumberTreeIter;
143     for ( aNumberTreeIter = maListTrees.begin();
144           aNumberTreeIter != maListTrees.end();
145           ++aNumberTreeIter )
146     {
147         const SwPosition* pStart = (*aNumberTreeIter).second->Start();
148         const SwPosition* pEnd = (*aNumberTreeIter).second->End();
149         const SwNodes* pRangeNodes = &(pStart->nNode.GetNode().GetNodes());
150 
151         if ( pRangeNodes == pNodesOfNodeNum &&
152              *pStart <= aPosOfNodeNum && aPosOfNodeNum <= *pEnd)
153         {
154             (*aNumberTreeIter).first->AddChild( &rNodeNum, nLevel );
155 
156             break;
157         }
158     }
159 }
160 
161 void SwListImpl::RemoveListItem( SwNodeNum& rNodeNum )
162 {
163     rNodeNum.RemoveMe();
164 }
165 
166 void SwListImpl::InvalidateListTree()
167 {
168     tListTrees::iterator aNumberTreeIter;
169     for ( aNumberTreeIter = maListTrees.begin();
170           aNumberTreeIter != maListTrees.end();
171           ++aNumberTreeIter )
172     {
173         (*aNumberTreeIter).first->InvalidateTree();
174     }
175 }
176 
177 void SwListImpl::ValidateListTree()
178 {
179     tListTrees::iterator aNumberTreeIter;
180     for ( aNumberTreeIter = maListTrees.begin();
181           aNumberTreeIter != maListTrees.end();
182           ++aNumberTreeIter )
183     {
184         (*aNumberTreeIter).first->NotifyInvalidChildren();
185     }
186 }
187 
188 void SwListImpl::MarkListLevel( const int nListLevel,
189                                 const sal_Bool bValue )
190 {
191     if ( bValue )
192     {
193         if ( nListLevel != mnMarkedListLevel )
194         {
195             if ( mnMarkedListLevel != MAXLEVEL )
196             {
197                 // notify former marked list nodes
198                 NotifyItemsOnListLevel( mnMarkedListLevel );
199             }
200 
201             mnMarkedListLevel = nListLevel;
202 
203             // notify new marked list nodes
204             NotifyItemsOnListLevel( mnMarkedListLevel );
205         }
206     }
207     else
208     {
209         if ( mnMarkedListLevel != MAXLEVEL )
210         {
211             // notify former marked list nodes
212             NotifyItemsOnListLevel( mnMarkedListLevel );
213         }
214 
215         mnMarkedListLevel = MAXLEVEL;
216     }
217 }
218 
219 bool SwListImpl::IsListLevelMarked( const int nListLevel ) const
220 {
221     return nListLevel == mnMarkedListLevel;
222 }
223 
224 void SwListImpl::NotifyItemsOnListLevel( const int nLevel )
225 {
226     tListTrees::iterator aNumberTreeIter;
227     for ( aNumberTreeIter = maListTrees.begin();
228           aNumberTreeIter != maListTrees.end();
229           ++aNumberTreeIter )
230     {
231         (*aNumberTreeIter).first->NotifyNodesOnListLevel( nLevel );
232     }
233 }
234 
235 // ----------------------------------------------------------------------------
236 // SwList
237 // ----------------------------------------------------------------------------
238 SwList::SwList( const String sListId,
239                 SwNumRule& rDefaultListStyle,
240                 const SwNodes& rNodes )
241     : mpListImpl( new SwListImpl( sListId, rDefaultListStyle, rNodes ) )
242 {
243 }
244 
245 SwList::~SwList()
246 {
247     delete mpListImpl;
248 }
249 
250 const String SwList::GetListId() const
251 {
252     return mpListImpl->GetListId();
253 }
254 
255 const String SwList::GetDefaultListStyleName() const
256 {
257     return mpListImpl->GetDefaultListStyleName();
258 }
259 
260 void SwList::InsertListItem( SwNodeNum& rNodeNum,
261                              const int nLevel )
262 {
263     mpListImpl->InsertListItem( rNodeNum, nLevel );
264 }
265 
266 void SwList::RemoveListItem( SwNodeNum& rNodeNum )
267 {
268     mpListImpl->RemoveListItem( rNodeNum );
269 }
270 
271 void SwList::InvalidateListTree()
272 {
273     mpListImpl->InvalidateListTree();
274 }
275 
276 void SwList::ValidateListTree()
277 {
278     mpListImpl->ValidateListTree();
279 }
280 
281 void SwList::MarkListLevel( const int nListLevel,
282                                   const sal_Bool bValue )
283 {
284     mpListImpl->MarkListLevel( nListLevel, bValue );
285 }
286 
287 bool SwList::IsListLevelMarked( const int nListLevel ) const
288 {
289     return mpListImpl->IsListLevelMarked( nListLevel );
290 }
291 
292 //void SwList::ContinueList( SwList& rList )
293 //{
294 //    mpListImpl->ContinueList( rList );
295 //}
296 //const SwList* SwList::GetContinuedList() const
297 //{
298 //    return mpListImpl->GetContinuedList();
299 //}
300 //void SwList::ClearContinuation()
301 //{
302 //    mpListImpl->ClearContinuation();
303 //}
304