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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_editeng.hxx"
30 
31 #include <paralist.hxx>
32 #include <editeng/outliner.hxx>		// nur wegen Paragraph, muss geaendert werden!
33 #include <editeng/numdef.hxx>
34 
35 DBG_NAME(Paragraph)
36 
37 ParagraphData::ParagraphData()
38 : nDepth( -1 )
39 , mnNumberingStartValue( -1 )
40 , mbParaIsNumberingRestart( sal_False )
41 {
42 }
43 
44 ParagraphData::ParagraphData( const ParagraphData& r )
45 : nDepth( r.nDepth )
46 , mnNumberingStartValue( r.mnNumberingStartValue )
47 , mbParaIsNumberingRestart( r.mbParaIsNumberingRestart )
48 {
49 }
50 
51 ParagraphData& ParagraphData::operator=( const ParagraphData& r)
52 {
53     nDepth = r.nDepth;
54     mnNumberingStartValue = r.mnNumberingStartValue;
55     mbParaIsNumberingRestart = r.mbParaIsNumberingRestart;
56     return *this;
57 }
58 
59 bool ParagraphData::operator==(const ParagraphData& rCandidate) const
60 {
61     return (nDepth == rCandidate.nDepth
62         && mnNumberingStartValue == rCandidate.mnNumberingStartValue
63         && mbParaIsNumberingRestart == rCandidate.mbParaIsNumberingRestart);
64 }
65 
66 Paragraph::Paragraph( sal_Int16 nDDepth )
67 : aBulSize( -1, -1)
68 {
69 	DBG_CTOR( Paragraph, 0 );
70 
71     DBG_ASSERT(  ( nDDepth >= -1 ) && ( nDDepth < SVX_MAX_NUM ), "Paragraph-CTOR: nDepth invalid!" );
72 
73 	nDepth = nDDepth;
74 	nFlags = 0;
75 	bVisible = sal_True;
76 }
77 
78 Paragraph::Paragraph( const Paragraph& rPara )
79 : ParagraphData( rPara )
80 , aBulText( rPara.aBulText )
81 , aBulSize( rPara.aBulSize )
82 {
83 	DBG_CTOR( Paragraph, 0 );
84 
85 	nDepth = rPara.nDepth;
86 	nFlags = rPara.nFlags;
87 	bVisible = rPara.bVisible;
88 }
89 
90 Paragraph::Paragraph( const ParagraphData& rData )
91 : nFlags( 0 )
92 , aBulSize( -1, -1)
93 , bVisible( sal_True )
94 {
95 	DBG_CTOR( Paragraph, 0 );
96 
97     nDepth = rData.nDepth;
98     mnNumberingStartValue = rData.mnNumberingStartValue;
99     mbParaIsNumberingRestart = rData.mbParaIsNumberingRestart;
100 }
101 
102 Paragraph::~Paragraph()
103 {
104 	DBG_DTOR( Paragraph, 0 );
105 }
106 
107 void Paragraph::SetNumberingStartValue( sal_Int16 nNumberingStartValue )
108 {
109     mnNumberingStartValue = nNumberingStartValue;
110     if( mnNumberingStartValue != -1 )
111         mbParaIsNumberingRestart = true;
112 }
113 
114 void Paragraph::SetParaIsNumberingRestart( sal_Bool bParaIsNumberingRestart )
115 {
116     mbParaIsNumberingRestart = bParaIsNumberingRestart;
117     if( !mbParaIsNumberingRestart )
118         mnNumberingStartValue = -1;
119 }
120 
121 void ParagraphList::Clear( sal_Bool bDestroyParagraphs )
122 {
123 	if ( bDestroyParagraphs )
124 	{
125 		for ( sal_uLong n = GetParagraphCount(); n; )
126 		{
127 			Paragraph* pPara = GetParagraph( --n );
128 			delete pPara;
129 		}
130 	}
131 	List::Clear();
132 }
133 
134 void ParagraphList::MoveParagraphs( sal_uLong nStart, sal_uLong nDest, sal_uLong _nCount )
135 {
136 	if ( ( nDest < nStart ) || ( nDest >= ( nStart + _nCount ) ) )
137 	{
138 		sal_uLong n;
139 		ParagraphList aParas;
140 		for ( n = 0; n < _nCount; n++ )
141 		{
142 			Paragraph* pPara = GetParagraph( nStart );
143 			aParas.Insert( pPara, LIST_APPEND );
144 			Remove( nStart );
145 		}
146 
147 		if ( nDest > nStart )
148 			nDest -= _nCount;
149 
150 		for ( n = 0; n < _nCount; n++ )
151 		{
152 			Paragraph* pPara = aParas.GetParagraph( n );
153 			Insert( pPara, nDest++ );
154 		}
155 	}
156 	else
157 	{
158 		DBG_ERROR( "MoveParagraphs: Invalid Parameters" );
159 	}
160 }
161 
162 Paragraph* ParagraphList::NextVisible( Paragraph* pPara ) const
163 {
164 	sal_uLong n = GetAbsPos( pPara );
165 
166 	Paragraph* p = GetParagraph( ++n );
167 	while ( p && !p->IsVisible() )
168 		p = GetParagraph( ++n );
169 
170 	return p;
171 }
172 
173 Paragraph* ParagraphList::PrevVisible( Paragraph* pPara ) const
174 {
175 	sal_uLong n = GetAbsPos( pPara );
176 
177 	Paragraph* p = n ? GetParagraph( --n ) : NULL;
178 	while ( p && !p->IsVisible() )
179 		p = n ? GetParagraph( --n ) : NULL;
180 
181 	return p;
182 }
183 
184 Paragraph* ParagraphList::LastVisible() const
185 {
186 	sal_uLong n = GetParagraphCount();
187 
188 	Paragraph* p = n ? GetParagraph( --n ) : NULL;
189 	while ( p && !p->IsVisible() )
190 		p = n ? GetParagraph( --n ) : NULL;
191 
192 	return p;
193 }
194 
195 sal_Bool ParagraphList::HasChilds( Paragraph* pParagraph ) const
196 {
197 	sal_uLong n = GetAbsPos( pParagraph );
198 	Paragraph* pNext = GetParagraph( ++n );
199 	return ( pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) ) ? sal_True : sal_False;
200 }
201 
202 sal_Bool ParagraphList::HasHiddenChilds( Paragraph* pParagraph ) const
203 {
204 	sal_uLong n = GetAbsPos( pParagraph );
205 	Paragraph* pNext = GetParagraph( ++n );
206 	return ( pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && !pNext->IsVisible() ) ? sal_True : sal_False;
207 }
208 
209 sal_Bool ParagraphList::HasVisibleChilds( Paragraph* pParagraph ) const
210 {
211 	sal_uLong n = GetAbsPos( pParagraph );
212 	Paragraph* pNext = GetParagraph( ++n );
213 	return ( pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && pNext->IsVisible() ) ? sal_True : sal_False;
214 }
215 
216 sal_uLong ParagraphList::GetChildCount( Paragraph* pParent ) const
217 {
218 	sal_uLong nChildCount = 0;
219 	sal_uLong n = GetAbsPos( pParent );
220 	Paragraph* pPara = GetParagraph( ++n );
221 	while ( pPara && ( pPara->GetDepth() > pParent->GetDepth() ) )
222 	{
223 		nChildCount++;
224 		pPara = GetParagraph( ++n );
225 	}
226 	return nChildCount;
227 }
228 
229 Paragraph* ParagraphList::GetParent( Paragraph* pParagraph /*, sal_uInt16& rRelPos */ ) const
230 {
231 	/* rRelPos = 0 */;
232 	sal_uLong n = GetAbsPos( pParagraph );
233 	Paragraph* pPrev = GetParagraph( --n );
234 	while ( pPrev && ( pPrev->GetDepth() >= pParagraph->GetDepth() ) )
235 	{
236 //		if ( pPrev->GetDepth() == pParagraph->GetDepth() )
237 //			rRelPos++;
238 		pPrev = GetParagraph( --n );
239 	}
240 
241 	return pPrev;
242 }
243 
244 void ParagraphList::Expand( Paragraph* pParent )
245 {
246 	sal_uLong nChildCount = GetChildCount( pParent );
247 	sal_uLong nPos = GetAbsPos( pParent );
248 
249 	for ( sal_uLong n = 1; n <= nChildCount; n++  )
250 	{
251 		Paragraph* pPara = GetParagraph( nPos+n );
252 		if ( !( pPara->IsVisible() ) )
253 		{
254 			pPara->bVisible = sal_True;
255 			aVisibleStateChangedHdl.Call( pPara );
256 		}
257 	}
258 }
259 
260 void ParagraphList::Collapse( Paragraph* pParent )
261 {
262 	sal_uLong nChildCount = GetChildCount( pParent );
263 	sal_uLong nPos = GetAbsPos( pParent );
264 
265 	for ( sal_uLong n = 1; n <= nChildCount; n++  )
266 	{
267 		Paragraph* pPara = GetParagraph( nPos+n );
268 		if ( pPara->IsVisible() )
269 		{
270 			pPara->bVisible = sal_False;
271 			aVisibleStateChangedHdl.Call( pPara );
272 		}
273 	}
274 }
275 
276 sal_uLong ParagraphList::GetVisPos( Paragraph* pPara )
277 {
278 	sal_uLong nVisPos = 0;
279 	sal_uLong nPos = GetAbsPos( pPara );
280 	for ( sal_uLong n = 0; n < nPos; n++ )
281 	{
282 		Paragraph* _pPara = GetParagraph( n );
283 		if ( _pPara->IsVisible() )
284 			nVisPos++;
285 	}
286 	return nVisPos;
287 }
288