xref: /aoo41x/main/sw/source/core/docnode/node.cxx (revision 76b751b2)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <hintids.hxx>
28 #include <editeng/frmdiritem.hxx>
29 #include <editeng/protitem.hxx>
30 #include <com/sun/star/i18n/CharacterIteratorMode.hdl>
31 #include <fmtcntnt.hxx>
32 #include <fmtanchr.hxx>
33 #include <frmfmt.hxx>
34 #include <txtftn.hxx>
35 #include <ftnfrm.hxx>
36 #include <doc.hxx>
37 #include <docary.hxx>
38 #include <node.hxx>
39 #include <ndindex.hxx>
40 #include <numrule.hxx>
41 #include <swtable.hxx>
42 #include <ndtxt.hxx>
43 #include <pam.hxx>
44 #include <swcache.hxx>
45 #include <section.hxx>
46 #include <cntfrm.hxx>
47 #include <flyfrm.hxx>
48 #include <txtfrm.hxx>
49 #include <tabfrm.hxx>  // SwTabFrm
50 #include <viewsh.hxx>
51 #include <paratr.hxx>
52 #include <ftnidx.hxx>
53 #include <fmtftn.hxx>
54 #include <fmthdft.hxx>
55 #include <frmatr.hxx>
56 #include <fmtautofmt.hxx>
57 #include <frmtool.hxx>
58 #include <pagefrm.hxx>
59 #include <node2lay.hxx>
60 #include <pagedesc.hxx>
61 #include <fmtpdsc.hxx>
62 #include <breakit.hxx>
63 #include <crsskip.hxx>
64 #include <SwStyleNameMapper.hxx>
65 #include <scriptinfo.hxx>
66 #include <rootfrm.hxx>
67 #include <istyleaccess.hxx>
68 #include <IDocumentListItems.hxx>
69 #include <switerator.hxx>
70 #include "ndole.hxx"
71 
72 using namespace ::com::sun::star::i18n;
73 
74 TYPEINIT2( SwCntntNode, SwModify, SwIndexReg )
75 
76 /*
77  * Some local helper functions for the attribute set handle of a content node.
78  * Since the attribute set of a content node may not be modified directly,
79  * we always have to create a new SwAttrSet, do the modifications, and get
80  * a new handle from the style access
81  */
82 
83 namespace AttrSetHandleHelper
84 {
85 
86 void GetNewAutoStyle( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
87                       const SwCntntNode& rNode,
88                       SwAttrSet& rNewAttrSet )
89 {
90     const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get());
91 	if( rNode.GetModifyAtAttr() )
92         const_cast<SwAttrSet*>(pAttrSet)->SetModifyAtAttr( 0 );
93     IStyleAccess& rSA = pAttrSet->GetPool()->GetDoc()->GetIStyleAccess();
94     mrpAttrSet = rSA.getAutomaticStyle( rNewAttrSet, rNode.IsTxtNode() ?
95                                                      IStyleAccess::AUTO_STYLE_PARA :
96                                                      IStyleAccess::AUTO_STYLE_NOTXT );
97     const bool bSetModifyAtAttr = ((SwAttrSet*)mrpAttrSet.get())->SetModifyAtAttr( &rNode );
98     rNode.SetModifyAtAttr( bSetModifyAtAttr );
99 }
100 
101 
102 void SetParent( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
103                 const SwCntntNode& rNode,
104                 const SwFmt* pParentFmt,
105                 const SwFmt* pConditionalFmt )
106 {
107     const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get());
108     ASSERT( pAttrSet, "no SwAttrSet" )
109     ASSERT( pParentFmt || !pConditionalFmt, "ConditionalFmt without ParentFmt?" )
110 
111     const SwAttrSet* pParentSet = pParentFmt ? &pParentFmt->GetAttrSet() : 0;
112 
113     if ( pParentSet != pAttrSet->GetParent() )
114     {
115         SwAttrSet aNewSet( *pAttrSet );
116         aNewSet.SetParent( pParentSet );
117         aNewSet.ClearItem( RES_FRMATR_STYLE_NAME );
118         aNewSet.ClearItem( RES_FRMATR_CONDITIONAL_STYLE_NAME );
119         String sVal;
120 
121         if ( pParentFmt )
122         {
123             SwStyleNameMapper::FillProgName( pParentFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True );
124             const SfxStringItem aAnyFmtColl( RES_FRMATR_STYLE_NAME, sVal );
125             aNewSet.Put( aAnyFmtColl );
126 
127             if ( pConditionalFmt != pParentFmt )
128                 SwStyleNameMapper::FillProgName( pConditionalFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True );
129 
130             const SfxStringItem aFmtColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal );
131             aNewSet.Put( aFmtColl );
132         }
133 
134         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
135     }
136 }
137 
138 const SfxPoolItem* Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
139                         const SwCntntNode& rNode,
140                         const SfxPoolItem& rAttr )
141 {
142     SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
143     const SfxPoolItem* pRet = aNewSet.Put( rAttr );
144     if ( pRet )
145         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
146     return pRet;
147 }
148 
149 int Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, const SwCntntNode& rNode,
150          const SfxItemSet& rSet )
151 {
152     SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
153 
154     // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
155     SfxItemSet* pStyleNames = 0;
156     if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) )
157     {
158         pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME );
159         pStyleNames->Put( aNewSet );
160     }
161     // <--
162 
163     const int nRet = aNewSet.Put( rSet );
164 
165     // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
166     if ( pStyleNames )
167     {
168         aNewSet.Put( *pStyleNames );
169         delete pStyleNames;
170     }
171     // <--
172 
173     if ( nRet )
174         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
175 
176     return nRet;
177 }
178 
179 int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
180             const SwCntntNode& rNode, const SfxPoolItem& rAttr,
181             SwAttrSet* pOld, SwAttrSet* pNew )
182 {
183     SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
184 
185     // for a correct broadcast, we need to do a SetModifyAtAttr with the items
186     // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle
187     if( rNode.GetModifyAtAttr() )
188         aNewSet.SetModifyAtAttr( &rNode );
189 
190     const int nRet = aNewSet.Put_BC( rAttr, pOld, pNew );
191 
192     if ( nRet )
193         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
194 
195     return nRet;
196 }
197 
198 int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
199             const SwCntntNode& rNode, const SfxItemSet& rSet,
200             SwAttrSet* pOld, SwAttrSet* pNew )
201 {
202     SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
203 
204     // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
205     SfxItemSet* pStyleNames = 0;
206     if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) )
207     {
208         pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME );
209         pStyleNames->Put( aNewSet );
210     }
211     // <--
212 
213     // for a correct broadcast, we need to do a SetModifyAtAttr with the items
214     // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle
215 	if( rNode.GetModifyAtAttr() )
216         aNewSet.SetModifyAtAttr( &rNode );
217 
218     const int nRet = aNewSet.Put_BC( rSet, pOld, pNew );
219 
220     // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
221     if ( pStyleNames )
222     {
223         aNewSet.Put( *pStyleNames );
224         delete pStyleNames;
225     }
226     // <--
227 
228     if ( nRet )
229         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
230 
231     return nRet;
232 }
233 
234 sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
235                      const SwCntntNode& rNode, sal_uInt16 nWhich,
236                      SwAttrSet* pOld, SwAttrSet* pNew )
237 {
238     SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
239 	if( rNode.GetModifyAtAttr() )
240         aNewSet.SetModifyAtAttr( &rNode );
241     const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich, pOld, pNew );
242     if ( nRet )
243         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
244     return nRet;
245 }
246 
247 sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
248                      const SwCntntNode& rNode,
249                      sal_uInt16 nWhich1, sal_uInt16 nWhich2,
250                      SwAttrSet* pOld, SwAttrSet* pNew )
251 {
252     SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
253 	if( rNode.GetModifyAtAttr() )
254         aNewSet.SetModifyAtAttr( &rNode );
255     const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich1, nWhich2, pOld, pNew );
256     if ( nRet )
257         GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
258     return nRet;
259 }
260 
261 }
262 
263 /*******************************************************************
264 |*
265 |*	SwNode::GetSectionLevel
266 |*
267 |*	Beschreibung
268 |*		Die Funktion liefert den Sectionlevel an der durch
269 |*		aIndex bezeichneten Position.
270 |*
271 |*		Die Logik ist wie folgt:   ( S -> Start, E -> End, C -> CntntNode)
272 |*			Level 	0		E
273 |*					1 	S  E
274 |*					2  	 SC
275 |*
276 |*		alle EndNodes der GrundSection haben den Level 0
277 |*		alle StartNodes der GrundSection haben den Level 1
278 |*
279 |*	Ersterstellung
280 |*		VER0100 vb 901214
281 |*
282 |*	Aenderung:	JP	11.08.93
283 |*		keine Rekursion mehr !!
284 |*
285 *******************************************************************/
286 
287 
288 sal_uInt16 SwNode::GetSectionLevel() const
289 {
290 	// EndNode einer Grund-Section ?? diese sind immer 0 !!
291 	if( IsEndNode() && 0 == pStartOfSection->StartOfSectionIndex() )
292 		return 0;
293 
294 	sal_uInt16 nLevel;
295 	const SwNode* pNode = IsStartNode() ? this : pStartOfSection;
296 	for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel )
297 		pNode = pNode->pStartOfSection;
298 	return IsEndNode() ? nLevel-1 : nLevel;
299 }
300 
301 /*******************************************************************
302 |*
303 |*	SwNode::SwNode
304 |*
305 |*	Beschreibung
306 |*		Konstruktor; dieser fuegt einen Node in das Array rNodes
307 |*		an der Position rWhere ein. Dieser bekommt als
308 |*		theEndOfSection den EndOfSection-Index des Nodes
309 |*		unmittelbar vor ihm. Falls er sich an der Position 0
310 |*		innerhalb des variablen Arrays befindet, wird
311 |*		theEndOfSection 0 (der neue selbst).
312 |*
313 |*	Parameter
314 |*		IN
315 |*		rNodes bezeichnet das variable Array, in das der Node
316 |*		eingefuegt werden soll
317 |*		IN
318 |*		rWhere bezeichnet die Position innerhalb dieses Arrays,
319 |*		an der der Node eingefuegt werden soll
320 |*
321 |*	Ersterstellung
322 |*		VER0100 vb 901214
323 |*
324 |*	Stand
325 |*		VER0100 vb 901214
326 |*
327 *******************************************************************/
328 
329 #ifdef DBG_UTIL
330 long SwNode::nSerial = 0;
331 #endif
332 
333 SwNode::SwNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType )
334 	: nNodeType( nNdType ), pStartOfSection( 0 )
335 {
336     bSetNumLSpace = bIgnoreDontExpand = sal_False;
337 	nAFmtNumLvl = 0;
338 
339 	SwNodes& rNodes = (SwNodes&)rWhere.GetNodes();
340 	SwNode* pInsNd = this; 		// der MAC kann this nicht einfuegen !!
341 	if( rWhere.GetIndex() )
342 	{
343 		SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ];
344         rNodes.InsertNode( pInsNd, rWhere );
345 		if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
346 		{
347 			pStartOfSection = pNd->pStartOfSection;
348 			if( pNd->GetEndNode() )		// EndNode ? Section ueberspringen!
349 			{
350 				pNd = pStartOfSection;
351 				pStartOfSection = pNd->pStartOfSection;
352 			}
353 		}
354 	}
355 	else
356 	{
357         rNodes.InsertNode( pInsNd, rWhere );
358 		pStartOfSection = (SwStartNode*)this;
359 	}
360 
361 #ifdef DBG_UTIL
362     nMySerial = nSerial;
363     nSerial++;
364 #endif
365 }
366 
367 SwNode::SwNode( SwNodes& rNodes, sal_uLong nPos, const sal_uInt8 nNdType )
368 	: nNodeType( nNdType ), pStartOfSection( 0 )
369 {
370     bSetNumLSpace = bIgnoreDontExpand = sal_False;
371 	nAFmtNumLvl = 0;
372 
373 	SwNode* pInsNd = this; 		// der MAC kann this nicht einfuegen !!
374 	if( nPos )
375 	{
376 		SwNode* pNd = rNodes[ nPos - 1 ];
377         rNodes.InsertNode( pInsNd, nPos );
378 		if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
379 		{
380 			pStartOfSection = pNd->pStartOfSection;
381 			if( pNd->GetEndNode() )		// EndNode ? Section ueberspringen!
382 			{
383 				pNd = pStartOfSection;
384 				pStartOfSection = pNd->pStartOfSection;
385 			}
386 		}
387 	}
388 	else
389 	{
390         rNodes.InsertNode( pInsNd, nPos );
391 		pStartOfSection = (SwStartNode*)this;
392 	}
393 
394 #ifdef DBG_UTIL
395     nMySerial = nSerial;
396     nSerial++;
397 #endif
398 }
399 
400 SwNode::~SwNode()
401 {
402 }
403 
404 // suche den TabellenNode, in dem dieser steht. Wenn in keiner
405 // Tabelle wird 0 returnt.
406 
407 
408 SwTableNode* SwNode::FindTableNode()
409 {
410 	if( IsTableNode() )
411 		return GetTableNode();
412 	SwStartNode* pTmp = pStartOfSection;
413 	while( !pTmp->IsTableNode() && pTmp->GetIndex() )
414 #if defined( ALPHA ) && defined( UNX )
415 		pTmp = ((SwNode*)pTmp)->pStartOfSection;
416 #else
417 		pTmp = pTmp->pStartOfSection;
418 #endif
419 	return pTmp->GetTableNode();
420 }
421 
422 
423 // liegt der Node im Sichtbarenbereich der Shell ?
424 sal_Bool SwNode::IsInVisibleArea( ViewShell* pSh ) const
425 {
426 	sal_Bool bRet = sal_False;
427 	const SwCntntNode* pNd;
428 
429 	if( ND_STARTNODE & nNodeType )
430 	{
431 		SwNodeIndex aIdx( *this );
432 		pNd = GetNodes().GoNext( &aIdx );
433 	}
434 	else if( ND_ENDNODE & nNodeType )
435 	{
436 		SwNodeIndex aIdx( *EndOfSectionNode() );
437 		pNd = GetNodes().GoPrevious( &aIdx );
438 	}
439 	else
440 		pNd = GetCntntNode();
441 
442 	if( !pSh )
443 		// dann die Shell vom Doc besorgen:
444 		GetDoc()->GetEditShell( &pSh );
445 
446     if( pSh )
447     {
448 	    const SwFrm* pFrm;
449 	    if( pNd && 0 != ( pFrm = pNd->getLayoutFrm( pSh->GetLayout(), 0, 0, sal_False ) ) )
450 	    {
451 
452 			if ( pFrm->IsInTab() )
453 				pFrm = pFrm->FindTabFrm();
454 
455 			if( !pFrm->IsValid() )
456 				do
457 				{	pFrm = pFrm->FindPrev();
458 				} while ( pFrm && !pFrm->IsValid() );
459 
460 			if( !pFrm || pSh->VisArea().IsOver( pFrm->Frm() ) )
461 				bRet = sal_True;
462 		}
463 	}
464 
465 	return bRet;
466 }
467 
468 sal_Bool SwNode::IsInProtectSect() const
469 {
470 	const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
471 	const SwSectionNode* pSectNd = pNd->FindSectionNode();
472 	return pSectNd && pSectNd->GetSection().IsProtectFlag();
473 }
474 
475 	// befindet sich der Node in irgendetwas geschuetzten ?
476 	// (Bereich/Rahmen/Tabellenzellen/... incl. des Ankers bei
477 	//	Rahmen/Fussnoten/..)
478 sal_Bool SwNode::IsProtect() const
479 {
480 	const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
481 	const SwStartNode* pSttNd = pNd->FindSectionNode();
482 	if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() )
483 		return sal_True;
484 
485 	if( 0 != ( pSttNd = FindTableBoxStartNode() ) )
486 	{
487 		SwCntntFrm* pCFrm;
488 		if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->getLayoutFrm( GetDoc()->GetCurrentLayout() ) ))
489 			return pCFrm->IsProtected();
490 
491 		const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
492 										GetTblBox( pSttNd->GetIndex() );
493         //Robust #149568
494 		if( pBox && pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
495 			return sal_True;
496 	}
497 
498 	SwFrmFmt* pFlyFmt = GetFlyFmt();
499 	if( pFlyFmt )
500 	{
501 		if( pFlyFmt->GetProtect().IsCntntProtected() )
502 			return sal_True;
503 		const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
504 		return rAnchor.GetCntntAnchor()
505 				? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect()
506 				: sal_False;
507 	}
508 
509 	if( 0 != ( pSttNd = FindFootnoteStartNode() ) )
510 	{
511 		const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry(
512 								SwNodeIndex( *pSttNd ) );
513 		if( pTFtn )
514 			return pTFtn->GetTxtNode().IsProtect();
515 	}
516 
517 	return sal_False;
518 }
519 
520 	// suche den PageDesc, mit dem dieser Node formatiert ist. Wenn das
521 	// Layout vorhanden ist wird ueber das gesucht, ansonsten gibt es nur
522 	// die harte Tour ueber die Nodes nach vorne suchen!!
523 const SwPageDesc* SwNode::FindPageDesc( sal_Bool bCalcLay,
524                                         sal_uInt32* pPgDescNdIdx ) const
525 {
526     // OD 18.03.2003 #106329#
527     if ( !GetNodes().IsDocNodes() )
528     {
529         return 0;
530     }
531 
532     const SwPageDesc* pPgDesc = 0;
533 
534     const SwCntntNode* pNode;
535     if( ND_STARTNODE & nNodeType )
536     {
537         SwNodeIndex aIdx( *this );
538         pNode = GetNodes().GoNext( &aIdx );
539     }
540     else if( ND_ENDNODE & nNodeType )
541     {
542         SwNodeIndex aIdx( *EndOfSectionNode() );
543         pNode = GetNodes().GoPrevious( &aIdx );
544     }
545     else
546     {
547         pNode = GetCntntNode();
548         if( pNode )
549             pPgDesc = ((SwFmtPageDesc&)pNode->GetAttr( RES_PAGEDESC )).GetPageDesc();
550     }
551 
552     // geht es uebers Layout?
553     if( !pPgDesc )
554     {
555         const SwFrm* pFrm;
556         const SwPageFrm* pPage;
557         if( pNode && 0 != ( pFrm = pNode->getLayoutFrm( pNode->GetDoc()->GetCurrentLayout(), 0, 0, bCalcLay ) ) &&
558             0 != ( pPage = pFrm->FindPageFrm() ) )
559         {
560             pPgDesc = pPage->GetPageDesc();
561             // OD 18.03.2003 #106329#
562             if ( pPgDescNdIdx )
563             {
564                 *pPgDescNdIdx = pNode->GetIndex();
565             }
566         }
567     }
568 
569     if( !pPgDesc )
570     {
571         // dann also uebers Nodes-Array
572         const SwDoc* pDoc = GetDoc();
573         const SwNode* pNd = this;
574         const SwStartNode* pSttNd;
575         if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() &&
576             0 != ( pSttNd = pNd->FindFlyStartNode() ) )
577         {
578             // dann erstmal den richtigen Anker finden
579             const SwFrmFmt* pFmt = 0;
580             const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
581             sal_uInt16 n;
582 
583             for( n = 0; n < rFmts.Count(); ++n )
584             {
585                 SwFrmFmt* pFrmFmt = rFmts[ n ];
586                 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
587                 if( rCntnt.GetCntntIdx() &&
588                     &rCntnt.GetCntntIdx()->GetNode() == (SwNode*)pSttNd )
589                 {
590                     pFmt = pFrmFmt;
591                     break;
592                 }
593             }
594 
595             if( pFmt )
596             {
597                 const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
598                 if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
599                     pAnchor->GetCntntAnchor() )
600                 {
601                     pNd = &pAnchor->GetCntntAnchor()->nNode.GetNode();
602                     const SwNode* pFlyNd = pNd->FindFlyStartNode();
603                     while( pFlyNd )
604                     {
605                         // dann ueber den Anker nach oben "hangeln"
606                         for( n = 0; n < rFmts.Count(); ++n )
607                         {
608                             const SwFrmFmt* pFrmFmt = rFmts[ n ];
609                             const SwNodeIndex* pIdx = pFrmFmt->GetCntnt().
610                                                         GetCntntIdx();
611                             if( pIdx && pFlyNd == &pIdx->GetNode() )
612                             {
613                                 if( pFmt == pFrmFmt )
614                                 {
615                                     pNd = pFlyNd;
616                                     pFlyNd = 0;
617                                     break;
618                                 }
619                                 pAnchor = &pFrmFmt->GetAnchor();
620                                 if ((FLY_AT_PAGE == pAnchor->GetAnchorId()) ||
621                                     !pAnchor->GetCntntAnchor() )
622                                 {
623                                     pFlyNd = 0;
624                                     break;
625                                 }
626 
627                                 pFlyNd = pAnchor->GetCntntAnchor()->nNode.
628                                         GetNode().FindFlyStartNode();
629                                 break;
630                             }
631                         }
632                         if( n >= rFmts.Count() )
633                         {
634                             ASSERT( !this, "Fly-Section but no format found" );
635                             return NULL;
636                         }
637                     }
638                 }
639             }
640             // in pNd sollte jetzt der richtige Anker Node stehen oder
641             // immer noch der this
642         }
643 
644         if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() )
645         {
646             if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() )
647             {
648                 pPgDesc = &pDoc->GetPageDesc( 0 );
649                 pNd = 0;
650             }
651             else
652             {
653                 // suche den Body Textnode
654                 if( 0 != ( pSttNd = pNd->FindHeaderStartNode() ) ||
655                     0 != ( pSttNd = pNd->FindFooterStartNode() ))
656                 {
657                     // dann in den PageDescs diesen StartNode suchen
658                     sal_uInt16 nId;
659                     UseOnPage eAskUse;
660                     if( SwHeaderStartNode == pSttNd->GetStartNodeType())
661                     {
662                         nId = RES_HEADER;
663                         eAskUse = nsUseOnPage::PD_HEADERSHARE;
664                     }
665                     else
666                     {
667                         nId = RES_FOOTER;
668                         eAskUse = nsUseOnPage::PD_FOOTERSHARE;
669                     }
670 
671                     for( sal_uInt16 n = pDoc->GetPageDescCnt(); n && !pPgDesc; )
672                     {
673                         const SwPageDesc& rPgDsc = pDoc->GetPageDesc( --n );
674                         const SwFrmFmt* pFmt = &rPgDsc.GetMaster();
675                         int nStt = 0, nLast = 1;
676                         if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast;
677 
678                         for( ; nStt < nLast; ++nStt, pFmt = &rPgDsc.GetLeft() )
679                         {
680                             const SwFmtHeader& rHdFt = (SwFmtHeader&)
681                                                     pFmt->GetFmtAttr( nId );
682                             if( rHdFt.GetHeaderFmt() )
683                             {
684                                 const SwFmtCntnt& rCntnt =
685                                     rHdFt.GetHeaderFmt()->GetCntnt();
686                                 if( rCntnt.GetCntntIdx() &&
687                                     &rCntnt.GetCntntIdx()->GetNode() ==
688                                     (SwNode*)pSttNd )
689                                 {
690                                     pPgDesc = &rPgDsc;
691                                     break;
692                                 }
693                             }
694                         }
695                     }
696 
697                     if( !pPgDesc )
698                         pPgDesc = &pDoc->GetPageDesc( 0 );
699                     pNd = 0;
700                 }
701                 else if( 0 != ( pSttNd = pNd->FindFootnoteStartNode() ))
702                 {
703                     // der Anker kann nur im Bodytext sein
704                     const SwTxtFtn* pTxtFtn;
705                     const SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
706                     for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n )
707                         if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
708                             (SwNode*)pSttNd ==
709                             &pTxtFtn->GetStartNode()->GetNode() )
710                         {
711                             pNd = &pTxtFtn->GetTxtNode();
712                             break;
713                         }
714                 }
715                 else
716                 {
717                     // kann jetzt nur noch ein Seitengebundener Fly sein
718                     // oder irgendetwas neueres.
719                     // Hier koennen wir nur noch den Standard returnen
720                     ASSERT( pNd->FindFlyStartNode(),
721                             "wo befindet sich dieser Node?" );
722 
723                     pPgDesc = &pDoc->GetPageDesc( 0 );
724                     pNd = 0;
725                 }
726             }
727         }
728 
729         if( pNd )
730         {
731             SwFindNearestNode aInfo( *pNd );
732             // dann ueber alle Nodes aller PageDesc
733             const SfxPoolItem* pItem;
734             sal_uInt32 i, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_PAGEDESC );
735             for( i = 0; i < nMaxItems; ++i )
736                 if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_PAGEDESC, i ) ) &&
737                     ((SwFmtPageDesc*)pItem)->GetDefinedIn() )
738                 {
739                     const SwModify* pMod = ((SwFmtPageDesc*)pItem)->GetDefinedIn();
740                     if( pMod->ISA( SwCntntNode ) )
741                         aInfo.CheckNode( *(SwCntntNode*)pMod );
742                     else if( pMod->ISA( SwFmt ))
743                         ((SwFmt*)pMod)->GetInfo( aInfo );
744                 }
745 
746             if( 0 != ( pNd = aInfo.GetFoundNode() ))
747             {
748                 if( pNd->IsCntntNode() )
749                     pPgDesc = ((SwFmtPageDesc&)pNd->GetCntntNode()->
750                                 GetAttr( RES_PAGEDESC )).GetPageDesc();
751                 else if( pNd->IsTableNode() )
752                     pPgDesc = pNd->GetTableNode()->GetTable().
753                             GetFrmFmt()->GetPageDesc().GetPageDesc();
754                 else if( pNd->IsSectionNode() )
755                     pPgDesc = pNd->GetSectionNode()->GetSection().
756                             GetFmt()->GetPageDesc().GetPageDesc();
757                 // OD 18.03.2003 #106329#
758                 if ( pPgDescNdIdx )
759                 {
760                     *pPgDescNdIdx = pNd->GetIndex();
761                 }
762             }
763             if( !pPgDesc )
764                 pPgDesc = &pDoc->GetPageDesc( 0 );
765         }
766     }
767 	return pPgDesc;
768 }
769 
770 
771 	// falls der Node in einem Fly steht, dann wird das entsprechende Format
772 	// returnt
773 SwFrmFmt* SwNode::GetFlyFmt() const
774 {
775 	SwFrmFmt* pRet = 0;
776 	const SwNode* pSttNd = FindFlyStartNode();
777 	if( pSttNd )
778 	{
779 		if( IsCntntNode() )
780 		{
781 			SwCntntFrm* pFrm = SwIterator<SwCntntFrm,SwCntntNode>::FirstElement( *(SwCntntNode*)this );
782 			if( pFrm )
783 				pRet = pFrm->FindFlyFrm()->GetFmt();
784 		}
785 		if( !pRet )
786 		{
787 			// dann gibts noch harten steinigen Weg uebers Dokument:
788 			const SwSpzFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts();
789 			for( sal_uInt16 n = 0; n < rFrmFmtTbl.Count(); ++n )
790 			{
791 				SwFrmFmt* pFmt = rFrmFmtTbl[n];
792 				const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
793 				if( rCntnt.GetCntntIdx() &&
794 					&rCntnt.GetCntntIdx()->GetNode() == pSttNd )
795 				{
796 					pRet = pFmt;
797 					break;
798 				}
799 			}
800 		}
801 	}
802 	return pRet;
803 }
804 
805 SwTableBox* SwNode::GetTblBox() const
806 {
807 	SwTableBox* pBox = 0;
808 	const SwNode* pSttNd = FindTableBoxStartNode();
809 	if( pSttNd )
810 		pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox(
811 													pSttNd->GetIndex() );
812 	return pBox;
813 }
814 
815 SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp )
816 {
817 	SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection;
818 
819 	while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() )
820 #if defined( ALPHA ) && defined( UNX )
821 		pTmp = ((SwNode*)pTmp)->pStartOfSection;
822 #else
823 		pTmp = pTmp->pStartOfSection;
824 #endif
825 	return eTyp == pTmp->GetStartNodeType() ? pTmp : 0;
826 }
827 
828 const SwTxtNode* SwNode::FindOutlineNodeOfLevel( sal_uInt8 nLvl ) const
829 {
830 	const SwTxtNode* pRet = 0;
831 	const SwOutlineNodes& rONds = GetNodes().GetOutLineNds();
832 	if( MAXLEVEL > nLvl && rONds.Count() )
833 	{
834 		sal_uInt16 nPos;
835 		SwNode* pNd = (SwNode*)this;
836 		sal_Bool bCheckFirst = sal_False;
837 		if( !rONds.Seek_Entry( pNd, &nPos ))
838 		{
839 			if( nPos )
840 				nPos = nPos-1;
841 			else
842 				bCheckFirst = sal_True;
843 		}
844 
845 		if( bCheckFirst )
846 		{
847 			// der 1.GliederungsNode liegt hinter dem Fragenden. Dann
848 			// teste mal, ob dieser auf der gleichen Seite steht. Wenn
849 			// nicht, ist das ein ungueltiger. Bug 61865
850 			pRet = rONds[0]->GetTxtNode();
851 
852 			const SwCntntNode* pCNd = GetCntntNode();
853 
854 			Point aPt( 0, 0 );
855 			const SwFrm* pFrm = pRet->getLayoutFrm( pRet->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ),
856 					   * pMyFrm = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ) : 0;
857 			const SwPageFrm* pPgFrm = pFrm ? pFrm->FindPageFrm() : 0;
858 			if( pPgFrm && pMyFrm &&
859 				pPgFrm->Frm().Top() > pMyFrm->Frm().Top() )
860 			{
861 				// der Fragende liegt vor der Seite, also ist er ungueltig
862 				pRet = 0;
863 			}
864 		}
865 		else
866 		{
867 			// oder ans Feld und von dort holen !!
868             while( nPos &&
869                    nLvl < ( pRet = rONds[nPos]->GetTxtNode() )
870 					//->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
871                     ->GetAttrOutlineLevel() - 1 )  //<-end,zhaojianwei
872 				--nPos;
873 
874 			if( !nPos )		// bei 0 gesondert holen !!
875 				pRet = rONds[0]->GetTxtNode();
876 		}
877 	}
878 	return pRet;
879 }
880 
881 inline sal_Bool IsValidNextPrevNd( const SwNode& rNd )
882 {
883 	return ND_TABLENODE == rNd.GetNodeType() ||
884            ( ND_CONTENTNODE & rNd.GetNodeType() ) ||
885 			( ND_ENDNODE == rNd.GetNodeType() && rNd.StartOfSectionNode() &&
886             ND_TABLENODE == rNd.StartOfSectionNode()->GetNodeType() );
887 }
888 
889 sal_uInt8 SwNode::HasPrevNextLayNode() const
890 {
891     // assumption: <this> node is a node inside the document nodes array section.
892 
893 	sal_uInt8 nRet = 0;
894 	if( IsValidNextPrevNd( *this ))
895 	{
896 		SwNodeIndex aIdx( *this, -1 );
897         // --> OD 2007-06-04 #i77805#
898         // skip section start and end nodes
899         while ( aIdx.GetNode().IsSectionNode() ||
900                 ( aIdx.GetNode().IsEndNode() &&
901                   aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) )
902         {
903             --aIdx;
904         }
905         // <--
906 		if( IsValidNextPrevNd( aIdx.GetNode() ))
907 			nRet |= ND_HAS_PREV_LAYNODE;
908         // --> OD 2007-06-04 #i77805#
909         // skip section start and end nodes
910 //        aIdx += 2;
911         aIdx = SwNodeIndex( *this, +1 );
912         while ( aIdx.GetNode().IsSectionNode() ||
913                 ( aIdx.GetNode().IsEndNode() &&
914                   aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) )
915         {
916             ++aIdx;
917         }
918         // <--
919         if( IsValidNextPrevNd( aIdx.GetNode() ))
920 			nRet |= ND_HAS_NEXT_LAYNODE;
921 	}
922 	return nRet;
923 }
924 
925 /*******************************************************************
926 |*
927 |*	SwNode::StartOfSection
928 |*
929 |*	Beschreibung
930 |*		Die Funktion liefert die StartOfSection des Nodes.
931 |*
932 |*	Parameter
933 |*		IN
934 |*		rNodes bezeichnet das variable Array, in dem sich der Node
935 |*		befindet
936 |*	Ersterstellung
937 |*		VER0100 vb 901214
938 |*
939 |*	Stand
940 |*		VER0100 vb 901214
941 |*
942 *******************************************************************/
943 
944 
945 SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType,
946 							SwStartNodeType eSttNd )
947 	: SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd )
948 {
949 	// erstmal temporaer, bis der EndNode eingefuegt wird.
950 	pEndOfSection = (SwEndNode*)this;
951 }
952 
953 SwStartNode::SwStartNode( SwNodes& rNodes, sal_uLong nPos )
954 	: SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode )
955 {
956 	// erstmal temporaer, bis der EndNode eingefuegt wird.
957 	pEndOfSection = (SwEndNode*)this;
958 }
959 
960 
961 void SwStartNode::CheckSectionCondColl() const
962 {
963 //FEATURE::CONDCOLL
964 	SwNodeIndex aIdx( *this );
965 	sal_uLong nEndIdx = EndOfSectionIndex();
966 	const SwNodes& rNds = GetNodes();
967 	SwCntntNode* pCNd;
968 	while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx )
969 		pCNd->ChkCondColl();
970 //FEATURE::CONDCOLL
971 }
972 
973 /*******************************************************************
974 |*
975 |*	SwEndNode::SwEndNode
976 |*
977 |*	Beschreibung
978 |*		Konstruktor; dieser fuegt einen Node in das Array rNodes
979 |*		an der Position aWhere ein. Der
980 |*		theStartOfSection-Pointer wird entsprechend gesetzt,
981 |*		und der EndOfSection-Pointer des zugehoerigen
982 |*		Startnodes -- durch rStartOfSection bezeichnet --
983 |*		wird auf diesen Node gesetzt.
984 |*
985 |*	Parameter
986 |*		IN
987 |*		rNodes bezeichnet das variable Array, in das der Node
988 |*		eingefuegt werden soll
989 |*		IN
990 |*		aWhere bezeichnet die Position innerhalb dieses Arrays,
991 |*		an der der Node eingefuegt werden soll
992 |*		!!!!!!!!!!!!
993 |*		Es wird eine Kopie uebergeben!
994 |*
995 |*	Ersterstellung
996 |*		VER0100 vb 901214
997 |*
998 |*	Stand
999 |*		VER0100 vb 901214
1000 |*
1001 *******************************************************************/
1002 
1003 
1004 SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd )
1005 	: SwNode( rWhere, ND_ENDNODE )
1006 {
1007 	pStartOfSection = &rSttNd;
1008 	pStartOfSection->pEndOfSection = this;
1009 }
1010 
1011 SwEndNode::SwEndNode( SwNodes& rNds, sal_uLong nPos, SwStartNode& rSttNd )
1012 	: SwNode( rNds, nPos, ND_ENDNODE )
1013 {
1014 	pStartOfSection = &rSttNd;
1015 	pStartOfSection->pEndOfSection = this;
1016 }
1017 
1018 
1019 
1020 // --------------------
1021 // SwCntntNode
1022 // --------------------
1023 
1024 
1025 SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType,
1026 							SwFmtColl *pColl )
1027 	: SwModify( pColl ),	 // CrsrsShell, FrameFmt,
1028     SwNode( rWhere, nNdType ),
1029     pCondColl( 0 ),
1030     mbSetModifyAtAttr( false )
1031 #ifdef OLD_INDEX
1032 	,SwIndexReg(2)
1033 #endif
1034 {
1035 }
1036 
1037 
1038 SwCntntNode::~SwCntntNode()
1039 {
1040 	// Die Basisklasse SwClient vom SwFrm nimmt sich aus
1041 	// der Abhaengikeitsliste raus!
1042 	// Daher muessen alle Frames in der Abhaengigkeitsliste geloescht werden.
1043 	if( GetDepends() )
1044 		//IAccessibility2 Implementation 2009-----
1045 		DelFrms(sal_True, sal_False);
1046 		//-----IAccessibility2 Implementation 2009
1047 
1048     if( pCondColl )
1049 		delete pCondColl;
1050 
1051     if ( mpAttrSet.get() && mbSetModifyAtAttr )
1052         ((SwAttrSet*)mpAttrSet.get())->SetModifyAtAttr( 0 );
1053 }
1054 
1055 void SwCntntNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
1056 {
1057 	sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
1058 					pNewValue ? pNewValue->Which() : 0 ;
1059 
1060 	switch( nWhich )
1061 	{
1062 	case RES_OBJECTDYING :
1063 		{
1064 			SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject;
1065 
1066 			// nicht umhaengen wenn dieses das oberste Format ist !!
1067 			if( GetRegisteredIn() == pFmt )
1068 			{
1069 				if( pFmt->GetRegisteredIn() )
1070 				{
1071 					// wenn Parent, dann im neuen Parent wieder anmelden
1072 					((SwModify*)pFmt->GetRegisteredIn())->Add( this );
1073                     if ( GetpSwAttrSet() )
1074                         AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
1075 				}
1076 				else
1077 				{
1078 					// sonst auf jeden Fall beim sterbenden abmelden
1079 					((SwModify*)GetRegisteredIn())->Remove( this );
1080                     if ( GetpSwAttrSet() )
1081                         AttrSetHandleHelper::SetParent( mpAttrSet, *this, 0, 0 );
1082 				}
1083 			}
1084 		}
1085 		break;
1086 
1087 
1088 	case RES_FMT_CHG:
1089 		// falls mein Format Parent umgesetzt wird, dann melde ich
1090 		// meinen Attrset beim Neuen an.
1091 
1092 		// sein eigenes Modify ueberspringen !!
1093         if( GetpSwAttrSet() &&
1094 			((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() )
1095 		{
1096 			// den Set an den neuen Parent haengen
1097             AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
1098 		}
1099 		break;
1100 //FEATURE::CONDCOLL
1101 	case RES_CONDCOLL_CONDCHG:
1102 		if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() &&
1103 			&GetNodes() == &GetDoc()->GetNodes() )
1104 		{
1105 			ChkCondColl();
1106 		}
1107 		return ;	// nicht an die Basisklasse / Frames weitergeben
1108 //FEATURE::CONDCOLL
1109 
1110 	case RES_ATTRSET_CHG:
1111 		if( GetNodes().IsDocNodes() && IsTxtNode() )
1112 		{
1113             if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState(
1114                 RES_CHRATR_HIDDEN, sal_False ) )
1115             {
1116                 ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1117             }
1118 		}
1119 		break;
1120 
1121     case RES_UPDATE_ATTR:
1122 		if( GetNodes().IsDocNodes() && IsTxtNode() )
1123         {
1124             const sal_uInt16 nTmp = ((SwUpdateAttr*)pNewValue)->nWhichAttr;
1125             if ( RES_ATTRSET_CHG == nTmp )
1126             {
1127                 // anybody wants to do some optimization here?
1128                 ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1129             }
1130         }
1131         break;
1132 	}
1133 
1134 	NotifyClients( pOldValue, pNewValue );
1135 }
1136 
1137 sal_Bool SwCntntNode::InvalidateNumRule()
1138 {
1139 	SwNumRule* pRule = 0;
1140 	const SfxPoolItem* pItem;
1141 	if( GetNodes().IsDocNodes() &&
1142 		0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, sal_True )) &&
1143 		((SwNumRuleItem*)pItem)->GetValue().Len() &&
1144 		0 != (pRule = GetDoc()->FindNumRulePtr(
1145 								((SwNumRuleItem*)pItem)->GetValue() ) ) )
1146 	{
1147 		pRule->SetInvalidRule( sal_True );
1148 	}
1149 	return 0 != pRule;
1150 }
1151 
1152 SwCntntFrm *SwCntntNode::getLayoutFrm( const SwRootFrm* _pRoot,
1153     const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm ) const
1154 {
1155 	return (SwCntntFrm*) ::GetFrmOfModify( _pRoot, *(SwModify*)this, FRM_CNTNT,
1156 											pPoint, pPos, bCalcFrm );
1157 }
1158 
1159 SwRect SwCntntNode::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint,
1160 									const sal_Bool bCalcFrm ) const
1161 {
1162 	SwRect aRet;
1163 	SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( 0, *(SwModify*)this,
1164 											FRM_CNTNT, pPoint, 0, bCalcFrm );
1165 	if( pFrm )
1166 		aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1167 	return aRet;
1168 }
1169 
1170 SwRect SwCntntNode::FindPageFrmRect( const sal_Bool bPrtArea, const Point* pPoint,
1171 									const sal_Bool bCalcFrm ) const
1172 {
1173 	SwRect aRet;
1174 	SwFrm* pFrm = ::GetFrmOfModify( 0, *(SwModify*)this,
1175 											FRM_CNTNT, pPoint, 0, bCalcFrm );
1176 	if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() ))
1177 		aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1178 	return aRet;
1179 }
1180 
1181 xub_StrLen SwCntntNode::Len() const { return 0; }
1182 
1183 
1184 
1185 SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl )
1186 {
1187 	ASSERT( pNewColl, "Collectionpointer ist 0." );
1188 	SwFmtColl *pOldColl = GetFmtColl();
1189 
1190 	if( pNewColl != pOldColl )
1191 	{
1192 		pNewColl->Add( this );
1193 
1194 		// setze den Parent von unseren Auto-Attributen auf die neue
1195 		// Collection:
1196         if( GetpSwAttrSet() )
1197             AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl );
1198 
1199 //FEATURE::CONDCOLL
1200 		// HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen
1201 		//		neu ueberprueft werden!
1202 		if( sal_True /*pNewColl */ )
1203 		{
1204 			SetCondFmtColl( 0 );
1205 		}
1206 //FEATURE::CONDCOLL
1207 
1208 		if( !IsModifyLocked() )
1209 		{
1210 			SwFmtChg aTmp1( pOldColl );
1211 			SwFmtChg aTmp2( pNewColl );
1212             SwCntntNode::Modify( &aTmp1, &aTmp2 );
1213 		}
1214 	}
1215 	if ( IsInCache() )
1216 	{
1217 		SwFrm::GetCache().Delete( this );
1218 		SetInCache( sal_False );
1219 	}
1220 	return pOldColl;
1221 }
1222 
1223 
1224 sal_Bool SwCntntNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const
1225 {
1226 	sal_Bool bRet = sal_True;
1227 	if( pIdx->GetIndex() < Len() )
1228 	{
1229 		if( !IsTxtNode() )
1230 			(*pIdx)++;
1231 		else
1232 		{
1233 			const SwTxtNode& rTNd = *GetTxtNode();
1234 			xub_StrLen nPos = pIdx->GetIndex();
1235 			if( pBreakIt->GetBreakIter().is() )
1236 			{
1237 				sal_Int32 nDone = 0;
1238 				sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1239                                         CharacterIteratorMode::SKIPCELL :
1240                                         CharacterIteratorMode::SKIPCONTROLCHARACTER;
1241                 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetTxt(), nPos,
1242                                    pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1243                                    nItrMode, 1, nDone );
1244 
1245                 // Check if nPos is inside hidden text range:
1246                 if ( CRSR_SKIP_HIDDEN & nMode )
1247                 {
1248                     xub_StrLen nHiddenStart;
1249                     xub_StrLen nHiddenEnd;
1250                     SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1251                     if ( nHiddenStart != STRING_LEN && nHiddenStart != nPos )
1252                          nPos = nHiddenEnd;
1253                 }
1254 
1255 				if( 1 == nDone )
1256 					*pIdx = nPos;
1257 				else
1258 					bRet = sal_False;
1259 			}
1260 			else if( nPos < rTNd.GetTxt().Len() )
1261 				(*pIdx)++;
1262 			else
1263 				bRet = sal_False;
1264 		}
1265 	}
1266 	else
1267 		bRet = sal_False;
1268 	return bRet;
1269 }
1270 
1271 
1272 sal_Bool SwCntntNode::GoPrevious(SwIndex * pIdx, sal_uInt16 nMode ) const
1273 {
1274 	sal_Bool bRet = sal_True;
1275 	if( pIdx->GetIndex() > 0 )
1276 	{
1277 		if( !IsTxtNode() )
1278 			(*pIdx)--;
1279 		else
1280 		{
1281 			const SwTxtNode& rTNd = *GetTxtNode();
1282 			xub_StrLen nPos = pIdx->GetIndex();
1283 			if( pBreakIt->GetBreakIter().is() )
1284 			{
1285 				sal_Int32 nDone = 0;
1286 				sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1287                                         CharacterIteratorMode::SKIPCELL :
1288                                         CharacterIteratorMode::SKIPCONTROLCHARACTER;
1289                 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetTxt(), nPos,
1290                                    pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1291                                    nItrMode, 1, nDone );
1292 
1293                 // Check if nPos is inside hidden text range:
1294                 if ( CRSR_SKIP_HIDDEN & nMode )
1295                 {
1296                     xub_StrLen nHiddenStart;
1297                     xub_StrLen nHiddenEnd;
1298                     SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1299                     if ( nHiddenStart != STRING_LEN  )
1300                          nPos = nHiddenStart;
1301                 }
1302 
1303 				if( 1 == nDone )
1304 					*pIdx = nPos;
1305 				else
1306 					bRet = sal_False;
1307 			}
1308 			else if( nPos )
1309 				(*pIdx)--;
1310 			else
1311 				bRet = sal_False;
1312 		}
1313 	}
1314 	else
1315 		bRet = sal_False;
1316 	return bRet;
1317 }
1318 
1319 
1320 /*
1321  * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
1322  * Dokument. Die erzeugten Contentframes werden in das entsprechende
1323  * Layout gehaengt.
1324  */
1325 
1326 
1327 void SwCntntNode::MakeFrms( SwCntntNode& rNode )
1328 {
1329 	ASSERT( &rNode != this,
1330 			"Kein Contentnode oder Copy-Node und neuer Node identisch." );
1331 
1332 	if( !GetDepends() || &rNode == this )	// gibt es ueberhaupt Frames ??
1333 		return;
1334 
1335 	SwFrm *pFrm, *pNew;
1336 	SwLayoutFrm *pUpper;
1337 	// Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ??
1338 	ASSERT( FindTableNode() == rNode.FindTableNode(), "Table confusion" )
1339 
1340 	SwNode2Layout aNode2Layout( *this, rNode.GetIndex() );
1341 
1342 	while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) )
1343 	{
1344 		pNew = rNode.MakeFrm( pUpper );
1345 		pNew->Paste( pUpper, pFrm );
1346         // --> OD 2005-12-01 #i27138#
1347         // notify accessibility paragraphs objects about changed
1348         // CONTENT_FLOWS_FROM/_TO relation.
1349         // Relation CONTENT_FLOWS_FROM for next paragraph will change
1350         // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1351         if ( pNew->IsTxtFrm() )
1352         {
1353             ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
1354             if ( pViewShell && pViewShell->GetLayout() &&
1355                  pViewShell->GetLayout()->IsAnyShellAccessible() )
1356             {
1357                 pViewShell->InvalidateAccessibleParaFlowRelation(
1358                             dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
1359                             dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) );
1360             }
1361         }
1362         // <--
1363     }
1364 }
1365 
1366 /*
1367  * Methode loescht fuer den Node alle Ansichten vom
1368  * Dokument. Die Contentframes werden aus dem entsprechenden
1369  * Layout ausgehaengt.
1370  */
1371 
1372 
1373 //IAccessibility2 Implementation 2009-----
1374 //Solution:Add a input param to identify if the acc table should be disposed.
1375 //add a flag(bNeedDel) to indicate whether to del corresponding frm even in doc loading process,
1376 //void SwCntntNode::DelFrms()
1377 void SwCntntNode::DelFrms( sal_Bool /* bNeedDel */, sal_Bool bIsDisposeAccTable )
1378 //-----IAccessibility2 Implementation 2009
1379 {
1380 	if( !GetDepends() )
1381 		return;
1382 
1383 	SwClientIter aIter( *this );
1384 	SwCntntFrm *pFrm;
1385 
1386 	for( pFrm = (SwCntntFrm*)aIter.First( TYPE(SwCntntFrm)); pFrm;
1387 		 pFrm = (SwCntntFrm*)aIter.Next() )
1388 	{
1389         // --> OD 2005-12-01 #i27138#
1390         // notify accessibility paragraphs objects about changed
1391         // CONTENT_FLOWS_FROM/_TO relation.
1392         // Relation CONTENT_FLOWS_FROM for current next paragraph will change
1393         // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
1394         if ( pFrm->IsTxtFrm() )
1395         {
1396             ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1397             if ( pViewShell && pViewShell->GetLayout() &&
1398                  pViewShell->GetLayout()->IsAnyShellAccessible() )
1399             {
1400                 pViewShell->InvalidateAccessibleParaFlowRelation(
1401                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1402                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1403             }
1404         }
1405         // <--
1406         if( pFrm->HasFollow() )
1407             pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() );
1408         if( pFrm->IsFollow() )
1409         {
1410             SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster();
1411             pMaster->SetFollow( pFrm->GetFollow() );
1412             pFrm->_SetIsFollow( sal_False );
1413         }
1414 		pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt.
1415 								//Andernfalls kann es sein, dass ein Follow
1416 								//vor seinem Master zerstoert wird, der Master
1417 								//greift dann ueber den ungueltigen
1418 								//Follow-Pointer auf fremdes Memory zu.
1419 								//Die Kette darf hier zerknauscht werden, weil
1420 								//sowieso alle zerstoert werden.
1421 		if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() &&
1422 			!pFrm->GetIndPrev() )
1423 		{
1424 			SwFtnFrm *pFtn = pFrm->FindFtnFrm();
1425 			ASSERT( pFtn, "You promised a FtnFrm?" );
1426 			SwCntntFrm* pCFrm;
1427 			if( !pFtn->GetFollow() && !pFtn->GetMaster() &&
1428 				0 != ( pCFrm = pFtn->GetRefFromAttr()) && pCFrm->IsFollow() )
1429 			{
1430 				ASSERT( pCFrm->IsTxtFrm(), "NoTxtFrm has Footnote?" );
1431 				((SwTxtFrm*)pCFrm->FindMaster())->Prepare( PREP_FTN_GONE );
1432 			}
1433 		}
1434 		//IAccessibility2 Implementation 2009-----
1435 		//Solution:Set acc table dispose state
1436 		pFrm->SetAccTableDispose( bIsDisposeAccTable );
1437 		//End Added
1438 		pFrm->Cut();
1439 		//Solution:Set acc table dispose state to default value
1440 		pFrm->SetAccTableDispose( sal_True );
1441 		//-----IAccessibility2 Implementation 2009
1442 		delete pFrm;
1443 	}
1444 	if( IsTxtNode() )
1445 	{
1446         ((SwTxtNode*)this)->SetWrong( NULL );
1447         ((SwTxtNode*)this)->SetWrongDirty( true );
1448 
1449         ((SwTxtNode*)this)->SetGrammarCheck( NULL );
1450         ((SwTxtNode*)this)->SetGrammarCheckDirty( true );
1451         // SMARTTAGS
1452         ((SwTxtNode*)this)->SetSmartTags( NULL );
1453         ((SwTxtNode*)this)->SetSmartTagDirty( true );
1454 
1455         ((SwTxtNode*)this)->SetWordCountDirty( true );
1456         ((SwTxtNode*)this)->SetAutoCompleteWordDirty( true );
1457 	}
1458 }
1459 
1460 
1461 SwCntntNode *SwCntntNode::JoinNext()
1462 {
1463 	return this;
1464 }
1465 
1466 
1467 SwCntntNode *SwCntntNode::JoinPrev()
1468 {
1469 	return this;
1470 }
1471 
1472 
1473 
1474 	// erfrage vom Modify Informationen
1475 sal_Bool SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const
1476 {
1477 	switch( rInfo.Which() )
1478 	{
1479 	case RES_AUTOFMT_DOCNODE:
1480 		if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
1481 		{
1482 			((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this;
1483 			return sal_False;
1484 		}
1485 		break;
1486     // --> OD 2008-02-19 #refactorlists#
1487 //    case RES_GETNUMNODES:
1488 //        // #111955# only numbered nodes in rInfo
1489 //        if( IsTxtNode())
1490 //        {
1491 //            SwTxtNode * pTxtNode = (SwTxtNode*)this;
1492 //            pItem = (SwNumRuleItem*)GetNoCondAttr(RES_PARATR_NUMRULE, sal_True );
1493 
1494 //            if (0 != pItem  &&
1495 //                pItem->GetValue().Len() &&
1496 //                pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() &&
1497 //                GetNodes().IsDocNodes())
1498 //            {
1499 //                ((SwNumRuleInfo&)rInfo).AddNode( *pTxtNode );
1500 //            }
1501 //        }
1502 
1503 //        return sal_True;
1504     // <--
1505 
1506 	case RES_FINDNEARESTNODE:
1507         if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() )
1508 			((SwFindNearestNode&)rInfo).CheckNode( *this );
1509 		return sal_True;
1510 
1511 	case RES_CONTENT_VISIBLE:
1512 		{
1513 			((SwPtrMsgPoolItem&)rInfo).pObject =
1514 				SwIterator<SwFrm,SwCntntNode>::FirstElement(*this);
1515 		}
1516 		return sal_False;
1517 	}
1518 
1519 	return SwModify::GetInfo( rInfo );
1520 }
1521 
1522 
1523 	// setze ein Attribut
1524 sal_Bool SwCntntNode::SetAttr(const SfxPoolItem& rAttr )
1525 {
1526     if( !GetpSwAttrSet() )            // lasse von den entsprechenden Nodes die
1527 		NewAttrSet( GetDoc()->GetAttrPool() );		// AttrSets anlegen
1528 
1529     ASSERT( GetpSwAttrSet(), "warum wurde kein AttrSet angelegt?" );
1530 
1531     if ( IsInCache() )
1532 	{
1533 		SwFrm::GetCache().Delete( this );
1534 		SetInCache( sal_False );
1535 	}
1536 
1537 	sal_Bool bRet = sal_False;
1538 	// wenn Modify gelockt ist, werden keine Modifies verschickt
1539 	if( IsModifyLocked() ||
1540 		( !GetDepends() &&  RES_PARATR_NUMRULE != rAttr.Which() ))
1541 	{
1542         bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr );
1543 	}
1544 	else
1545 	{
1546         SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1547                   aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1548         if( 0 != ( bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ) ))
1549 		{
1550             SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1551             SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1552 			ModifyNotification( &aChgOld, &aChgNew );		// alle veraenderten werden verschickt
1553 		}
1554 	}
1555 	return bRet;
1556 }
1557 #include <svl/itemiter.hxx>
1558 
1559 sal_Bool SwCntntNode::SetAttr( const SfxItemSet& rSet )
1560 {
1561     if ( IsInCache() )
1562 	{
1563 		SwFrm::GetCache().Delete( this );
1564 		SetInCache( sal_False );
1565 	}
1566 
1567     const SfxPoolItem* pFnd = 0;
1568     if( SFX_ITEM_SET == rSet.GetItemState( RES_AUTO_STYLE, sal_False, &pFnd ) )
1569     {
1570         ASSERT( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" );
1571         const SwFmtAutoFmt* pTmp = static_cast<const SwFmtAutoFmt*>(pFnd);
1572 
1573         // If there already is an attribute set (usually containing a numbering
1574         // item), we have to merge the attribute of the new set into the old set:
1575         bool bSetParent = true;
1576         if ( GetpSwAttrSet() )
1577         {
1578             bSetParent = false;
1579             AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() );
1580         }
1581         else
1582         {
1583             mpAttrSet = pTmp->GetStyleHandle();
1584         }
1585 
1586         if ( bSetParent )
1587         {
1588             // If the content node has a conditional style, we have to set the
1589             // string item containing the correct conditional style name (the
1590             // style name property has already been set during the import!)
1591             // In case we do not have a conditional style, we make use of the
1592             // fact that nobody else uses the attribute set behind the handle.
1593             // FME 2007-07-10 #i78124# If autostyle does not have a parent,
1594             // the string is empty.
1595             const SfxPoolItem* pNameItem = 0;
1596             if ( 0 != GetCondFmtColl() ||
1597                  SFX_ITEM_SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, sal_False, &pNameItem ) ||
1598                  0 == static_cast<const SfxStringItem*>(pNameItem)->GetValue().Len() )
1599                 AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1600             else
1601                 const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFmtColl()->GetAttrSet() );
1602         }
1603 
1604         return sal_True;
1605     }
1606 
1607     if( !GetpSwAttrSet() )            // lasse von den entsprechenden Nodes die
1608 		NewAttrSet( GetDoc()->GetAttrPool() );		// AttrSets anlegen
1609 
1610     sal_Bool bRet = sal_False;
1611 	// wenn Modify gelockt ist, werden keine Modifies verschickt
1612     if ( IsModifyLocked() ||
1613          ( !GetDepends() &&
1614            SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, sal_False ) ) )
1615 	{
1616 		// einige Sonderbehandlungen fuer Attribute
1617         bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rSet );
1618 	}
1619 	else
1620 	{
1621         SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1622                   aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1623         if( 0 != (bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew )) )
1624 		{
1625 			// einige Sonderbehandlungen fuer Attribute
1626             SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1627             SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1628 			ModifyNotification( &aChgOld, &aChgNew );		// alle veraenderten werden verschickt
1629 		}
1630 	}
1631 	return bRet;
1632 }
1633 
1634 // Nimmt den Hint mit nWhich aus dem Delta-Array
1635 
1636 
1637 sal_Bool SwCntntNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
1638 {
1639     if( !GetpSwAttrSet() )
1640 		return sal_False;
1641 
1642     if ( IsInCache() )
1643 	{
1644 		SwFrm::GetCache().Delete( this );
1645 		SetInCache( sal_False );
1646 	}
1647 
1648 	// wenn Modify gelockt ist, werden keine Modifies verschickt
1649 	if( IsModifyLocked() )
1650 	{
1651         sal_uInt16 nDel = 0;
1652         if ( !nWhich2 || nWhich2 < nWhich1 )
1653         {
1654             std::vector<sal_uInt16> aClearWhichIds;
1655             aClearWhichIds.push_back( nWhich1 );
1656             nDel = ClearItemsFromAttrSet( aClearWhichIds );
1657         }
1658         else
1659             nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, 0, 0 );
1660 
1661         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1662             mpAttrSet.reset();//DELETEZ( mpAttrSet );
1663 		return 0 != nDel;
1664 	}
1665 
1666 	// sollte kein gueltiger Bereich definiert sein ?
1667 	if( !nWhich2 || nWhich2 < nWhich1 )
1668 		nWhich2 = nWhich1;		// dann setze auf 1. Id, nur dieses Item
1669 
1670     SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1671               aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1672     sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew );
1673 
1674 	if( bRet )
1675 	{
1676         SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1677         SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1678 		ModifyNotification( &aChgOld, &aChgNew );		// alle veraenderten werden verschickt
1679 
1680         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1681             mpAttrSet.reset();//DELETEZ( mpAttrSet );
1682 	}
1683 	return bRet;
1684 }
1685 sal_Bool SwCntntNode::ResetAttr( const SvUShorts& rWhichArr )
1686 {
1687     if( !GetpSwAttrSet() )
1688 		return sal_False;
1689 
1690     if ( IsInCache() )
1691 	{
1692 		SwFrm::GetCache().Delete( this );
1693 		SetInCache( sal_False );
1694 	}
1695 
1696 	// wenn Modify gelockt ist, werden keine Modifies verschickt
1697 	sal_uInt16 nDel = 0;
1698 	if( IsModifyLocked() )
1699 	{
1700         std::vector<sal_uInt16> aClearWhichIds;
1701 		for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
1702             aClearWhichIds.push_back( rWhichArr[ n ] );
1703 
1704         nDel = ClearItemsFromAttrSet( aClearWhichIds );
1705     }
1706 	else
1707 	{
1708         SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1709                   aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1710 
1711 		for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
1712             if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, rWhichArr[ n ], &aOld, &aNew ))
1713 				++nDel;
1714 
1715 		if( nDel )
1716 		{
1717             SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1718             SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1719 			ModifyNotification( &aChgOld, &aChgNew );		// alle veraenderten werden verschickt
1720 		}
1721 	}
1722     if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1723         mpAttrSet.reset();//DELETEZ( mpAttrSet );
1724 	return 0 != nDel ;
1725 }
1726 
1727 
1728 sal_uInt16 SwCntntNode::ResetAllAttr()
1729 {
1730     if( !GetpSwAttrSet() )
1731 		return 0;
1732 
1733     if ( IsInCache() )
1734 	{
1735 		SwFrm::GetCache().Delete( this );
1736 		SetInCache( sal_False );
1737 	}
1738 
1739 	// wenn Modify gelockt ist, werden keine Modifies verschickt
1740 	if( IsModifyLocked() )
1741 	{
1742         std::vector<sal_uInt16> aClearWhichIds;
1743         aClearWhichIds.push_back(0);
1744         sal_uInt16 nDel = ClearItemsFromAttrSet( aClearWhichIds );
1745         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1746             mpAttrSet.reset();            // DELETEZ( mpAttrSet );
1747 		return nDel;
1748 	}
1749 
1750     SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1751               aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1752     sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew );
1753 
1754 	if( bRet )
1755 	{
1756         SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1757         SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1758 		ModifyNotification( &aChgOld, &aChgNew );		// alle veraenderten werden verschickt
1759 
1760         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1761             mpAttrSet.reset();//DELETEZ( mpAttrSet );
1762 	}
1763 	return aNew.Count();
1764 }
1765 
1766 
1767 sal_Bool SwCntntNode::GetAttr( SfxItemSet& rSet, sal_Bool bInParent ) const
1768 {
1769 	if( rSet.Count() )
1770 		rSet.ClearItem();
1771 
1772 	const SwAttrSet& rAttrSet = GetSwAttrSet();
1773 	if( bInParent )
1774 		return rSet.Set( rAttrSet, sal_True ) ? sal_True : sal_False;
1775 
1776 	rSet.Put( rAttrSet );
1777 	return rSet.Count() ? sal_True : sal_False;
1778 }
1779 
1780 sal_uInt16 SwCntntNode::ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds )
1781 {
1782     sal_uInt16 nRet = 0;
1783     if ( 0 == rWhichIds.size() )
1784         return nRet;
1785 
1786     ASSERT( GetpSwAttrSet(), "no item set" )
1787     SwAttrSet aNewAttrSet( *GetpSwAttrSet() );
1788     for ( std::vector<sal_uInt16>::const_iterator aIter = rWhichIds.begin();
1789           aIter != rWhichIds.end();
1790           ++aIter )
1791     {
1792         nRet = nRet + aNewAttrSet.ClearItem( *aIter );
1793     }
1794     if ( nRet )
1795         AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet );
1796 
1797     return nRet;
1798 }
1799 
1800 const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich,
1801 												sal_Bool bInParents ) const
1802 {
1803 	const SfxPoolItem* pFnd = 0;
1804 	if( pCondColl && pCondColl->GetRegisteredIn() )
1805 	{
1806         if( !GetpSwAttrSet() || ( SFX_ITEM_SET != GetpSwAttrSet()->GetItemState(
1807 					nWhich, sal_False, &pFnd ) && bInParents ))
1808 			((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd );
1809 	}
1810     // --> OD 2005-10-25 #126347# - undo change of issue #i51029#
1811     // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns
1812     //       the attribute set of the paragraph style, which is valid for the
1813     //       content node - see file <node.hxx>
1814     else
1815     // <--
1816     {
1817 		GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd );
1818     }
1819 	return pFnd;
1820 }
1821 
1822 	// koennen 2 Nodes zusammengefasst werden ?
1823 	// in pIdx kann die 2. Position returnt werden.
1824 int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
1825 {
1826 	const SwNodes& rNds = GetNodes();
1827 	sal_uInt8 nNdType = GetNodeType();
1828 	SwNodeIndex aIdx( *this, 1 );
1829 
1830 	const SwNode* pNd = this;
1831 	while( aIdx < rNds.Count()-1 &&
1832 		(( pNd = &aIdx.GetNode())->IsSectionNode() ||
1833             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1834 		aIdx++;
1835 
1836 	if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
1837 		return sal_False;
1838     if( IsTxtNode() )
1839     {   // Do not merge strings if the result exceeds the allowed string length
1840         const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this);
1841         sal_uInt64 nSum = pTxtNd->GetTxt().Len();
1842         pTxtNd = static_cast<const SwTxtNode*>(pNd);
1843         nSum += pTxtNd->GetTxt().Len();
1844         if( nSum > STRING_LEN )
1845             return sal_False;
1846     }
1847 	if( pIdx )
1848 		*pIdx = aIdx;
1849 	return sal_True;
1850 }
1851 
1852 
1853 	// koennen 2 Nodes zusammengefasst werden ?
1854 	// in pIdx kann die 2. Position returnt werden.
1855 int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
1856 {
1857     sal_uInt8 nNdType = GetNodeType();
1858 	SwNodeIndex aIdx( *this, -1 );
1859 
1860 	const SwNode* pNd = this;
1861 	while( aIdx.GetIndex() &&
1862 		(( pNd = &aIdx.GetNode())->IsSectionNode() ||
1863             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1864 		aIdx--;
1865 
1866 	if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
1867 		return sal_False;
1868 	if( pIdx )
1869 		*pIdx = aIdx;
1870 	return sal_True;
1871 }
1872 
1873 
1874 //FEATURE::CONDCOLL
1875 
1876 
1877 void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl )
1878 {
1879 	if( (!pColl && pCondColl) || ( pColl && !pCondColl ) ||
1880 		( pColl && pColl != pCondColl->GetRegisteredIn() ) )
1881 	{
1882 		SwFmtColl* pOldColl = GetCondFmtColl();
1883 		delete pCondColl;
1884 		if( pColl )
1885 			pCondColl = new SwDepend( this, pColl );
1886 		else
1887 			pCondColl = 0;
1888 
1889         if( GetpSwAttrSet() )
1890 		{
1891             AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1892 		}
1893 
1894 		if( !IsModifyLocked() )
1895 		{
1896 			SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() );
1897 			SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() );
1898 			NotifyClients( &aTmp1, &aTmp2 );
1899 		}
1900 		if( IsInCache() )
1901 		{
1902 			SwFrm::GetCache().Delete( this );
1903 			SetInCache( sal_False );
1904 		}
1905 	}
1906 }
1907 
1908 
1909 sal_Bool SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const
1910 {
1911 	const SwNodes& rNds = GetNodes();
1912 	{
1913 		int nCond = 0;
1914         const SwStartNode* pSttNd = StartOfSectionNode();
1915 		while( pSttNd )
1916 		{
1917 			switch( pSttNd->GetNodeType() )
1918 			{
1919 			case ND_TABLENODE:		nCond = PARA_IN_TABLEBODY; break;
1920 			case ND_SECTIONNODE: 	nCond = PARA_IN_SECTION; break;
1921 
1922 			default:
1923 				switch( pSttNd->GetStartNodeType() )
1924 				{
1925 				case SwTableBoxStartNode:
1926 					{
1927 						nCond = PARA_IN_TABLEBODY;
1928 						const SwTableNode* pTblNd = pSttNd->FindTableNode();
1929 						const SwTableBox* pBox;
1930 						if( pTblNd && 0 != ( pBox = pTblNd->GetTable().
1931 							GetTblBox( pSttNd->GetIndex() ) ) && pBox &&
1932 							pBox->IsInHeadline( &pTblNd->GetTable() ) )
1933 							nCond = PARA_IN_TABLEHEAD;
1934 					}
1935 					break;
1936 				case SwFlyStartNode:		nCond = PARA_IN_FRAME; break;
1937 				case SwFootnoteStartNode:
1938 					{
1939 						nCond = PARA_IN_FOOTENOTE;
1940 						const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs();
1941 						const SwTxtFtn* pTxtFtn;
1942 						const SwNode* pSrchNd = pSttNd;
1943 
1944 						for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n )
1945 							if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
1946 								pSrchNd == &pTxtFtn->GetStartNode()->GetNode() )
1947 							{
1948 								if( pTxtFtn->GetFtn().IsEndNote() )
1949 									nCond = PARA_IN_ENDNOTE;
1950 								break;
1951 							}
1952 					}
1953 					break;
1954 				case SwHeaderStartNode:     nCond = PARA_IN_HEADER; break;
1955 				case SwFooterStartNode:     nCond = PARA_IN_FOOTER; break;
1956 				case SwNormalStartNode:     break;
1957 				}
1958 			}
1959 
1960 			if( nCond )
1961 			{
1962 				rTmp.SetCondition( (Master_CollConditions)nCond, 0 );
1963 				return sal_True;
1964 			}
1965 			pSttNd = pSttNd->GetIndex()
1966                         ? pSttNd->StartOfSectionNode()
1967 						: 0;
1968 		}
1969 	}
1970 
1971 	{
1972 		sal_uInt16 nPos;
1973 		const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1974 		if( rOutlNds.Count() )
1975 		{
1976 			if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos )
1977 				--nPos;
1978 			if( nPos < rOutlNds.Count() &&
1979 				rOutlNds[ nPos ]->GetIndex() < GetIndex() )
1980 			{
1981 				SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode();
1982 
1983 				if( pOutlNd->IsOutline())
1984 				{
1985                     rTmp.SetCondition( PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 );
1986 					return sal_True;
1987 				}
1988 			}
1989 		}
1990 	}
1991 
1992 	return sal_False;
1993 }
1994 
1995 
1996 void SwCntntNode::ChkCondColl()
1997 {
1998 	// zur Sicherheit abfragen
1999 	if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() )
2000 	{
2001 		SwCollCondition aTmp( 0, 0, 0 );
2002 		const SwCollCondition* pCColl;
2003 
2004         bool bDone = false;
2005 
2006 		if( IsAnyCondition( aTmp ))
2007         {
2008             pCColl = static_cast<SwConditionTxtFmtColl*>(GetFmtColl())
2009                 ->HasCondition( aTmp );
2010 
2011             if (pCColl)
2012             {
2013                 SetCondFmtColl( pCColl->GetTxtFmtColl() );
2014                 bDone = true;
2015             }
2016         }
2017 
2018 		if (!bDone)
2019 		{
2020             if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule())
2021 			{
2022 				// steht in einer Numerierung
2023 				// welcher Level?
2024 				aTmp.SetCondition( PARA_IN_LIST,
2025                                 ((SwTxtNode*)this)->GetActualListLevel() );
2026 				pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())->
2027 								HasCondition( aTmp );
2028 			}
2029 			else
2030 				pCColl = 0;
2031 
2032 			if( pCColl )
2033 				SetCondFmtColl( pCColl->GetTxtFmtColl() );
2034 			else if( pCondColl )
2035 				SetCondFmtColl( 0 );
2036 		}
2037 	}
2038 }
2039 
2040 // --> OD 2005-02-21 #i42921#
2041 short SwCntntNode::GetTextDirection( const SwPosition& rPos,
2042                                      const Point* pPt ) const
2043 {
2044     short nRet = -1;
2045 
2046     Point aPt;
2047     if( pPt )
2048         aPt = *pPt;
2049 
2050     // --> OD 2007-01-10 #i72024#
2051     // No format of the frame, because this can cause recursive layout actions
2052     SwFrm* pFrm = getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, &rPos, sal_False );
2053     // <--
2054 
2055     if ( pFrm )
2056     {
2057         if ( pFrm->IsVertical() )
2058         {
2059             if ( pFrm->IsRightToLeft() )
2060                 nRet = FRMDIR_VERT_TOP_LEFT;
2061             else
2062                 nRet = FRMDIR_VERT_TOP_RIGHT;
2063         }
2064         else
2065         {
2066             if ( pFrm->IsRightToLeft() )
2067                 nRet = FRMDIR_HORI_RIGHT_TOP;
2068             else
2069                 nRet = FRMDIR_HORI_LEFT_TOP;
2070         }
2071     }
2072 
2073 
2074     return nRet;
2075 }
2076 // <--
2077 
2078 SwOLENodes* SwCntntNode::CreateOLENodesArray( const SwFmtColl& rColl, bool bOnlyWithInvalidSize )
2079 {
2080     SwOLENodes *pNodes = 0;
2081     SwIterator<SwCntntNode,SwFmtColl> aIter( rColl );
2082     for( SwCntntNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
2083     {
2084         SwOLENode *pONd = pNd->GetOLENode();
2085         if ( pONd && (!bOnlyWithInvalidSize || pONd->IsOLESizeInvalid()) )
2086         {
2087             if ( !pNodes  )
2088                 pNodes = new SwOLENodes;
2089             pNodes->Insert( pONd, pNodes->Count() );
2090         }
2091     }
2092 
2093     return pNodes;
2094 }
2095 
2096 //FEATURE::CONDCOLL
2097 // Metoden aus Node.hxx - erst hier ist der TxtNode bekannt !!
2098 // os: nur fuer ICC, da der zum optimieren zu dumm ist
2099 #ifdef ICC
2100 SwTxtNode   *SwNode::GetTxtNode()
2101 {
2102 	 return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0;
2103 }
2104 const SwTxtNode   *SwNode::GetTxtNode() const
2105 {
2106 	 return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0;
2107 }
2108 #endif
2109 
2110 /*
2111  * Document Interface Access
2112  */
2113 const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return GetDoc(); }
2114 const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return GetDoc(); }
2115 const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc()->getIDocumentMarkAccess(); }
2116 const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return GetDoc(); }
2117 const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); }
2118 const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); }
2119 const IDocumentDrawModelAccess* SwNode::getIDocumentDrawModelAccess() const { return GetDoc(); }
2120 const IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() const { return GetDoc(); }
2121 IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() { return GetDoc(); }
2122 const IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() const { return GetDoc(); }
2123 IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() { return GetDoc(); }
2124 const IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() const { return GetDoc(); }
2125 IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() { return GetDoc(); }
2126 IDocumentContentOperations* SwNode::getIDocumentContentOperations() { return GetDoc(); }
2127 IStyleAccess& SwNode::getIDocumentStyleAccess() { return GetDoc()->GetIStyleAccess(); }
2128 // --> OD 2007-10-31 #i83479#
2129 IDocumentListItems& SwNode::getIDocumentListItems()
2130 {
2131     return *GetDoc();
2132 }
2133 // <--
2134 
2135 sal_Bool SwNode::IsInRedlines() const
2136 {
2137     const SwDoc * pDoc = GetDoc();
2138     sal_Bool bResult = sal_False;
2139 
2140     if (pDoc != NULL)
2141         bResult = pDoc->IsInRedlines(*this);
2142 
2143     return bResult;
2144 }
2145