Update ooo320-m1
[ooovba.git] / sw / source / core / docnode / node.cxx
blob69a6f68d90386b45fe321109d24d30af24f4d9d8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: node.cxx,v $
10 * $Revision: 1.45 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
37 // --> OD 2005-02-21 #i42921#
38 #include <svx/frmdiritem.hxx>
39 // <--
40 #include <svx/protitem.hxx>
41 #ifndef _COM_SUN_STAR_I18N_CHARACTERITERATORMODE_HDL_
42 #include <com/sun/star/i18n/CharacterIteratorMode.hdl>
43 #endif
44 #include <fmtcntnt.hxx>
45 #include <fmtanchr.hxx>
46 #include <frmfmt.hxx>
47 #include <txtftn.hxx>
48 #include <ftnfrm.hxx>
49 #include <doc.hxx>
50 #include <docary.hxx>
51 #include <node.hxx>
52 #include <ndindex.hxx>
53 #include <numrule.hxx>
54 #include <swtable.hxx>
55 #include <ndtxt.hxx>
56 #include <pam.hxx>
57 #include <swcache.hxx>
58 #include <section.hxx>
59 #include <cntfrm.hxx>
60 #include <flyfrm.hxx>
61 #include <txtfrm.hxx>
62 #include <tabfrm.hxx> // SwTabFrm
63 #include <viewsh.hxx>
64 #include <paratr.hxx>
65 #include <ftnidx.hxx>
66 #include <fmtftn.hxx>
67 #include <fmthdft.hxx>
68 #include <frmatr.hxx>
69 #include <fmtautofmt.hxx>
70 #include <frmtool.hxx>
71 #include <pagefrm.hxx>
72 #include <node2lay.hxx>
73 #include <pagedesc.hxx>
74 #include <fmtpdsc.hxx>
75 #include <breakit.hxx>
76 #include <crsskip.hxx>
77 #include <SwStyleNameMapper.hxx>
78 #include <scriptinfo.hxx>
79 // --> OD 2005-12-05 #i27138#
80 #include <rootfrm.hxx>
81 // <--
82 #include <istyleaccess.hxx>
83 // --> OD 2007-10-31 #i83479#
84 #include <IDocumentListItems.hxx>
85 // <--
87 using namespace ::com::sun::star::i18n;
89 TYPEINIT2( SwCntntNode, SwModify, SwIndexReg )
92 * Some local helper functions for the attribute set handle of a content node.
93 * Since the attribute set of a content node may not be modified directly,
94 * we always have to create a new SwAttrSet, do the modifications, and get
95 * a new handle from the style access
98 namespace AttrSetHandleHelper
101 void GetNewAutoStyle( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
102 const SwCntntNode& rNode,
103 SwAttrSet& rNewAttrSet )
105 const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get());
106 if( rNode.GetModifyAtAttr() )
107 const_cast<SwAttrSet*>(pAttrSet)->SetModifyAtAttr( 0 );
108 IStyleAccess& rSA = pAttrSet->GetPool()->GetDoc()->GetIStyleAccess();
109 mrpAttrSet = rSA.getAutomaticStyle( rNewAttrSet, rNode.IsTxtNode() ?
110 IStyleAccess::AUTO_STYLE_PARA :
111 IStyleAccess::AUTO_STYLE_NOTXT );
112 const bool bSetModifyAtAttr = ((SwAttrSet*)mrpAttrSet.get())->SetModifyAtAttr( &rNode );
113 rNode.SetModifyAtAttr( bSetModifyAtAttr );
117 void SetParent( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
118 const SwCntntNode& rNode,
119 const SwFmt* pParentFmt,
120 const SwFmt* pConditionalFmt )
122 const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get());
123 ASSERT( pAttrSet, "no SwAttrSet" )
124 ASSERT( pParentFmt || !pConditionalFmt, "ConditionalFmt without ParentFmt?" )
126 const SwAttrSet* pParentSet = pParentFmt ? &pParentFmt->GetAttrSet() : 0;
128 if ( pParentSet != pAttrSet->GetParent() )
130 SwAttrSet aNewSet( *pAttrSet );
131 aNewSet.SetParent( pParentSet );
132 aNewSet.ClearItem( RES_FRMATR_STYLE_NAME );
133 aNewSet.ClearItem( RES_FRMATR_CONDITIONAL_STYLE_NAME );
134 String sVal;
136 if ( pParentFmt )
138 SwStyleNameMapper::FillProgName( pParentFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True );
139 const SfxStringItem aAnyFmtColl( RES_FRMATR_STYLE_NAME, sVal );
140 aNewSet.Put( aAnyFmtColl );
142 if ( pConditionalFmt != pParentFmt )
143 SwStyleNameMapper::FillProgName( pConditionalFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True );
145 const SfxStringItem aFmtColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal );
146 aNewSet.Put( aFmtColl );
149 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
153 const SfxPoolItem* Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
154 const SwCntntNode& rNode,
155 const SfxPoolItem& rAttr )
157 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
158 const SfxPoolItem* pRet = aNewSet.Put( rAttr );
159 if ( pRet )
160 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
161 return pRet;
164 int Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, const SwCntntNode& rNode,
165 const SfxItemSet& rSet )
167 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
169 // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
170 SfxItemSet* pStyleNames = 0;
171 if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, FALSE ) )
173 pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME );
174 pStyleNames->Put( aNewSet );
176 // <--
178 const int nRet = aNewSet.Put( rSet );
180 // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
181 if ( pStyleNames )
183 aNewSet.Put( *pStyleNames );
184 delete pStyleNames;
186 // <--
188 if ( nRet )
189 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
191 return nRet;
194 int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
195 const SwCntntNode& rNode, const SfxPoolItem& rAttr,
196 SwAttrSet* pOld, SwAttrSet* pNew )
198 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
200 // for a correct broadcast, we need to do a SetModifyAtAttr with the items
201 // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle
202 if( rNode.GetModifyAtAttr() )
203 aNewSet.SetModifyAtAttr( &rNode );
205 const int nRet = aNewSet.Put_BC( rAttr, pOld, pNew );
207 if ( nRet )
208 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
210 return nRet;
213 int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
214 const SwCntntNode& rNode, const SfxItemSet& rSet,
215 SwAttrSet* pOld, SwAttrSet* pNew )
217 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
219 // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
220 SfxItemSet* pStyleNames = 0;
221 if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, FALSE ) )
223 pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME );
224 pStyleNames->Put( aNewSet );
226 // <--
228 // for a correct broadcast, we need to do a SetModifyAtAttr with the items
229 // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle
230 if( rNode.GetModifyAtAttr() )
231 aNewSet.SetModifyAtAttr( &rNode );
233 const int nRet = aNewSet.Put_BC( rSet, pOld, pNew );
235 // --> FME 2007-4-12 #i76273# Robust: Save the style name items:
236 if ( pStyleNames )
238 aNewSet.Put( *pStyleNames );
239 delete pStyleNames;
241 // <--
243 if ( nRet )
244 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
246 return nRet;
249 USHORT ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
250 const SwCntntNode& rNode, USHORT nWhich,
251 SwAttrSet* pOld, SwAttrSet* pNew )
253 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
254 if( rNode.GetModifyAtAttr() )
255 aNewSet.SetModifyAtAttr( &rNode );
256 const USHORT nRet = aNewSet.ClearItem_BC( nWhich, pOld, pNew );
257 if ( nRet )
258 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
259 return nRet;
262 USHORT ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
263 const SwCntntNode& rNode,
264 USHORT nWhich1, USHORT nWhich2,
265 SwAttrSet* pOld, SwAttrSet* pNew )
267 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
268 if( rNode.GetModifyAtAttr() )
269 aNewSet.SetModifyAtAttr( &rNode );
270 const USHORT nRet = aNewSet.ClearItem_BC( nWhich1, nWhich2, pOld, pNew );
271 if ( nRet )
272 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
273 return nRet;
278 /*******************************************************************
280 |* SwNode::GetSectionLevel
282 |* Beschreibung
283 |* Die Funktion liefert den Sectionlevel an der durch
284 |* aIndex bezeichneten Position.
286 |* Die Logik ist wie folgt: ( S -> Start, E -> End, C -> CntntNode)
287 |* Level 0 E
288 |* 1 S E
289 |* 2 SC
291 |* alle EndNodes der GrundSection haben den Level 0
292 |* alle StartNodes der GrundSection haben den Level 1
294 |* Ersterstellung
295 |* VER0100 vb 901214
297 |* Aenderung: JP 11.08.93
298 |* keine Rekursion mehr !!
300 *******************************************************************/
303 USHORT SwNode::GetSectionLevel() const
305 // EndNode einer Grund-Section ?? diese sind immer 0 !!
306 if( IsEndNode() && 0 == pStartOfSection->StartOfSectionIndex() )
307 return 0;
309 USHORT nLevel;
310 const SwNode* pNode = IsStartNode() ? this : pStartOfSection;
311 for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel )
312 pNode = pNode->pStartOfSection;
313 return IsEndNode() ? nLevel-1 : nLevel;
316 /*******************************************************************
318 |* SwNode::SwNode
320 |* Beschreibung
321 |* Konstruktor; dieser fuegt einen Node in das Array rNodes
322 |* an der Position rWhere ein. Dieser bekommt als
323 |* theEndOfSection den EndOfSection-Index des Nodes
324 |* unmittelbar vor ihm. Falls er sich an der Position 0
325 |* innerhalb des variablen Arrays befindet, wird
326 |* theEndOfSection 0 (der neue selbst).
328 |* Parameter
329 |* IN
330 |* rNodes bezeichnet das variable Array, in das der Node
331 |* eingefuegt werden soll
332 |* IN
333 |* rWhere bezeichnet die Position innerhalb dieses Arrays,
334 |* an der der Node eingefuegt werden soll
336 |* Ersterstellung
337 |* VER0100 vb 901214
339 |* Stand
340 |* VER0100 vb 901214
342 *******************************************************************/
344 #ifndef PRODUCT
345 long SwNode::nSerial = 0;
346 #endif
348 SwNode::SwNode( const SwNodeIndex &rWhere, const BYTE nNdType )
349 : nNodeType( nNdType ), pStartOfSection( 0 )
351 bSetNumLSpace = bIgnoreDontExpand = FALSE;
352 nAFmtNumLvl = 0;
354 SwNodes& rNodes = (SwNodes&)rWhere.GetNodes();
355 SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !!
356 if( rWhere.GetIndex() )
358 SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ];
359 rNodes.InsertNode( pInsNd, rWhere );
360 if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
362 pStartOfSection = pNd->pStartOfSection;
363 if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen!
365 pNd = pStartOfSection;
366 pStartOfSection = pNd->pStartOfSection;
370 else
372 rNodes.InsertNode( pInsNd, rWhere );
373 pStartOfSection = (SwStartNode*)this;
376 #ifndef PRODUCT
377 nMySerial = nSerial;
378 nSerial++;
379 #endif
382 SwNode::SwNode( SwNodes& rNodes, ULONG nPos, const BYTE nNdType )
383 : nNodeType( nNdType ), pStartOfSection( 0 )
385 bSetNumLSpace = bIgnoreDontExpand = FALSE;
386 nAFmtNumLvl = 0;
388 SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !!
389 if( nPos )
391 SwNode* pNd = rNodes[ nPos - 1 ];
392 rNodes.InsertNode( pInsNd, nPos );
393 if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
395 pStartOfSection = pNd->pStartOfSection;
396 if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen!
398 pNd = pStartOfSection;
399 pStartOfSection = pNd->pStartOfSection;
403 else
405 rNodes.InsertNode( pInsNd, nPos );
406 pStartOfSection = (SwStartNode*)this;
409 #ifndef PRODUCT
410 nMySerial = nSerial;
411 nSerial++;
412 #endif
415 SwNode::~SwNode()
419 // suche den TabellenNode, in dem dieser steht. Wenn in keiner
420 // Tabelle wird 0 returnt.
423 SwTableNode* SwNode::FindTableNode()
425 if( IsTableNode() )
426 return GetTableNode();
427 SwStartNode* pTmp = pStartOfSection;
428 while( !pTmp->IsTableNode() && pTmp->GetIndex() )
429 #if defined( ALPHA ) && defined( UNX )
430 pTmp = ((SwNode*)pTmp)->pStartOfSection;
431 #else
432 pTmp = pTmp->pStartOfSection;
433 #endif
434 return pTmp->GetTableNode();
438 // liegt der Node im Sichtbarenbereich der Shell ?
439 BOOL SwNode::IsInVisibleArea( ViewShell* pSh ) const
441 BOOL bRet = FALSE;
442 const SwCntntNode* pNd;
444 if( ND_STARTNODE & nNodeType )
446 SwNodeIndex aIdx( *this );
447 pNd = GetNodes().GoNext( &aIdx );
449 else if( ND_ENDNODE & nNodeType )
451 SwNodeIndex aIdx( *EndOfSectionNode() );
452 pNd = GetNodes().GoPrevious( &aIdx );
454 else
455 pNd = GetCntntNode();
457 const SwFrm* pFrm;
458 if( pNd && 0 != ( pFrm = pNd->GetFrm( 0, 0, FALSE ) ) )
460 if( !pSh )
461 // dann die Shell vom Doc besorgen:
462 GetDoc()->GetEditShell( &pSh );
464 if( pSh )
466 if ( pFrm->IsInTab() )
467 pFrm = pFrm->FindTabFrm();
469 if( !pFrm->IsValid() )
471 { pFrm = pFrm->FindPrev();
472 } while ( pFrm && !pFrm->IsValid() );
474 if( !pFrm || pSh->VisArea().IsOver( pFrm->Frm() ) )
475 bRet = TRUE;
479 return bRet;
482 BOOL SwNode::IsInProtectSect() const
484 const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
485 const SwSectionNode* pSectNd = pNd->FindSectionNode();
486 return pSectNd && pSectNd->GetSection().IsProtectFlag();
489 // befindet sich der Node in irgendetwas geschuetzten ?
490 // (Bereich/Rahmen/Tabellenzellen/... incl. des Ankers bei
491 // Rahmen/Fussnoten/..)
492 BOOL SwNode::IsProtect() const
494 const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
495 const SwStartNode* pSttNd = pNd->FindSectionNode();
496 if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() )
497 return TRUE;
499 if( 0 != ( pSttNd = FindTableBoxStartNode() ) )
501 SwCntntFrm* pCFrm;
502 if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->GetFrm() ))
503 return pCFrm->IsProtected();
505 const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
506 GetTblBox( pSttNd->GetIndex() );
507 //Robust #149568
508 if( pBox && pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
509 return TRUE;
512 SwFrmFmt* pFlyFmt = GetFlyFmt();
513 if( pFlyFmt )
515 if( pFlyFmt->GetProtect().IsCntntProtected() )
516 return TRUE;
517 const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
518 return rAnchor.GetCntntAnchor()
519 ? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect()
520 : FALSE;
523 if( 0 != ( pSttNd = FindFootnoteStartNode() ) )
525 const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry(
526 SwNodeIndex( *pSttNd ) );
527 if( pTFtn )
528 return pTFtn->GetTxtNode().IsProtect();
531 return FALSE;
534 // suche den PageDesc, mit dem dieser Node formatiert ist. Wenn das
535 // Layout vorhanden ist wird ueber das gesucht, ansonsten gibt es nur
536 // die harte Tour ueber die Nodes nach vorne suchen!!
537 const SwPageDesc* SwNode::FindPageDesc( BOOL bCalcLay,
538 sal_uInt32* pPgDescNdIdx ) const
540 // OD 18.03.2003 #106329#
541 if ( !GetNodes().IsDocNodes() )
543 return 0;
546 const SwPageDesc* pPgDesc = 0;
548 const SwCntntNode* pNode;
549 if( ND_STARTNODE & nNodeType )
551 SwNodeIndex aIdx( *this );
552 pNode = GetNodes().GoNext( &aIdx );
554 else if( ND_ENDNODE & nNodeType )
556 SwNodeIndex aIdx( *EndOfSectionNode() );
557 pNode = GetNodes().GoPrevious( &aIdx );
559 else
561 pNode = GetCntntNode();
562 if( pNode )
563 pPgDesc = ((SwFmtPageDesc&)pNode->GetAttr( RES_PAGEDESC )).GetPageDesc();
566 // geht es uebers Layout?
567 if( !pPgDesc )
569 const SwFrm* pFrm;
570 const SwPageFrm* pPage;
571 if( pNode && 0 != ( pFrm = pNode->GetFrm( 0, 0, bCalcLay ) ) &&
572 0 != ( pPage = pFrm->FindPageFrm() ) )
574 pPgDesc = pPage->GetPageDesc();
575 // OD 18.03.2003 #106329#
576 if ( pPgDescNdIdx )
578 *pPgDescNdIdx = pNode->GetIndex();
583 if( !pPgDesc )
585 // dann also uebers Nodes-Array
586 const SwDoc* pDoc = GetDoc();
587 const SwNode* pNd = this;
588 const SwStartNode* pSttNd;
589 if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() &&
590 0 != ( pSttNd = pNd->FindFlyStartNode() ) )
592 // dann erstmal den richtigen Anker finden
593 const SwFrmFmt* pFmt = 0;
594 const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
595 USHORT n;
597 for( n = 0; n < rFmts.Count(); ++n )
599 SwFrmFmt* pFrmFmt = rFmts[ n ];
600 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
601 if( rCntnt.GetCntntIdx() &&
602 &rCntnt.GetCntntIdx()->GetNode() == (SwNode*)pSttNd )
604 pFmt = pFrmFmt;
605 break;
609 if( pFmt )
611 const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
612 if( FLY_PAGE != pAnchor->GetAnchorId() &&
613 pAnchor->GetCntntAnchor() )
615 pNd = &pAnchor->GetCntntAnchor()->nNode.GetNode();
616 const SwNode* pFlyNd = pNd->FindFlyStartNode();
617 while( pFlyNd )
619 // dann ueber den Anker nach oben "hangeln"
620 for( n = 0; n < rFmts.Count(); ++n )
622 const SwFrmFmt* pFrmFmt = rFmts[ n ];
623 const SwNodeIndex* pIdx = pFrmFmt->GetCntnt().
624 GetCntntIdx();
625 if( pIdx && pFlyNd == &pIdx->GetNode() )
627 if( pFmt == pFrmFmt )
629 pNd = pFlyNd;
630 pFlyNd = 0;
631 break;
633 pAnchor = &pFrmFmt->GetAnchor();
634 if( FLY_PAGE == pAnchor->GetAnchorId() ||
635 !pAnchor->GetCntntAnchor() )
637 pFlyNd = 0;
638 break;
641 pFlyNd = pAnchor->GetCntntAnchor()->nNode.
642 GetNode().FindFlyStartNode();
643 break;
646 if( n >= rFmts.Count() )
648 ASSERT( !this, "Fly-Section aber kein Format gefunden" );
649 return FALSE;
654 // in pNd sollte jetzt der richtige Anker Node stehen oder
655 // immer noch der this
658 if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() )
660 if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() )
662 pPgDesc = &pDoc->GetPageDesc( 0 );
663 pNd = 0;
665 else
667 // suche den Body Textnode
668 if( 0 != ( pSttNd = pNd->FindHeaderStartNode() ) ||
669 0 != ( pSttNd = pNd->FindFooterStartNode() ))
671 // dann in den PageDescs diesen StartNode suchen
672 USHORT nId;
673 UseOnPage eAskUse;
674 if( SwHeaderStartNode == pSttNd->GetStartNodeType())
676 nId = RES_HEADER;
677 eAskUse = nsUseOnPage::PD_HEADERSHARE;
679 else
681 nId = RES_FOOTER;
682 eAskUse = nsUseOnPage::PD_FOOTERSHARE;
685 for( USHORT n = pDoc->GetPageDescCnt(); n && !pPgDesc; )
687 const SwPageDesc& rPgDsc = pDoc->GetPageDesc( --n );
688 const SwFrmFmt* pFmt = &rPgDsc.GetMaster();
689 int nStt = 0, nLast = 1;
690 if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast;
692 for( ; nStt < nLast; ++nStt, pFmt = &rPgDsc.GetLeft() )
694 const SwFmtHeader& rHdFt = (SwFmtHeader&)
695 pFmt->GetFmtAttr( nId );
696 if( rHdFt.GetHeaderFmt() )
698 const SwFmtCntnt& rCntnt =
699 rHdFt.GetHeaderFmt()->GetCntnt();
700 if( rCntnt.GetCntntIdx() &&
701 &rCntnt.GetCntntIdx()->GetNode() ==
702 (SwNode*)pSttNd )
704 pPgDesc = &rPgDsc;
705 break;
711 if( !pPgDesc )
712 pPgDesc = &pDoc->GetPageDesc( 0 );
713 pNd = 0;
715 else if( 0 != ( pSttNd = pNd->FindFootnoteStartNode() ))
717 // der Anker kann nur im Bodytext sein
718 const SwTxtFtn* pTxtFtn;
719 const SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
720 for( USHORT n = 0; n < rFtnArr.Count(); ++n )
721 if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
722 (SwNode*)pSttNd ==
723 &pTxtFtn->GetStartNode()->GetNode() )
725 pNd = &pTxtFtn->GetTxtNode();
726 break;
729 else
731 // kann jetzt nur noch ein Seitengebundener Fly sein
732 // oder irgendetwas neueres.
733 // Hier koennen wir nur noch den Standard returnen
734 ASSERT( pNd->FindFlyStartNode(),
735 "wo befindet sich dieser Node?" );
737 pPgDesc = &pDoc->GetPageDesc( 0 );
738 pNd = 0;
743 if( pNd )
745 SwFindNearestNode aInfo( *pNd );
746 // dann ueber alle Nodes aller PageDesc
747 const SfxPoolItem* pItem;
748 USHORT i, nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_PAGEDESC );
749 for( i = 0; i < nMaxItems; ++i )
750 if( 0 != (pItem = pDoc->GetAttrPool().GetItem( RES_PAGEDESC, i ) ) &&
751 ((SwFmtPageDesc*)pItem)->GetDefinedIn() )
753 const SwModify* pMod = ((SwFmtPageDesc*)pItem)->GetDefinedIn();
754 if( pMod->ISA( SwCntntNode ) )
755 aInfo.CheckNode( *(SwCntntNode*)pMod );
756 else if( pMod->ISA( SwFmt ))
757 ((SwFmt*)pMod)->GetInfo( aInfo );
760 if( 0 != ( pNd = aInfo.GetFoundNode() ))
762 if( pNd->IsCntntNode() )
763 pPgDesc = ((SwFmtPageDesc&)pNd->GetCntntNode()->
764 GetAttr( RES_PAGEDESC )).GetPageDesc();
765 else if( pNd->IsTableNode() )
766 pPgDesc = pNd->GetTableNode()->GetTable().
767 GetFrmFmt()->GetPageDesc().GetPageDesc();
768 else if( pNd->IsSectionNode() )
769 pPgDesc = pNd->GetSectionNode()->GetSection().
770 GetFmt()->GetPageDesc().GetPageDesc();
771 // OD 18.03.2003 #106329#
772 if ( pPgDescNdIdx )
774 *pPgDescNdIdx = pNd->GetIndex();
777 if( !pPgDesc )
778 pPgDesc = &pDoc->GetPageDesc( 0 );
781 return pPgDesc;
785 // falls der Node in einem Fly steht, dann wird das entsprechende Format
786 // returnt
787 SwFrmFmt* SwNode::GetFlyFmt() const
789 SwFrmFmt* pRet = 0;
790 const SwNode* pSttNd = FindFlyStartNode();
791 if( pSttNd )
793 if( IsCntntNode() )
795 SwClientIter aIter( *(SwCntntNode*)this );
796 SwClient* pCli = aIter.First( TYPE( SwCntntFrm ));
797 if( pCli )
798 pRet = ((SwCntntFrm*)pCli)->FindFlyFrm()->GetFmt();
800 if( !pRet )
802 // dann gibts noch harten steinigen Weg uebers Dokument:
803 const SwSpzFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts();
804 for( USHORT n = 0; n < rFrmFmtTbl.Count(); ++n )
806 SwFrmFmt* pFmt = rFrmFmtTbl[n];
807 const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
808 if( rCntnt.GetCntntIdx() &&
809 &rCntnt.GetCntntIdx()->GetNode() == pSttNd )
811 pRet = pFmt;
812 break;
817 return pRet;
820 SwTableBox* SwNode::GetTblBox() const
822 SwTableBox* pBox = 0;
823 const SwNode* pSttNd = FindTableBoxStartNode();
824 if( pSttNd )
825 pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox(
826 pSttNd->GetIndex() );
827 return pBox;
830 SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp )
832 SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection;
834 while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() )
835 #if defined( ALPHA ) && defined( UNX )
836 pTmp = ((SwNode*)pTmp)->pStartOfSection;
837 #else
838 pTmp = pTmp->pStartOfSection;
839 #endif
840 return eTyp == pTmp->GetStartNodeType() ? pTmp : 0;
843 const SwTxtNode* SwNode::FindOutlineNodeOfLevel( BYTE nLvl ) const
845 const SwTxtNode* pRet = 0;
846 const SwOutlineNodes& rONds = GetNodes().GetOutLineNds();
847 if( MAXLEVEL > nLvl && rONds.Count() )
849 USHORT nPos;
850 SwNode* pNd = (SwNode*)this;
851 BOOL bCheckFirst = FALSE;
852 if( !rONds.Seek_Entry( pNd, &nPos ))
854 if( nPos )
855 nPos = nPos-1;
856 else
857 bCheckFirst = TRUE;
860 if( bCheckFirst )
862 // der 1.GliederungsNode liegt hinter dem Fragenden. Dann
863 // teste mal, ob dieser auf der gleichen Seite steht. Wenn
864 // nicht, ist das ein ungueltiger. Bug 61865
865 pRet = rONds[0]->GetTxtNode();
867 const SwCntntNode* pCNd = GetCntntNode();
869 Point aPt( 0, 0 );
870 const SwFrm* pFrm = pRet->GetFrm( &aPt, 0, FALSE ),
871 * pMyFrm = pCNd ? pCNd->GetFrm( &aPt, 0, FALSE ) : 0;
872 const SwPageFrm* pPgFrm = pFrm ? pFrm->FindPageFrm() : 0;
873 if( pPgFrm && pMyFrm &&
874 pPgFrm->Frm().Top() > pMyFrm->Frm().Top() )
876 // der Fragende liegt vor der Seite, also ist er ungueltig
877 pRet = 0;
880 else
882 // oder ans Feld und von dort holen !!
883 while( nPos &&
884 nLvl < ( pRet = rONds[nPos]->GetTxtNode() )
885 //->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
886 ->GetAttrOutlineLevel() - 1 ) //<-end,zhaojianwei
887 --nPos;
889 if( !nPos ) // bei 0 gesondert holen !!
890 pRet = rONds[0]->GetTxtNode();
893 return pRet;
896 inline sal_Bool IsValidNextPrevNd( const SwNode& rNd )
898 return ND_TABLENODE == rNd.GetNodeType() ||
899 ( ND_CONTENTNODE & rNd.GetNodeType() ) ||
900 ( ND_ENDNODE == rNd.GetNodeType() && rNd.StartOfSectionNode() &&
901 ND_TABLENODE == rNd.StartOfSectionNode()->GetNodeType() );
904 BYTE SwNode::HasPrevNextLayNode() const
906 // assumption: <this> node is a node inside the document nodes array section.
908 BYTE nRet = 0;
909 if( IsValidNextPrevNd( *this ))
911 SwNodeIndex aIdx( *this, -1 );
912 // --> OD 2007-06-04 #i77805#
913 // skip section start and end nodes
914 while ( aIdx.GetNode().IsSectionNode() ||
915 ( aIdx.GetNode().IsEndNode() &&
916 aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) )
918 --aIdx;
920 // <--
921 if( IsValidNextPrevNd( aIdx.GetNode() ))
922 nRet |= ND_HAS_PREV_LAYNODE;
923 // --> OD 2007-06-04 #i77805#
924 // skip section start and end nodes
925 // aIdx += 2;
926 aIdx = SwNodeIndex( *this, +1 );
927 while ( aIdx.GetNode().IsSectionNode() ||
928 ( aIdx.GetNode().IsEndNode() &&
929 aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) )
931 ++aIdx;
933 // <--
934 if( IsValidNextPrevNd( aIdx.GetNode() ))
935 nRet |= ND_HAS_NEXT_LAYNODE;
937 return nRet;
940 /*******************************************************************
942 |* SwNode::StartOfSection
944 |* Beschreibung
945 |* Die Funktion liefert die StartOfSection des Nodes.
947 |* Parameter
948 |* IN
949 |* rNodes bezeichnet das variable Array, in dem sich der Node
950 |* befindet
951 |* Ersterstellung
952 |* VER0100 vb 901214
954 |* Stand
955 |* VER0100 vb 901214
957 *******************************************************************/
960 SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const BYTE nNdType,
961 SwStartNodeType eSttNd )
962 : SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd )
964 // erstmal temporaer, bis der EndNode eingefuegt wird.
965 pEndOfSection = (SwEndNode*)this;
968 SwStartNode::SwStartNode( SwNodes& rNodes, ULONG nPos )
969 : SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode )
971 // erstmal temporaer, bis der EndNode eingefuegt wird.
972 pEndOfSection = (SwEndNode*)this;
976 void SwStartNode::CheckSectionCondColl() const
978 //FEATURE::CONDCOLL
979 SwNodeIndex aIdx( *this );
980 ULONG nEndIdx = EndOfSectionIndex();
981 const SwNodes& rNds = GetNodes();
982 SwCntntNode* pCNd;
983 while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx )
984 pCNd->ChkCondColl();
985 //FEATURE::CONDCOLL
988 /*******************************************************************
990 |* SwEndNode::SwEndNode
992 |* Beschreibung
993 |* Konstruktor; dieser fuegt einen Node in das Array rNodes
994 |* an der Position aWhere ein. Der
995 |* theStartOfSection-Pointer wird entsprechend gesetzt,
996 |* und der EndOfSection-Pointer des zugehoerigen
997 |* Startnodes -- durch rStartOfSection bezeichnet --
998 |* wird auf diesen Node gesetzt.
1000 |* Parameter
1001 |* IN
1002 |* rNodes bezeichnet das variable Array, in das der Node
1003 |* eingefuegt werden soll
1004 |* IN
1005 |* aWhere bezeichnet die Position innerhalb dieses Arrays,
1006 |* an der der Node eingefuegt werden soll
1007 |* !!!!!!!!!!!!
1008 |* Es wird eine Kopie uebergeben!
1010 |* Ersterstellung
1011 |* VER0100 vb 901214
1013 |* Stand
1014 |* VER0100 vb 901214
1016 *******************************************************************/
1019 SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd )
1020 : SwNode( rWhere, ND_ENDNODE )
1022 pStartOfSection = &rSttNd;
1023 pStartOfSection->pEndOfSection = this;
1026 SwEndNode::SwEndNode( SwNodes& rNds, ULONG nPos, SwStartNode& rSttNd )
1027 : SwNode( rNds, nPos, ND_ENDNODE )
1029 pStartOfSection = &rSttNd;
1030 pStartOfSection->pEndOfSection = this;
1035 // --------------------
1036 // SwCntntNode
1037 // --------------------
1040 SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const BYTE nNdType,
1041 SwFmtColl *pColl )
1042 : SwModify( pColl ), // CrsrsShell, FrameFmt,
1043 SwNode( rWhere, nNdType ),
1044 pCondColl( 0 ),
1045 mbSetModifyAtAttr( false )
1046 #ifdef OLD_INDEX
1047 ,SwIndexReg(2)
1048 #endif
1053 SwCntntNode::~SwCntntNode()
1055 // Die Basisklasse SwClient vom SwFrm nimmt sich aus
1056 // der Abhaengikeitsliste raus!
1057 // Daher muessen alle Frames in der Abhaengigkeitsliste geloescht werden.
1058 if( GetDepends() )
1059 DelFrms();
1061 if( pCondColl )
1062 delete pCondColl;
1064 if ( mpAttrSet.get() && mbSetModifyAtAttr )
1065 ((SwAttrSet*)mpAttrSet.get())->SetModifyAtAttr( 0 );
1068 void SwCntntNode::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue )
1070 USHORT nWhich = pOldValue ? pOldValue->Which() :
1071 pNewValue ? pNewValue->Which() : 0 ;
1073 switch( nWhich )
1075 case RES_OBJECTDYING :
1077 SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject;
1079 // nicht umhaengen wenn dieses das oberste Format ist !!
1080 if( pRegisteredIn == pFmt )
1082 if( pFmt->GetRegisteredIn() )
1084 // wenn Parent, dann im neuen Parent wieder anmelden
1085 ((SwModify*)pFmt->GetRegisteredIn())->Add( this );
1086 if ( GetpSwAttrSet() )
1087 AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
1089 else
1091 // sonst auf jeden Fall beim sterbenden abmelden
1092 ((SwModify*)GetRegisteredIn())->Remove( this );
1093 if ( GetpSwAttrSet() )
1094 AttrSetHandleHelper::SetParent( mpAttrSet, *this, 0, 0 );
1098 break;
1101 case RES_FMT_CHG:
1102 // falls mein Format Parent umgesetzt wird, dann melde ich
1103 // meinen Attrset beim Neuen an.
1105 // sein eigenes Modify ueberspringen !!
1106 if( GetpSwAttrSet() &&
1107 ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() )
1109 // den Set an den neuen Parent haengen
1110 AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
1112 break;
1113 //FEATURE::CONDCOLL
1114 case RES_CONDCOLL_CONDCHG:
1115 if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() &&
1116 &GetNodes() == &GetDoc()->GetNodes() )
1118 ChkCondColl();
1120 return ; // nicht an die Basisklasse / Frames weitergeben
1121 //FEATURE::CONDCOLL
1123 case RES_ATTRSET_CHG:
1124 if( GetNodes().IsDocNodes() && IsTxtNode() )
1126 if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState(
1127 RES_CHRATR_HIDDEN, FALSE ) )
1129 ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1132 break;
1134 case RES_UPDATE_ATTR:
1135 if( GetNodes().IsDocNodes() && IsTxtNode() )
1137 const USHORT nTmp = ((SwUpdateAttr*)pNewValue)->nWhichAttr;
1138 if ( RES_ATTRSET_CHG == nTmp )
1140 // anybody wants to do some optimization here?
1141 ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1144 break;
1147 SwModify::Modify( pOldValue, pNewValue );
1150 BOOL SwCntntNode::InvalidateNumRule()
1152 SwNumRule* pRule = 0;
1153 const SfxPoolItem* pItem;
1154 if( GetNodes().IsDocNodes() &&
1155 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE )) &&
1156 ((SwNumRuleItem*)pItem)->GetValue().Len() &&
1157 0 != (pRule = GetDoc()->FindNumRulePtr(
1158 ((SwNumRuleItem*)pItem)->GetValue() ) ) )
1160 pRule->SetInvalidRule( TRUE );
1162 return 0 != pRule;
1166 SwCntntFrm *SwCntntNode::GetFrm( const Point* pPoint,
1167 const SwPosition *pPos,
1168 const BOOL bCalcFrm ) const
1170 return (SwCntntFrm*) ::GetFrmOfModify( *(SwModify*)this, FRM_CNTNT,
1171 pPoint, pPos, bCalcFrm );
1174 SwRect SwCntntNode::FindLayoutRect( const BOOL bPrtArea, const Point* pPoint,
1175 const BOOL bCalcFrm ) const
1177 SwRect aRet;
1178 SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( *(SwModify*)this,
1179 FRM_CNTNT, pPoint, 0, bCalcFrm );
1180 if( pFrm )
1181 aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1182 return aRet;
1185 SwRect SwCntntNode::FindPageFrmRect( const BOOL bPrtArea, const Point* pPoint,
1186 const BOOL bCalcFrm ) const
1188 SwRect aRet;
1189 SwFrm* pFrm = ::GetFrmOfModify( *(SwModify*)this,
1190 FRM_CNTNT, pPoint, 0, bCalcFrm );
1191 if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() ))
1192 aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1193 return aRet;
1196 xub_StrLen SwCntntNode::Len() const { return 0; }
1200 SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl )
1202 ASSERT( pNewColl, "Collectionpointer ist 0." );
1203 SwFmtColl *pOldColl = GetFmtColl();
1205 if( pNewColl != pOldColl )
1207 pNewColl->Add( this );
1209 // setze den Parent von unseren Auto-Attributen auf die neue
1210 // Collection:
1211 if( GetpSwAttrSet() )
1212 AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl );
1214 //FEATURE::CONDCOLL
1215 // HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen
1216 // neu ueberprueft werden!
1217 if( TRUE /*pNewColl */ )
1219 SetCondFmtColl( 0 );
1221 //FEATURE::CONDCOLL
1223 if( !IsModifyLocked() )
1225 SwFmtChg aTmp1( pOldColl );
1226 SwFmtChg aTmp2( pNewColl );
1227 // damit alles was im Modify passiert hier nicht noch impl.
1228 // werden muss
1229 SwCntntNode::Modify( &aTmp1, &aTmp2 );
1232 if ( IsInCache() )
1234 SwFrm::GetCache().Delete( this );
1235 SetInCache( FALSE );
1237 return pOldColl;
1241 BOOL SwCntntNode::GoNext(SwIndex * pIdx, USHORT nMode ) const
1243 BOOL bRet = TRUE;
1244 if( pIdx->GetIndex() < Len() )
1246 if( !IsTxtNode() )
1247 (*pIdx)++;
1248 else
1250 const SwTxtNode& rTNd = *GetTxtNode();
1251 xub_StrLen nPos = pIdx->GetIndex();
1252 if( pBreakIt->GetBreakIter().is() )
1254 sal_Int32 nDone = 0;
1255 sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1256 CharacterIteratorMode::SKIPCELL :
1257 CharacterIteratorMode::SKIPCONTROLCHARACTER;
1258 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetTxt(), nPos,
1259 pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1260 nItrMode, 1, nDone );
1262 // Check if nPos is inside hidden text range:
1263 if ( CRSR_SKIP_HIDDEN & nMode )
1265 xub_StrLen nHiddenStart;
1266 xub_StrLen nHiddenEnd;
1267 SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1268 if ( nHiddenStart != STRING_LEN && nHiddenStart != nPos )
1269 nPos = nHiddenEnd;
1272 if( 1 == nDone )
1273 *pIdx = nPos;
1274 else
1275 bRet = FALSE;
1277 else if( nPos < rTNd.GetTxt().Len() )
1278 (*pIdx)++;
1279 else
1280 bRet = FALSE;
1283 else
1284 bRet = FALSE;
1285 return bRet;
1289 BOOL SwCntntNode::GoPrevious(SwIndex * pIdx, USHORT nMode ) const
1291 BOOL bRet = TRUE;
1292 if( pIdx->GetIndex() > 0 )
1294 if( !IsTxtNode() )
1295 (*pIdx)--;
1296 else
1298 const SwTxtNode& rTNd = *GetTxtNode();
1299 xub_StrLen nPos = pIdx->GetIndex();
1300 if( pBreakIt->GetBreakIter().is() )
1302 sal_Int32 nDone = 0;
1303 sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1304 CharacterIteratorMode::SKIPCELL :
1305 CharacterIteratorMode::SKIPCONTROLCHARACTER;
1306 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetTxt(), nPos,
1307 pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1308 nItrMode, 1, nDone );
1310 // Check if nPos is inside hidden text range:
1311 if ( CRSR_SKIP_HIDDEN & nMode )
1313 xub_StrLen nHiddenStart;
1314 xub_StrLen nHiddenEnd;
1315 SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1316 if ( nHiddenStart != STRING_LEN )
1317 nPos = nHiddenStart;
1320 if( 1 == nDone )
1321 *pIdx = nPos;
1322 else
1323 bRet = FALSE;
1325 else if( nPos )
1326 (*pIdx)--;
1327 else
1328 bRet = FALSE;
1331 else
1332 bRet = FALSE;
1333 return bRet;
1338 * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
1339 * Dokument. Die erzeugten Contentframes werden in das entsprechende
1340 * Layout gehaengt.
1344 void SwCntntNode::MakeFrms( SwCntntNode& rNode )
1346 ASSERT( &rNode != this,
1347 "Kein Contentnode oder Copy-Node und neuer Node identisch." );
1349 if( !GetDepends() || &rNode == this ) // gibt es ueberhaupt Frames ??
1350 return;
1352 SwFrm *pFrm, *pNew;
1353 SwLayoutFrm *pUpper;
1354 // Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ??
1355 ASSERT( FindTableNode() == rNode.FindTableNode(), "Table confusion" )
1357 SwNode2Layout aNode2Layout( *this, rNode.GetIndex() );
1359 while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) )
1361 pNew = rNode.MakeFrm();
1362 pNew->Paste( pUpper, pFrm );
1363 // --> OD 2005-12-01 #i27138#
1364 // notify accessibility paragraphs objects about changed
1365 // CONTENT_FLOWS_FROM/_TO relation.
1366 // Relation CONTENT_FLOWS_FROM for next paragraph will change
1367 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1368 if ( pNew->IsTxtFrm() )
1370 ViewShell* pViewShell( pNew->GetShell() );
1371 if ( pViewShell && pViewShell->GetLayout() &&
1372 pViewShell->GetLayout()->IsAnyShellAccessible() )
1374 pViewShell->InvalidateAccessibleParaFlowRelation(
1375 dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
1376 dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) );
1379 // <--
1384 * Methode loescht fuer den Node alle Ansichten vom
1385 * Dokument. Die Contentframes werden aus dem entsprechenden
1386 * Layout ausgehaengt.
1390 void SwCntntNode::DelFrms()
1392 if( !GetDepends() )
1393 return;
1395 SwClientIter aIter( *this );
1396 SwCntntFrm *pFrm;
1398 for( pFrm = (SwCntntFrm*)aIter.First( TYPE(SwCntntFrm)); pFrm;
1399 pFrm = (SwCntntFrm*)aIter.Next() )
1401 // --> OD 2005-12-01 #i27138#
1402 // notify accessibility paragraphs objects about changed
1403 // CONTENT_FLOWS_FROM/_TO relation.
1404 // Relation CONTENT_FLOWS_FROM for current next paragraph will change
1405 // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
1406 if ( pFrm->IsTxtFrm() )
1408 ViewShell* pViewShell( pFrm->GetShell() );
1409 if ( pViewShell && pViewShell->GetLayout() &&
1410 pViewShell->GetLayout()->IsAnyShellAccessible() )
1412 pViewShell->InvalidateAccessibleParaFlowRelation(
1413 dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1414 dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1417 // <--
1418 if( pFrm->HasFollow() )
1419 pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() );
1420 if( pFrm->IsFollow() )
1422 SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster();
1423 pMaster->SetFollow( pFrm->GetFollow() );
1424 pFrm->_SetIsFollow( FALSE );
1426 pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt.
1427 //Andernfalls kann es sein, dass ein Follow
1428 //vor seinem Master zerstoert wird, der Master
1429 //greift dann ueber den ungueltigen
1430 //Follow-Pointer auf fremdes Memory zu.
1431 //Die Kette darf hier zerknauscht werden, weil
1432 //sowieso alle zerstoert werden.
1433 if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() &&
1434 !pFrm->GetIndPrev() )
1436 SwFtnFrm *pFtn = pFrm->FindFtnFrm();
1437 ASSERT( pFtn, "You promised a FtnFrm?" );
1438 SwCntntFrm* pCFrm;
1439 if( !pFtn->GetFollow() && !pFtn->GetMaster() &&
1440 0 != ( pCFrm = pFtn->GetRefFromAttr()) && pCFrm->IsFollow() )
1442 ASSERT( pCFrm->IsTxtFrm(), "NoTxtFrm has Footnote?" );
1443 ((SwTxtFrm*)pCFrm->FindMaster())->Prepare( PREP_FTN_GONE );
1446 pFrm->Cut();
1447 delete pFrm;
1449 if( IsTxtNode() )
1451 ((SwTxtNode*)this)->SetWrong( NULL );
1452 ((SwTxtNode*)this)->SetWrongDirty( true );
1454 ((SwTxtNode*)this)->SetGrammarCheck( NULL );
1455 ((SwTxtNode*)this)->SetGrammarCheckDirty( true );
1456 // SMARTTAGS
1457 ((SwTxtNode*)this)->SetSmartTags( NULL );
1458 ((SwTxtNode*)this)->SetSmartTagDirty( true );
1460 ((SwTxtNode*)this)->SetWordCountDirty( true );
1461 ((SwTxtNode*)this)->SetAutoCompleteWordDirty( true );
1466 SwCntntNode *SwCntntNode::JoinNext()
1468 return this;
1472 SwCntntNode *SwCntntNode::JoinPrev()
1474 return this;
1479 // erfrage vom Modify Informationen
1480 BOOL SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const
1482 const SwNumRuleItem* pItem;
1483 switch( rInfo.Which() )
1485 case RES_AUTOFMT_DOCNODE:
1486 if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
1488 ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this;
1489 return FALSE;
1491 break;
1492 // --> OD 2008-02-19 #refactorlists#
1493 // case RES_GETNUMNODES:
1494 // // #111955# only numbered nodes in rInfo
1495 // if( IsTxtNode())
1496 // {
1497 // SwTxtNode * pTxtNode = (SwTxtNode*)this;
1498 // pItem = (SwNumRuleItem*)GetNoCondAttr(RES_PARATR_NUMRULE, TRUE );
1500 // if (0 != pItem &&
1501 // pItem->GetValue().Len() &&
1502 // pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() &&
1503 // GetNodes().IsDocNodes())
1504 // {
1505 // ((SwNumRuleInfo&)rInfo).AddNode( *pTxtNode );
1506 // }
1507 // }
1509 // return TRUE;
1510 // <--
1512 case RES_GETLOWERNUMLEVEL:
1513 if( IsTxtNode() &&
1514 0 != ( pItem = (SwNumRuleItem*)GetNoCondAttr(
1515 RES_PARATR_NUMRULE, TRUE )) && pItem->GetValue().Len() &&
1516 pItem->GetValue() == ((SwNRuleLowerLevel&)rInfo).GetName() &&
1517 ((SwTxtNode*)this)->GetActualListLevel()
1518 > ((SwNRuleLowerLevel&)rInfo).GetLevel() )
1520 return FALSE;
1522 break;
1524 case RES_FINDNEARESTNODE:
1525 if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() )
1526 ((SwFindNearestNode&)rInfo).CheckNode( *this );
1527 return TRUE;
1529 case RES_CONTENT_VISIBLE:
1531 ((SwPtrMsgPoolItem&)rInfo).pObject =
1532 SwClientIter( *(SwCntntNode*)this ).First( TYPE(SwFrm) );
1534 return FALSE;
1537 return SwModify::GetInfo( rInfo );
1541 // setze ein Attribut
1542 BOOL SwCntntNode::SetAttr(const SfxPoolItem& rAttr )
1544 if( !GetpSwAttrSet() ) // lasse von den entsprechenden Nodes die
1545 NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen
1547 ASSERT( GetpSwAttrSet(), "warum wurde kein AttrSet angelegt?" );
1549 if ( IsInCache() )
1551 SwFrm::GetCache().Delete( this );
1552 SetInCache( FALSE );
1555 BOOL bRet = FALSE;
1556 // wenn Modify gelockt ist, werden keine Modifies verschickt
1557 if( IsModifyLocked() ||
1558 ( !GetDepends() && RES_PARATR_NUMRULE != rAttr.Which() ))
1560 bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr );
1562 else
1564 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1565 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1566 if( 0 != ( bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ) ))
1568 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1569 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1570 Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt
1573 return bRet;
1575 #include <svtools/itemiter.hxx>
1577 BOOL SwCntntNode::SetAttr( const SfxItemSet& rSet )
1579 if ( IsInCache() )
1581 SwFrm::GetCache().Delete( this );
1582 SetInCache( FALSE );
1585 const SfxPoolItem* pFnd = 0;
1586 if( SFX_ITEM_SET == rSet.GetItemState( RES_AUTO_STYLE, FALSE, &pFnd ) )
1588 ASSERT( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" );
1589 const SwFmtAutoFmt* pTmp = static_cast<const SwFmtAutoFmt*>(pFnd);
1591 // If there already is an attribute set (usually containing a numbering
1592 // item), we have to merge the attribute of the new set into the old set:
1593 bool bSetParent = true;
1594 if ( GetpSwAttrSet() )
1596 bSetParent = false;
1597 AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() );
1599 else
1601 mpAttrSet = pTmp->GetStyleHandle();
1604 if ( bSetParent )
1606 // If the content node has a conditional style, we have to set the
1607 // string item containing the correct conditional style name (the
1608 // style name property has already been set during the import!)
1609 // In case we do not have a conditional style, we make use of the
1610 // fact that nobody else uses the attribute set behind the handle.
1611 // FME 2007-07-10 #i78124# If autostyle does not have a parent,
1612 // the string is empty.
1613 const SfxPoolItem* pNameItem = 0;
1614 if ( 0 != GetCondFmtColl() ||
1615 SFX_ITEM_SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, FALSE, &pNameItem ) ||
1616 0 == static_cast<const SfxStringItem*>(pNameItem)->GetValue().Len() )
1617 AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1618 else
1619 const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFmtColl()->GetAttrSet() );
1622 return TRUE;
1625 if( !GetpSwAttrSet() ) // lasse von den entsprechenden Nodes die
1626 NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen
1628 BOOL bRet = FALSE;
1629 // wenn Modify gelockt ist, werden keine Modifies verschickt
1630 if ( IsModifyLocked() ||
1631 ( !GetDepends() &&
1632 SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, FALSE ) ) )
1634 // einige Sonderbehandlungen fuer Attribute
1635 bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rSet );
1637 else
1639 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1640 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1641 if( 0 != (bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew )) )
1643 // einige Sonderbehandlungen fuer Attribute
1644 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1645 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1646 Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt
1649 return bRet;
1652 // Nimmt den Hint mit nWhich aus dem Delta-Array
1655 BOOL SwCntntNode::ResetAttr( USHORT nWhich1, USHORT nWhich2 )
1657 if( !GetpSwAttrSet() )
1658 return FALSE;
1660 if ( IsInCache() )
1662 SwFrm::GetCache().Delete( this );
1663 SetInCache( FALSE );
1666 // wenn Modify gelockt ist, werden keine Modifies verschickt
1667 if( IsModifyLocked() )
1669 USHORT nDel = 0;
1670 if ( !nWhich2 || nWhich2 < nWhich1 )
1672 std::vector<USHORT> aClearWhichIds;
1673 aClearWhichIds.push_back( nWhich1 );
1674 nDel = ClearItemsFromAttrSet( aClearWhichIds );
1676 else
1677 nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, 0, 0 );
1679 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen
1680 mpAttrSet.reset();//DELETEZ( mpAttrSet );
1681 return 0 != nDel;
1684 // sollte kein gueltiger Bereich definiert sein ?
1685 if( !nWhich2 || nWhich2 < nWhich1 )
1686 nWhich2 = nWhich1; // dann setze auf 1. Id, nur dieses Item
1688 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1689 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1690 BOOL bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew );
1692 if( bRet )
1694 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1695 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1696 Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt
1698 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen
1699 mpAttrSet.reset();//DELETEZ( mpAttrSet );
1701 return bRet;
1703 BOOL SwCntntNode::ResetAttr( const SvUShorts& rWhichArr )
1705 if( !GetpSwAttrSet() )
1706 return FALSE;
1708 if ( IsInCache() )
1710 SwFrm::GetCache().Delete( this );
1711 SetInCache( FALSE );
1714 // wenn Modify gelockt ist, werden keine Modifies verschickt
1715 USHORT nDel = 0;
1716 if( IsModifyLocked() )
1718 std::vector<USHORT> aClearWhichIds;
1719 for( USHORT n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
1720 aClearWhichIds.push_back( rWhichArr[ n ] );
1722 nDel = ClearItemsFromAttrSet( aClearWhichIds );
1724 else
1726 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1727 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1729 for( USHORT n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
1730 if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, rWhichArr[ n ], &aOld, &aNew ))
1731 ++nDel;
1733 if( nDel )
1735 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1736 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1737 Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt
1740 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen
1741 mpAttrSet.reset();//DELETEZ( mpAttrSet );
1742 return 0 != nDel ;
1746 USHORT SwCntntNode::ResetAllAttr()
1748 if( !GetpSwAttrSet() )
1749 return 0;
1751 if ( IsInCache() )
1753 SwFrm::GetCache().Delete( this );
1754 SetInCache( FALSE );
1757 // wenn Modify gelockt ist, werden keine Modifies verschickt
1758 if( IsModifyLocked() )
1760 std::vector<USHORT> aClearWhichIds;
1761 aClearWhichIds.push_back(0);
1762 USHORT nDel = ClearItemsFromAttrSet( aClearWhichIds );
1763 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen
1764 mpAttrSet.reset(); // DELETEZ( mpAttrSet );
1765 return nDel;
1768 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1769 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1770 BOOL bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew );
1772 if( bRet )
1774 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1775 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1776 Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt
1778 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen
1779 mpAttrSet.reset();//DELETEZ( mpAttrSet );
1781 return aNew.Count();
1785 BOOL SwCntntNode::GetAttr( SfxItemSet& rSet, BOOL bInParent ) const
1787 if( rSet.Count() )
1788 rSet.ClearItem();
1790 const SwAttrSet& rAttrSet = GetSwAttrSet();
1791 if( bInParent )
1792 return rSet.Set( rAttrSet, TRUE ) ? TRUE : FALSE;
1794 rSet.Put( rAttrSet );
1795 return rSet.Count() ? TRUE : FALSE;
1798 USHORT SwCntntNode::ClearItemsFromAttrSet( const std::vector<USHORT>& rWhichIds )
1800 USHORT nRet = 0;
1801 if ( 0 == rWhichIds.size() )
1802 return nRet;
1804 ASSERT( GetpSwAttrSet(), "no item set" )
1805 SwAttrSet aNewAttrSet( *GetpSwAttrSet() );
1806 for ( std::vector<USHORT>::const_iterator aIter = rWhichIds.begin();
1807 aIter != rWhichIds.end();
1808 ++aIter )
1810 nRet = nRet + aNewAttrSet.ClearItem( *aIter );
1812 if ( nRet )
1813 AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet );
1815 return nRet;
1818 const SfxPoolItem* SwCntntNode::GetNoCondAttr( USHORT nWhich,
1819 BOOL bInParents ) const
1821 const SfxPoolItem* pFnd = 0;
1822 if( pCondColl && pCondColl->GetRegisteredIn() )
1824 if( !GetpSwAttrSet() || ( SFX_ITEM_SET != GetpSwAttrSet()->GetItemState(
1825 nWhich, FALSE, &pFnd ) && bInParents ))
1826 ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd );
1828 // --> OD 2005-10-25 #126347# - undo change of issue #i51029#
1829 // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns
1830 // the attribute set of the paragraph style, which is valid for the
1831 // content node - see file <node.hxx>
1832 else
1833 // <--
1835 GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd );
1837 return pFnd;
1840 // koennen 2 Nodes zusammengefasst werden ?
1841 // in pIdx kann die 2. Position returnt werden.
1842 int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
1844 const SwNodes& rNds = GetNodes();
1845 BYTE nNdType = GetNodeType();
1846 SwNodeIndex aIdx( *this, 1 );
1848 const SwNode* pNd = this;
1849 while( aIdx < rNds.Count()-1 &&
1850 (( pNd = &aIdx.GetNode())->IsSectionNode() ||
1851 ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1852 aIdx++;
1854 if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
1855 return FALSE;
1856 if( IsTxtNode() )
1857 { // Do not merge strings if the result exceeds the allowed string length
1858 const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this);
1859 sal_uInt64 nSum = pTxtNd->GetTxt().Len();
1860 pTxtNd = static_cast<const SwTxtNode*>(pNd);
1861 nSum += pTxtNd->GetTxt().Len();
1862 if( nSum > STRING_LEN )
1863 return FALSE;
1865 if( pIdx )
1866 *pIdx = aIdx;
1867 return TRUE;
1871 // koennen 2 Nodes zusammengefasst werden ?
1872 // in pIdx kann die 2. Position returnt werden.
1873 int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
1875 BYTE nNdType = GetNodeType();
1876 SwNodeIndex aIdx( *this, -1 );
1878 const SwNode* pNd = this;
1879 while( aIdx.GetIndex() &&
1880 (( pNd = &aIdx.GetNode())->IsSectionNode() ||
1881 ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1882 aIdx--;
1884 if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
1885 return FALSE;
1886 if( pIdx )
1887 *pIdx = aIdx;
1888 return TRUE;
1892 //FEATURE::CONDCOLL
1895 void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl )
1897 if( (!pColl && pCondColl) || ( pColl && !pCondColl ) ||
1898 ( pColl && pColl != pCondColl->GetRegisteredIn() ) )
1900 SwFmtColl* pOldColl = GetCondFmtColl();
1901 delete pCondColl;
1902 if( pColl )
1903 pCondColl = new SwDepend( this, pColl );
1904 else
1905 pCondColl = 0;
1907 if( GetpSwAttrSet() )
1909 AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1912 if( !IsModifyLocked() )
1914 SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() );
1915 SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() );
1916 SwModify::Modify( &aTmp1, &aTmp2 );
1918 if( IsInCache() )
1920 SwFrm::GetCache().Delete( this );
1921 SetInCache( FALSE );
1927 BOOL SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const
1929 const SwNodes& rNds = GetNodes();
1931 int nCond = 0;
1932 const SwStartNode* pSttNd = StartOfSectionNode();
1933 while( pSttNd )
1935 switch( pSttNd->GetNodeType() )
1937 case ND_TABLENODE: nCond = PARA_IN_TABLEBODY; break;
1938 case ND_SECTIONNODE: nCond = PARA_IN_SECTION; break;
1940 default:
1941 switch( pSttNd->GetStartNodeType() )
1943 case SwTableBoxStartNode:
1945 nCond = PARA_IN_TABLEBODY;
1946 const SwTableNode* pTblNd = pSttNd->FindTableNode();
1947 const SwTableBox* pBox;
1948 if( pTblNd && 0 != ( pBox = pTblNd->GetTable().
1949 GetTblBox( pSttNd->GetIndex() ) ) && pBox &&
1950 pBox->IsInHeadline( &pTblNd->GetTable() ) )
1951 nCond = PARA_IN_TABLEHEAD;
1953 break;
1954 case SwFlyStartNode: nCond = PARA_IN_FRAME; break;
1955 case SwFootnoteStartNode:
1957 nCond = PARA_IN_FOOTENOTE;
1958 const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs();
1959 const SwTxtFtn* pTxtFtn;
1960 const SwNode* pSrchNd = pSttNd;
1962 for( USHORT n = 0; n < rFtnArr.Count(); ++n )
1963 if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
1964 pSrchNd == &pTxtFtn->GetStartNode()->GetNode() )
1966 if( pTxtFtn->GetFtn().IsEndNote() )
1967 nCond = PARA_IN_ENDNOTE;
1968 break;
1971 break;
1972 case SwHeaderStartNode: nCond = PARA_IN_HEADER; break;
1973 case SwFooterStartNode: nCond = PARA_IN_FOOTER; break;
1974 case SwNormalStartNode: break;
1978 if( nCond )
1980 rTmp.SetCondition( (Master_CollConditions)nCond, 0 );
1981 return TRUE;
1983 pSttNd = pSttNd->GetIndex()
1984 ? pSttNd->StartOfSectionNode()
1985 : 0;
1990 USHORT nPos;
1991 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1992 if( rOutlNds.Count() )
1994 if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos )
1995 --nPos;
1996 if( nPos < rOutlNds.Count() &&
1997 rOutlNds[ nPos ]->GetIndex() < GetIndex() )
1999 SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode();
2001 if( pOutlNd->IsOutline())
2003 rTmp.SetCondition( PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 );
2004 return TRUE;
2010 return FALSE;
2014 void SwCntntNode::ChkCondColl()
2016 // zur Sicherheit abfragen
2017 if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() )
2019 SwCollCondition aTmp( 0, 0, 0 );
2020 const SwCollCondition* pCColl;
2022 bool bDone = false;
2024 if( IsAnyCondition( aTmp ))
2026 pCColl = static_cast<SwConditionTxtFmtColl*>(GetFmtColl())
2027 ->HasCondition( aTmp );
2029 if (pCColl)
2031 SetCondFmtColl( pCColl->GetTxtFmtColl() );
2032 bDone = true;
2036 if (!bDone)
2038 if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule())
2040 // steht in einer Numerierung
2041 // welcher Level?
2042 aTmp.SetCondition( PARA_IN_LIST,
2043 ((SwTxtNode*)this)->GetActualListLevel() );
2044 pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())->
2045 HasCondition( aTmp );
2047 else
2048 pCColl = 0;
2050 if( pCColl )
2051 SetCondFmtColl( pCColl->GetTxtFmtColl() );
2052 else if( pCondColl )
2053 SetCondFmtColl( 0 );
2058 // --> OD 2005-02-21 #i42921#
2059 short SwCntntNode::GetTextDirection( const SwPosition& rPos,
2060 const Point* pPt ) const
2062 short nRet = -1;
2064 Point aPt;
2065 if( pPt )
2066 aPt = *pPt;
2068 // --> OD 2007-01-10 #i72024#
2069 // No format of the frame, because this can cause recursive layout actions
2070 SwFrm* pFrm = GetFrm( &aPt, &rPos, FALSE );
2071 // <--
2073 if ( pFrm )
2075 if ( pFrm->IsVertical() )
2077 if ( pFrm->IsRightToLeft() )
2078 nRet = FRMDIR_VERT_TOP_LEFT;
2079 else
2080 nRet = FRMDIR_VERT_TOP_RIGHT;
2082 else
2084 if ( pFrm->IsRightToLeft() )
2085 nRet = FRMDIR_HORI_RIGHT_TOP;
2086 else
2087 nRet = FRMDIR_HORI_LEFT_TOP;
2092 return nRet;
2094 // <--
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()
2102 return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0;
2104 const SwTxtNode *SwNode::GetTxtNode() const
2106 return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0;
2108 #endif
2111 * Document Interface Access
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()
2131 return *GetDoc();
2133 // <--
2135 BOOL SwNode::IsInRedlines() const
2137 const SwDoc * pDoc = GetDoc();
2138 BOOL bResult = FALSE;
2140 if (pDoc != NULL)
2141 bResult = pDoc->IsInRedlines(*this);
2143 return bResult;