xref: /AOO41X/main/sw/source/core/docnode/node.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
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 
GetNewAutoStyle(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,SwAttrSet & rNewAttrSet)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 
SetParent(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,const SwFmt * pParentFmt,const SwFmt * pConditionalFmt)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 
Put(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,const SfxPoolItem & rAttr)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 
Put(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,const SfxItemSet & rSet)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 
Put_BC(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,const SfxPoolItem & rAttr,SwAttrSet * pOld,SwAttrSet * pNew)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 
Put_BC(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,const SfxItemSet & rSet,SwAttrSet * pOld,SwAttrSet * pNew)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 
ClearItem_BC(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,sal_uInt16 nWhich,SwAttrSet * pOld,SwAttrSet * pNew)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 
ClearItem_BC(boost::shared_ptr<const SfxItemSet> & mrpAttrSet,const SwCntntNode & rNode,sal_uInt16 nWhich1,sal_uInt16 nWhich2,SwAttrSet * pOld,SwAttrSet * pNew)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 
GetSectionLevel() const288 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 
SwNode(const SwNodeIndex & rWhere,const sal_uInt8 nNdType)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 
SwNode(SwNodes & rNodes,sal_uLong nPos,const sal_uInt8 nNdType)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 
~SwNode()400 SwNode::~SwNode()
401 {
402 }
403 
404 // suche den TabellenNode, in dem dieser steht. Wenn in keiner
405 // Tabelle wird 0 returnt.
406 
407 
FindTableNode()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 ?
IsInVisibleArea(ViewShell * pSh) const424 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 
IsInProtectSect() const468 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/..)
IsProtect() const478 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!!
FindPageDesc(sal_Bool bCalcLay,sal_uInt32 * pPgDescNdIdx) const523 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
GetFlyFmt() const773 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 
GetTblBox() const805 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 
FindSttNodeByType(SwStartNodeType eTyp)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 
FindOutlineNodeOfLevel(sal_uInt8 nLvl) const828 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 
IsValidNextPrevNd(const SwNode & rNd)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 
HasPrevNextLayNode() const889 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 
SwStartNode(const SwNodeIndex & rWhere,const sal_uInt8 nNdType,SwStartNodeType eSttNd)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 
SwStartNode(SwNodes & rNodes,sal_uLong nPos)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 
CheckSectionCondColl() const961 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 
SwEndNode(const SwNodeIndex & rWhere,SwStartNode & rSttNd)1004 SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd )
1005     : SwNode( rWhere, ND_ENDNODE )
1006 {
1007     pStartOfSection = &rSttNd;
1008     pStartOfSection->pEndOfSection = this;
1009 }
1010 
SwEndNode(SwNodes & rNds,sal_uLong nPos,SwStartNode & rSttNd)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 
SwCntntNode(const SwNodeIndex & rWhere,const sal_uInt8 nNdType,SwFmtColl * pColl)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 
~SwCntntNode()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         DelFrms(sal_True, sal_False);
1045 
1046     if( pCondColl )
1047         delete pCondColl;
1048 
1049     if ( mpAttrSet.get() && mbSetModifyAtAttr )
1050         ((SwAttrSet*)mpAttrSet.get())->SetModifyAtAttr( 0 );
1051 }
1052 
Modify(const SfxPoolItem * pOldValue,const SfxPoolItem * pNewValue)1053 void SwCntntNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
1054 {
1055     sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
1056                     pNewValue ? pNewValue->Which() : 0 ;
1057 
1058     switch( nWhich )
1059     {
1060     case RES_OBJECTDYING :
1061         {
1062             SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject;
1063 
1064             // nicht umhaengen wenn dieses das oberste Format ist !!
1065             if( GetRegisteredIn() == pFmt )
1066             {
1067                 if( pFmt->GetRegisteredIn() )
1068                 {
1069                     // wenn Parent, dann im neuen Parent wieder anmelden
1070                     ((SwModify*)pFmt->GetRegisteredIn())->Add( this );
1071                     if ( GetpSwAttrSet() )
1072                         AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
1073                 }
1074                 else
1075                 {
1076                     // sonst auf jeden Fall beim sterbenden abmelden
1077                     ((SwModify*)GetRegisteredIn())->Remove( this );
1078                     if ( GetpSwAttrSet() )
1079                         AttrSetHandleHelper::SetParent( mpAttrSet, *this, 0, 0 );
1080                 }
1081             }
1082         }
1083         break;
1084 
1085 
1086     case RES_FMT_CHG:
1087         // falls mein Format Parent umgesetzt wird, dann melde ich
1088         // meinen Attrset beim Neuen an.
1089 
1090         // sein eigenes Modify ueberspringen !!
1091         if( GetpSwAttrSet() &&
1092             ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() )
1093         {
1094             // den Set an den neuen Parent haengen
1095             AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
1096         }
1097         break;
1098 //FEATURE::CONDCOLL
1099     case RES_CONDCOLL_CONDCHG:
1100         if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() &&
1101             &GetNodes() == &GetDoc()->GetNodes() )
1102         {
1103             ChkCondColl();
1104         }
1105         return ;    // nicht an die Basisklasse / Frames weitergeben
1106 //FEATURE::CONDCOLL
1107 
1108     case RES_ATTRSET_CHG:
1109         if( GetNodes().IsDocNodes() && IsTxtNode() )
1110         {
1111             if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState(
1112                 RES_CHRATR_HIDDEN, sal_False ) )
1113             {
1114                 ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1115             }
1116         }
1117         break;
1118 
1119     case RES_UPDATE_ATTR:
1120         if( GetNodes().IsDocNodes() && IsTxtNode() )
1121         {
1122             const sal_uInt16 nTmp = ((SwUpdateAttr*)pNewValue)->nWhichAttr;
1123             if ( RES_ATTRSET_CHG == nTmp )
1124             {
1125                 // anybody wants to do some optimization here?
1126                 ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1127             }
1128         }
1129         break;
1130     }
1131 
1132     NotifyClients( pOldValue, pNewValue );
1133 }
1134 
InvalidateNumRule()1135 sal_Bool SwCntntNode::InvalidateNumRule()
1136 {
1137     SwNumRule* pRule = 0;
1138     const SfxPoolItem* pItem;
1139     if( GetNodes().IsDocNodes() &&
1140         0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, sal_True )) &&
1141         ((SwNumRuleItem*)pItem)->GetValue().Len() &&
1142         0 != (pRule = GetDoc()->FindNumRulePtr(
1143                                 ((SwNumRuleItem*)pItem)->GetValue() ) ) )
1144     {
1145         pRule->SetInvalidRule( sal_True );
1146     }
1147     return 0 != pRule;
1148 }
1149 
getLayoutFrm(const SwRootFrm * _pRoot,const Point * pPoint,const SwPosition * pPos,const sal_Bool bCalcFrm) const1150 SwCntntFrm *SwCntntNode::getLayoutFrm( const SwRootFrm* _pRoot,
1151     const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm ) const
1152 {
1153     return (SwCntntFrm*) ::GetFrmOfModify( _pRoot, *(SwModify*)this, FRM_CNTNT,
1154                                             pPoint, pPos, bCalcFrm );
1155 }
1156 
FindLayoutRect(const sal_Bool bPrtArea,const Point * pPoint,const sal_Bool bCalcFrm) const1157 SwRect SwCntntNode::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint,
1158                                     const sal_Bool bCalcFrm ) const
1159 {
1160     SwRect aRet;
1161     SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( 0, *(SwModify*)this,
1162                                             FRM_CNTNT, pPoint, 0, bCalcFrm );
1163     if( pFrm )
1164         aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1165     return aRet;
1166 }
1167 
FindPageFrmRect(const sal_Bool bPrtArea,const Point * pPoint,const sal_Bool bCalcFrm) const1168 SwRect SwCntntNode::FindPageFrmRect( const sal_Bool bPrtArea, const Point* pPoint,
1169                                     const sal_Bool bCalcFrm ) const
1170 {
1171     SwRect aRet;
1172     SwFrm* pFrm = ::GetFrmOfModify( 0, *(SwModify*)this,
1173                                             FRM_CNTNT, pPoint, 0, bCalcFrm );
1174     if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() ))
1175         aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1176     return aRet;
1177 }
1178 
Len() const1179 xub_StrLen SwCntntNode::Len() const { return 0; }
1180 
1181 
1182 
ChgFmtColl(SwFmtColl * pNewColl)1183 SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl )
1184 {
1185     ASSERT( pNewColl, "Collectionpointer ist 0." );
1186     SwFmtColl *pOldColl = GetFmtColl();
1187 
1188     if( pNewColl != pOldColl )
1189     {
1190         pNewColl->Add( this );
1191 
1192         // setze den Parent von unseren Auto-Attributen auf die neue
1193         // Collection:
1194         if( GetpSwAttrSet() )
1195             AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl );
1196 
1197 //FEATURE::CONDCOLL
1198         // HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen
1199         //      neu ueberprueft werden!
1200         if( sal_True /*pNewColl */ )
1201         {
1202             SetCondFmtColl( 0 );
1203         }
1204 //FEATURE::CONDCOLL
1205 
1206         if( !IsModifyLocked() )
1207         {
1208             SwFmtChg aTmp1( pOldColl );
1209             SwFmtChg aTmp2( pNewColl );
1210             SwCntntNode::Modify( &aTmp1, &aTmp2 );
1211         }
1212     }
1213     if ( IsInCache() )
1214     {
1215         SwFrm::GetCache().Delete( this );
1216         SetInCache( sal_False );
1217     }
1218     return pOldColl;
1219 }
1220 
1221 
GoNext(SwIndex * pIdx,sal_uInt16 nMode) const1222 sal_Bool SwCntntNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const
1223 {
1224     sal_Bool bRet = sal_True;
1225     if( pIdx->GetIndex() < Len() )
1226     {
1227         if( !IsTxtNode() )
1228             (*pIdx)++;
1229         else
1230         {
1231             const SwTxtNode& rTNd = *GetTxtNode();
1232             xub_StrLen nPos = pIdx->GetIndex();
1233             if( pBreakIt->GetBreakIter().is() )
1234             {
1235                 sal_Int32 nDone = 0;
1236                 sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1237                                         CharacterIteratorMode::SKIPCELL :
1238                                         CharacterIteratorMode::SKIPCONTROLCHARACTER;
1239                 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetTxt(), nPos,
1240                                    pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1241                                    nItrMode, 1, nDone );
1242 
1243                 // Check if nPos is inside hidden text range:
1244                 if ( CRSR_SKIP_HIDDEN & nMode )
1245                 {
1246                     xub_StrLen nHiddenStart;
1247                     xub_StrLen nHiddenEnd;
1248                     SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1249                     if ( nHiddenStart != STRING_LEN && nHiddenStart != nPos )
1250                          nPos = nHiddenEnd;
1251                 }
1252 
1253                 if( 1 == nDone )
1254                     *pIdx = nPos;
1255                 else
1256                     bRet = sal_False;
1257             }
1258             else if( nPos < rTNd.GetTxt().Len() )
1259                 (*pIdx)++;
1260             else
1261                 bRet = sal_False;
1262         }
1263     }
1264     else
1265         bRet = sal_False;
1266     return bRet;
1267 }
1268 
1269 
GoPrevious(SwIndex * pIdx,sal_uInt16 nMode) const1270 sal_Bool SwCntntNode::GoPrevious(SwIndex * pIdx, sal_uInt16 nMode ) const
1271 {
1272     sal_Bool bRet = sal_True;
1273     if( pIdx->GetIndex() > 0 )
1274     {
1275         if( !IsTxtNode() )
1276             (*pIdx)--;
1277         else
1278         {
1279             const SwTxtNode& rTNd = *GetTxtNode();
1280             xub_StrLen nPos = pIdx->GetIndex();
1281             if( pBreakIt->GetBreakIter().is() )
1282             {
1283                 sal_Int32 nDone = 0;
1284                 sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1285                                         CharacterIteratorMode::SKIPCELL :
1286                                         CharacterIteratorMode::SKIPCONTROLCHARACTER;
1287                 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetTxt(), nPos,
1288                                    pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1289                                    nItrMode, 1, nDone );
1290 
1291                 // Check if nPos is inside hidden text range:
1292                 if ( CRSR_SKIP_HIDDEN & nMode )
1293                 {
1294                     xub_StrLen nHiddenStart;
1295                     xub_StrLen nHiddenEnd;
1296                     SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1297                     if ( nHiddenStart != STRING_LEN  )
1298                          nPos = nHiddenStart;
1299                 }
1300 
1301                 if( 1 == nDone )
1302                     *pIdx = nPos;
1303                 else
1304                     bRet = sal_False;
1305             }
1306             else if( nPos )
1307                 (*pIdx)--;
1308             else
1309                 bRet = sal_False;
1310         }
1311     }
1312     else
1313         bRet = sal_False;
1314     return bRet;
1315 }
1316 
1317 
1318 /*
1319  * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
1320  * Dokument. Die erzeugten Contentframes werden in das entsprechende
1321  * Layout gehaengt.
1322  */
1323 
1324 
MakeFrms(SwCntntNode & rNode)1325 void SwCntntNode::MakeFrms( SwCntntNode& rNode )
1326 {
1327     ASSERT( &rNode != this,
1328             "Kein Contentnode oder Copy-Node und neuer Node identisch." );
1329 
1330     if( !GetDepends() || &rNode == this )   // gibt es ueberhaupt Frames ??
1331         return;
1332 
1333     SwFrm *pFrm, *pNew;
1334     SwLayoutFrm *pUpper;
1335     // Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ??
1336     ASSERT( FindTableNode() == rNode.FindTableNode(), "Table confusion" )
1337 
1338     SwNode2Layout aNode2Layout( *this, rNode.GetIndex() );
1339 
1340     while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) )
1341     {
1342         pNew = rNode.MakeFrm( pUpper );
1343         pNew->Paste( pUpper, pFrm );
1344         // --> OD 2005-12-01 #i27138#
1345         // notify accessibility paragraphs objects about changed
1346         // CONTENT_FLOWS_FROM/_TO relation.
1347         // Relation CONTENT_FLOWS_FROM for next paragraph will change
1348         // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1349         if ( pNew->IsTxtFrm() )
1350         {
1351             ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
1352             if ( pViewShell && pViewShell->GetLayout() &&
1353                  pViewShell->GetLayout()->IsAnyShellAccessible() )
1354             {
1355                 pViewShell->InvalidateAccessibleParaFlowRelation(
1356                             dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
1357                             dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) );
1358             }
1359         }
1360         // <--
1361     }
1362 }
1363 
1364 /*
1365  * Methode loescht fuer den Node alle Ansichten vom
1366  * Dokument. Die Contentframes werden aus dem entsprechenden
1367  * Layout ausgehaengt.
1368  */
1369 
1370 
1371 //Solution:Add a input param to identify if the acc table should be disposed.
1372 //add a flag(bNeedDel) to indicate whether to del corresponding frm even in doc loading process,
1373 //void SwCntntNode::DelFrms()
DelFrms(sal_Bool,sal_Bool bIsDisposeAccTable)1374 void SwCntntNode::DelFrms( sal_Bool /* bNeedDel */, sal_Bool bIsDisposeAccTable )
1375 {
1376     if( !GetDepends() )
1377         return;
1378 
1379     SwClientIter aIter( *this );
1380     SwCntntFrm *pFrm;
1381 
1382     for( pFrm = (SwCntntFrm*)aIter.First( TYPE(SwCntntFrm)); pFrm;
1383          pFrm = (SwCntntFrm*)aIter.Next() )
1384     {
1385         // --> OD 2005-12-01 #i27138#
1386         // notify accessibility paragraphs objects about changed
1387         // CONTENT_FLOWS_FROM/_TO relation.
1388         // Relation CONTENT_FLOWS_FROM for current next paragraph will change
1389         // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
1390         if ( pFrm->IsTxtFrm() )
1391         {
1392             ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1393             if ( pViewShell && pViewShell->GetLayout() &&
1394                  pViewShell->GetLayout()->IsAnyShellAccessible() )
1395             {
1396                 pViewShell->InvalidateAccessibleParaFlowRelation(
1397                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1398                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1399             }
1400         }
1401         // <--
1402         if( pFrm->HasFollow() )
1403             pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() );
1404         if( pFrm->IsFollow() )
1405         {
1406             SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster();
1407             pMaster->SetFollow( pFrm->GetFollow() );
1408             pFrm->_SetIsFollow( sal_False );
1409         }
1410         pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt.
1411                                 //Andernfalls kann es sein, dass ein Follow
1412                                 //vor seinem Master zerstoert wird, der Master
1413                                 //greift dann ueber den ungueltigen
1414                                 //Follow-Pointer auf fremdes Memory zu.
1415                                 //Die Kette darf hier zerknauscht werden, weil
1416                                 //sowieso alle zerstoert werden.
1417         if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() &&
1418             !pFrm->GetIndPrev() )
1419         {
1420             SwFtnFrm *pFtn = pFrm->FindFtnFrm();
1421             ASSERT( pFtn, "You promised a FtnFrm?" );
1422             SwCntntFrm* pCFrm;
1423             if( !pFtn->GetFollow() && !pFtn->GetMaster() &&
1424                 0 != ( pCFrm = pFtn->GetRefFromAttr()) && pCFrm->IsFollow() )
1425             {
1426                 ASSERT( pCFrm->IsTxtFrm(), "NoTxtFrm has Footnote?" );
1427                 ((SwTxtFrm*)pCFrm->FindMaster())->Prepare( PREP_FTN_GONE );
1428             }
1429         }
1430         //Solution:Set acc table dispose state
1431         pFrm->SetAccTableDispose( bIsDisposeAccTable );
1432         //End Added
1433         pFrm->Cut();
1434         //Solution:Set acc table dispose state to default value
1435         pFrm->SetAccTableDispose( sal_True );
1436         delete pFrm;
1437     }
1438     if( IsTxtNode() )
1439     {
1440         ((SwTxtNode*)this)->SetWrong( NULL );
1441         ((SwTxtNode*)this)->SetWrongDirty( true );
1442 
1443         ((SwTxtNode*)this)->SetGrammarCheck( NULL );
1444         ((SwTxtNode*)this)->SetGrammarCheckDirty( true );
1445         // SMARTTAGS
1446         ((SwTxtNode*)this)->SetSmartTags( NULL );
1447         ((SwTxtNode*)this)->SetSmartTagDirty( true );
1448 
1449         ((SwTxtNode*)this)->SetWordCountDirty( true );
1450         ((SwTxtNode*)this)->SetAutoCompleteWordDirty( true );
1451     }
1452 }
1453 
1454 
JoinNext()1455 SwCntntNode *SwCntntNode::JoinNext()
1456 {
1457     return this;
1458 }
1459 
1460 
JoinPrev()1461 SwCntntNode *SwCntntNode::JoinPrev()
1462 {
1463     return this;
1464 }
1465 
1466 
1467 
1468     // erfrage vom Modify Informationen
GetInfo(SfxPoolItem & rInfo) const1469 sal_Bool SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const
1470 {
1471     switch( rInfo.Which() )
1472     {
1473     case RES_AUTOFMT_DOCNODE:
1474         if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
1475         {
1476             ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this;
1477             return sal_False;
1478         }
1479         break;
1480     // --> OD 2008-02-19 #refactorlists#
1481 //    case RES_GETNUMNODES:
1482 //        // #111955# only numbered nodes in rInfo
1483 //        if( IsTxtNode())
1484 //        {
1485 //            SwTxtNode * pTxtNode = (SwTxtNode*)this;
1486 //            pItem = (SwNumRuleItem*)GetNoCondAttr(RES_PARATR_NUMRULE, sal_True );
1487 
1488 //            if (0 != pItem  &&
1489 //                pItem->GetValue().Len() &&
1490 //                pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() &&
1491 //                GetNodes().IsDocNodes())
1492 //            {
1493 //                ((SwNumRuleInfo&)rInfo).AddNode( *pTxtNode );
1494 //            }
1495 //        }
1496 
1497 //        return sal_True;
1498     // <--
1499 
1500     case RES_FINDNEARESTNODE:
1501         if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() )
1502             ((SwFindNearestNode&)rInfo).CheckNode( *this );
1503         return sal_True;
1504 
1505     case RES_CONTENT_VISIBLE:
1506         {
1507             ((SwPtrMsgPoolItem&)rInfo).pObject =
1508                 SwIterator<SwFrm,SwCntntNode>::FirstElement(*this);
1509         }
1510         return sal_False;
1511     }
1512 
1513     return SwModify::GetInfo( rInfo );
1514 }
1515 
1516 
1517     // setze ein Attribut
SetAttr(const SfxPoolItem & rAttr)1518 sal_Bool SwCntntNode::SetAttr(const SfxPoolItem& rAttr )
1519 {
1520     if( !GetpSwAttrSet() )            // lasse von den entsprechenden Nodes die
1521         NewAttrSet( GetDoc()->GetAttrPool() );      // AttrSets anlegen
1522 
1523     ASSERT( GetpSwAttrSet(), "warum wurde kein AttrSet angelegt?" );
1524 
1525     if ( IsInCache() )
1526     {
1527         SwFrm::GetCache().Delete( this );
1528         SetInCache( sal_False );
1529     }
1530 
1531     sal_Bool bRet = sal_False;
1532     // wenn Modify gelockt ist, werden keine Modifies verschickt
1533     if( IsModifyLocked() ||
1534         ( !GetDepends() &&  RES_PARATR_NUMRULE != rAttr.Which() ))
1535     {
1536         bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr );
1537     }
1538     else
1539     {
1540         SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1541                   aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1542         if( 0 != ( bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ) ))
1543         {
1544             SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1545             SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1546             ModifyNotification( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
1547         }
1548     }
1549     return bRet;
1550 }
1551 #include <svl/itemiter.hxx>
1552 
SetAttr(const SfxItemSet & rSet)1553 sal_Bool SwCntntNode::SetAttr( const SfxItemSet& rSet )
1554 {
1555     if ( IsInCache() )
1556     {
1557         SwFrm::GetCache().Delete( this );
1558         SetInCache( sal_False );
1559     }
1560 
1561     const SfxPoolItem* pFnd = 0;
1562     if( SFX_ITEM_SET == rSet.GetItemState( RES_AUTO_STYLE, sal_False, &pFnd ) )
1563     {
1564         ASSERT( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" );
1565         const SwFmtAutoFmt* pTmp = static_cast<const SwFmtAutoFmt*>(pFnd);
1566 
1567         // If there already is an attribute set (usually containing a numbering
1568         // item), we have to merge the attribute of the new set into the old set:
1569         bool bSetParent = true;
1570         if ( GetpSwAttrSet() )
1571         {
1572             bSetParent = false;
1573             AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() );
1574         }
1575         else
1576         {
1577             mpAttrSet = pTmp->GetStyleHandle();
1578         }
1579 
1580         if ( bSetParent )
1581         {
1582             // If the content node has a conditional style, we have to set the
1583             // string item containing the correct conditional style name (the
1584             // style name property has already been set during the import!)
1585             // In case we do not have a conditional style, we make use of the
1586             // fact that nobody else uses the attribute set behind the handle.
1587             // FME 2007-07-10 #i78124# If autostyle does not have a parent,
1588             // the string is empty.
1589             const SfxPoolItem* pNameItem = 0;
1590             if ( 0 != GetCondFmtColl() ||
1591                  SFX_ITEM_SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, sal_False, &pNameItem ) ||
1592                  0 == static_cast<const SfxStringItem*>(pNameItem)->GetValue().Len() )
1593                 AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1594             else
1595                 const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFmtColl()->GetAttrSet() );
1596         }
1597 
1598         return sal_True;
1599     }
1600 
1601     if( !GetpSwAttrSet() )            // lasse von den entsprechenden Nodes die
1602         NewAttrSet( GetDoc()->GetAttrPool() );      // AttrSets anlegen
1603 
1604     sal_Bool bRet = sal_False;
1605     // wenn Modify gelockt ist, werden keine Modifies verschickt
1606     if ( IsModifyLocked() ||
1607          ( !GetDepends() &&
1608            SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, sal_False ) ) )
1609     {
1610         // einige Sonderbehandlungen fuer Attribute
1611         bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rSet );
1612     }
1613     else
1614     {
1615         SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1616                   aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1617         if( 0 != (bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew )) )
1618         {
1619             // einige Sonderbehandlungen fuer Attribute
1620             SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1621             SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1622             ModifyNotification( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
1623         }
1624     }
1625     return bRet;
1626 }
1627 
1628 // Nimmt den Hint mit nWhich aus dem Delta-Array
1629 
1630 
ResetAttr(sal_uInt16 nWhich1,sal_uInt16 nWhich2)1631 sal_Bool SwCntntNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
1632 {
1633     if( !GetpSwAttrSet() )
1634         return sal_False;
1635 
1636     if ( IsInCache() )
1637     {
1638         SwFrm::GetCache().Delete( this );
1639         SetInCache( sal_False );
1640     }
1641 
1642     // wenn Modify gelockt ist, werden keine Modifies verschickt
1643     if( IsModifyLocked() )
1644     {
1645         sal_uInt16 nDel = 0;
1646         if ( !nWhich2 || nWhich2 < nWhich1 )
1647         {
1648             std::vector<sal_uInt16> aClearWhichIds;
1649             aClearWhichIds.push_back( nWhich1 );
1650             nDel = ClearItemsFromAttrSet( aClearWhichIds );
1651         }
1652         else
1653             nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, 0, 0 );
1654 
1655         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1656             mpAttrSet.reset();//DELETEZ( mpAttrSet );
1657         return 0 != nDel;
1658     }
1659 
1660     // sollte kein gueltiger Bereich definiert sein ?
1661     if( !nWhich2 || nWhich2 < nWhich1 )
1662         nWhich2 = nWhich1;      // dann setze auf 1. Id, nur dieses Item
1663 
1664     SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1665               aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1666     sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew );
1667 
1668     if( bRet )
1669     {
1670         SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1671         SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1672         ModifyNotification( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
1673 
1674         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1675             mpAttrSet.reset();//DELETEZ( mpAttrSet );
1676     }
1677     return bRet;
1678 }
ResetAttr(const SvUShorts & rWhichArr)1679 sal_Bool SwCntntNode::ResetAttr( const SvUShorts& rWhichArr )
1680 {
1681     if( !GetpSwAttrSet() )
1682         return sal_False;
1683 
1684     if ( IsInCache() )
1685     {
1686         SwFrm::GetCache().Delete( this );
1687         SetInCache( sal_False );
1688     }
1689 
1690     // wenn Modify gelockt ist, werden keine Modifies verschickt
1691     sal_uInt16 nDel = 0;
1692     if( IsModifyLocked() )
1693     {
1694         std::vector<sal_uInt16> aClearWhichIds;
1695         for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
1696             aClearWhichIds.push_back( rWhichArr[ n ] );
1697 
1698         nDel = ClearItemsFromAttrSet( aClearWhichIds );
1699     }
1700     else
1701     {
1702         SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1703                   aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1704 
1705         for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
1706             if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, rWhichArr[ n ], &aOld, &aNew ))
1707                 ++nDel;
1708 
1709         if( nDel )
1710         {
1711             SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1712             SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1713             ModifyNotification( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
1714         }
1715     }
1716     if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1717         mpAttrSet.reset();//DELETEZ( mpAttrSet );
1718     return 0 != nDel ;
1719 }
1720 
1721 
ResetAllAttr()1722 sal_uInt16 SwCntntNode::ResetAllAttr()
1723 {
1724     if( !GetpSwAttrSet() )
1725         return 0;
1726 
1727     if ( IsInCache() )
1728     {
1729         SwFrm::GetCache().Delete( this );
1730         SetInCache( sal_False );
1731     }
1732 
1733     // wenn Modify gelockt ist, werden keine Modifies verschickt
1734     if( IsModifyLocked() )
1735     {
1736         std::vector<sal_uInt16> aClearWhichIds;
1737         aClearWhichIds.push_back(0);
1738         sal_uInt16 nDel = ClearItemsFromAttrSet( aClearWhichIds );
1739         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1740             mpAttrSet.reset();            // DELETEZ( mpAttrSet );
1741         return nDel;
1742     }
1743 
1744     SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1745               aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1746     sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew );
1747 
1748     if( bRet )
1749     {
1750         SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1751         SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1752         ModifyNotification( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
1753 
1754         if( !GetpSwAttrSet()->Count() )   // leer, dann loeschen
1755             mpAttrSet.reset();//DELETEZ( mpAttrSet );
1756     }
1757     return aNew.Count();
1758 }
1759 
1760 
GetAttr(SfxItemSet & rSet,sal_Bool bInParent) const1761 sal_Bool SwCntntNode::GetAttr( SfxItemSet& rSet, sal_Bool bInParent ) const
1762 {
1763     if( rSet.Count() )
1764         rSet.ClearItem();
1765 
1766     const SwAttrSet& rAttrSet = GetSwAttrSet();
1767     if( bInParent )
1768         return rSet.Set( rAttrSet, sal_True ) ? sal_True : sal_False;
1769 
1770     rSet.Put( rAttrSet );
1771     return rSet.Count() ? sal_True : sal_False;
1772 }
1773 
ClearItemsFromAttrSet(const std::vector<sal_uInt16> & rWhichIds)1774 sal_uInt16 SwCntntNode::ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds )
1775 {
1776     sal_uInt16 nRet = 0;
1777     if ( 0 == rWhichIds.size() )
1778         return nRet;
1779 
1780     ASSERT( GetpSwAttrSet(), "no item set" )
1781     SwAttrSet aNewAttrSet( *GetpSwAttrSet() );
1782     for ( std::vector<sal_uInt16>::const_iterator aIter = rWhichIds.begin();
1783           aIter != rWhichIds.end();
1784           ++aIter )
1785     {
1786         nRet = nRet + aNewAttrSet.ClearItem( *aIter );
1787     }
1788     if ( nRet )
1789         AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet );
1790 
1791     return nRet;
1792 }
1793 
GetNoCondAttr(sal_uInt16 nWhich,sal_Bool bInParents) const1794 const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich,
1795                                                 sal_Bool bInParents ) const
1796 {
1797     const SfxPoolItem* pFnd = 0;
1798     if( pCondColl && pCondColl->GetRegisteredIn() )
1799     {
1800         if( !GetpSwAttrSet() || ( SFX_ITEM_SET != GetpSwAttrSet()->GetItemState(
1801                     nWhich, sal_False, &pFnd ) && bInParents ))
1802             ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd );
1803     }
1804     // --> OD 2005-10-25 #126347# - undo change of issue #i51029#
1805     // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns
1806     //       the attribute set of the paragraph style, which is valid for the
1807     //       content node - see file <node.hxx>
1808     else
1809     // <--
1810     {
1811         GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd );
1812     }
1813     return pFnd;
1814 }
1815 
1816     // koennen 2 Nodes zusammengefasst werden ?
1817     // in pIdx kann die 2. Position returnt werden.
CanJoinNext(SwNodeIndex * pIdx) const1818 int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
1819 {
1820     const SwNodes& rNds = GetNodes();
1821     sal_uInt8 nNdType = GetNodeType();
1822     SwNodeIndex aIdx( *this, 1 );
1823 
1824     const SwNode* pNd = this;
1825     while( aIdx < rNds.Count()-1 &&
1826         (( pNd = &aIdx.GetNode())->IsSectionNode() ||
1827             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1828         aIdx++;
1829 
1830     if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
1831         return sal_False;
1832     if( IsTxtNode() )
1833     {   // Do not merge strings if the result exceeds the allowed string length
1834         const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this);
1835         sal_uInt64 nSum = pTxtNd->GetTxt().Len();
1836         pTxtNd = static_cast<const SwTxtNode*>(pNd);
1837         nSum += pTxtNd->GetTxt().Len();
1838         if( nSum > STRING_LEN )
1839             return sal_False;
1840     }
1841     if( pIdx )
1842         *pIdx = aIdx;
1843     return sal_True;
1844 }
1845 
1846 
1847     // koennen 2 Nodes zusammengefasst werden ?
1848     // in pIdx kann die 2. Position returnt werden.
CanJoinPrev(SwNodeIndex * pIdx) const1849 int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
1850 {
1851     sal_uInt8 nNdType = GetNodeType();
1852     SwNodeIndex aIdx( *this, -1 );
1853 
1854     const SwNode* pNd = this;
1855     while( aIdx.GetIndex() &&
1856         (( pNd = &aIdx.GetNode())->IsSectionNode() ||
1857             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1858         aIdx--;
1859 
1860     if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
1861         return sal_False;
1862     if( pIdx )
1863         *pIdx = aIdx;
1864     return sal_True;
1865 }
1866 
1867 
1868 //FEATURE::CONDCOLL
1869 
1870 
SetCondFmtColl(SwFmtColl * pColl)1871 void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl )
1872 {
1873     if( (!pColl && pCondColl) || ( pColl && !pCondColl ) ||
1874         ( pColl && pColl != pCondColl->GetRegisteredIn() ) )
1875     {
1876         SwFmtColl* pOldColl = GetCondFmtColl();
1877         delete pCondColl;
1878         if( pColl )
1879             pCondColl = new SwDepend( this, pColl );
1880         else
1881             pCondColl = 0;
1882 
1883         if( GetpSwAttrSet() )
1884         {
1885             AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1886         }
1887 
1888         if( !IsModifyLocked() )
1889         {
1890             SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() );
1891             SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() );
1892             NotifyClients( &aTmp1, &aTmp2 );
1893         }
1894         if( IsInCache() )
1895         {
1896             SwFrm::GetCache().Delete( this );
1897             SetInCache( sal_False );
1898         }
1899     }
1900 }
1901 
1902 
IsAnyCondition(SwCollCondition & rTmp) const1903 sal_Bool SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const
1904 {
1905     const SwNodes& rNds = GetNodes();
1906     {
1907         int nCond = 0;
1908         const SwStartNode* pSttNd = StartOfSectionNode();
1909         while( pSttNd )
1910         {
1911             switch( pSttNd->GetNodeType() )
1912             {
1913             case ND_TABLENODE:      nCond = PARA_IN_TABLEBODY; break;
1914             case ND_SECTIONNODE:    nCond = PARA_IN_SECTION; break;
1915 
1916             default:
1917                 switch( pSttNd->GetStartNodeType() )
1918                 {
1919                 case SwTableBoxStartNode:
1920                     {
1921                         nCond = PARA_IN_TABLEBODY;
1922                         const SwTableNode* pTblNd = pSttNd->FindTableNode();
1923                         const SwTableBox* pBox;
1924                         if( pTblNd && 0 != ( pBox = pTblNd->GetTable().
1925                             GetTblBox( pSttNd->GetIndex() ) ) && pBox &&
1926                             pBox->IsInHeadline( &pTblNd->GetTable() ) )
1927                             nCond = PARA_IN_TABLEHEAD;
1928                     }
1929                     break;
1930                 case SwFlyStartNode:        nCond = PARA_IN_FRAME; break;
1931                 case SwFootnoteStartNode:
1932                     {
1933                         nCond = PARA_IN_FOOTENOTE;
1934                         const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs();
1935                         const SwTxtFtn* pTxtFtn;
1936                         const SwNode* pSrchNd = pSttNd;
1937 
1938                         for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n )
1939                             if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
1940                                 pSrchNd == &pTxtFtn->GetStartNode()->GetNode() )
1941                             {
1942                                 if( pTxtFtn->GetFtn().IsEndNote() )
1943                                     nCond = PARA_IN_ENDNOTE;
1944                                 break;
1945                             }
1946                     }
1947                     break;
1948                 case SwHeaderStartNode:     nCond = PARA_IN_HEADER; break;
1949                 case SwFooterStartNode:     nCond = PARA_IN_FOOTER; break;
1950                 case SwNormalStartNode:     break;
1951                 }
1952             }
1953 
1954             if( nCond )
1955             {
1956                 rTmp.SetCondition( (Master_CollConditions)nCond, 0 );
1957                 return sal_True;
1958             }
1959             pSttNd = pSttNd->GetIndex()
1960                         ? pSttNd->StartOfSectionNode()
1961                         : 0;
1962         }
1963     }
1964 
1965     {
1966         sal_uInt16 nPos;
1967         const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1968         if( rOutlNds.Count() )
1969         {
1970             if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos )
1971                 --nPos;
1972             if( nPos < rOutlNds.Count() &&
1973                 rOutlNds[ nPos ]->GetIndex() < GetIndex() )
1974             {
1975                 SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode();
1976 
1977                 if( pOutlNd->IsOutline())
1978                 {
1979                     rTmp.SetCondition( PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 );
1980                     return sal_True;
1981                 }
1982             }
1983         }
1984     }
1985 
1986     return sal_False;
1987 }
1988 
1989 
ChkCondColl()1990 void SwCntntNode::ChkCondColl()
1991 {
1992     // zur Sicherheit abfragen
1993     if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() )
1994     {
1995         SwCollCondition aTmp( 0, 0, 0 );
1996         const SwCollCondition* pCColl;
1997 
1998         bool bDone = false;
1999 
2000         if( IsAnyCondition( aTmp ))
2001         {
2002             pCColl = static_cast<SwConditionTxtFmtColl*>(GetFmtColl())
2003                 ->HasCondition( aTmp );
2004 
2005             if (pCColl)
2006             {
2007                 SetCondFmtColl( pCColl->GetTxtFmtColl() );
2008                 bDone = true;
2009             }
2010         }
2011 
2012         if (!bDone)
2013         {
2014             if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule())
2015             {
2016                 // steht in einer Numerierung
2017                 // welcher Level?
2018                 aTmp.SetCondition( PARA_IN_LIST,
2019                                 ((SwTxtNode*)this)->GetActualListLevel() );
2020                 pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())->
2021                                 HasCondition( aTmp );
2022             }
2023             else
2024                 pCColl = 0;
2025 
2026             if( pCColl )
2027                 SetCondFmtColl( pCColl->GetTxtFmtColl() );
2028             else if( pCondColl )
2029                 SetCondFmtColl( 0 );
2030         }
2031     }
2032 }
2033 
2034 // --> OD 2005-02-21 #i42921#
GetTextDirection(const SwPosition & rPos,const Point * pPt) const2035 short SwCntntNode::GetTextDirection( const SwPosition& rPos,
2036                                      const Point* pPt ) const
2037 {
2038     short nRet = -1;
2039 
2040     Point aPt;
2041     if( pPt )
2042         aPt = *pPt;
2043 
2044     // --> OD 2007-01-10 #i72024#
2045     // No format of the frame, because this can cause recursive layout actions
2046     SwFrm* pFrm = getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, &rPos, sal_False );
2047     // <--
2048 
2049     if ( pFrm )
2050     {
2051         if ( pFrm->IsVertical() )
2052         {
2053             if ( pFrm->IsRightToLeft() )
2054                 nRet = FRMDIR_VERT_TOP_LEFT;
2055             else
2056                 nRet = FRMDIR_VERT_TOP_RIGHT;
2057         }
2058         else
2059         {
2060             if ( pFrm->IsRightToLeft() )
2061                 nRet = FRMDIR_HORI_RIGHT_TOP;
2062             else
2063                 nRet = FRMDIR_HORI_LEFT_TOP;
2064         }
2065     }
2066 
2067 
2068     return nRet;
2069 }
2070 // <--
2071 
CreateOLENodesArray(const SwFmtColl & rColl,bool bOnlyWithInvalidSize)2072 SwOLENodes* SwCntntNode::CreateOLENodesArray( const SwFmtColl& rColl, bool bOnlyWithInvalidSize )
2073 {
2074     SwOLENodes *pNodes = 0;
2075     SwIterator<SwCntntNode,SwFmtColl> aIter( rColl );
2076     for( SwCntntNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
2077     {
2078         SwOLENode *pONd = pNd->GetOLENode();
2079         if ( pONd && (!bOnlyWithInvalidSize || pONd->IsOLESizeInvalid()) )
2080         {
2081             if ( !pNodes  )
2082                 pNodes = new SwOLENodes;
2083             pNodes->Insert( pONd, pNodes->Count() );
2084         }
2085     }
2086 
2087     return pNodes;
2088 }
2089 
2090 //FEATURE::CONDCOLL
2091 // Metoden aus Node.hxx - erst hier ist der TxtNode bekannt !!
2092 // os: nur fuer ICC, da der zum optimieren zu dumm ist
2093 #ifdef ICC
GetTxtNode()2094 SwTxtNode   *SwNode::GetTxtNode()
2095 {
2096      return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0;
2097 }
GetTxtNode() const2098 const SwTxtNode   *SwNode::GetTxtNode() const
2099 {
2100      return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0;
2101 }
2102 #endif
2103 
2104 /*
2105  * Document Interface Access
2106  */
getIDocumentSettingAccess() const2107 const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return GetDoc(); }
getIDocumentDeviceAccess() const2108 const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return GetDoc(); }
getIDocumentMarkAccess() const2109 const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc()->getIDocumentMarkAccess(); }
getIDocumentRedlineAccess() const2110 const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return GetDoc(); }
getIDocumentStylePoolAccess() const2111 const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); }
getIDocumentLineNumberAccess() const2112 const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); }
getIDocumentDrawModelAccess() const2113 const IDocumentDrawModelAccess* SwNode::getIDocumentDrawModelAccess() const { return GetDoc(); }
getIDocumentLayoutAccess() const2114 const IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() const { return GetDoc(); }
getIDocumentLayoutAccess()2115 IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() { return GetDoc(); }
getIDocumentLinksAdministration() const2116 const IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() const { return GetDoc(); }
getIDocumentLinksAdministration()2117 IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() { return GetDoc(); }
getIDocumentFieldsAccess() const2118 const IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() const { return GetDoc(); }
getIDocumentFieldsAccess()2119 IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() { return GetDoc(); }
getIDocumentContentOperations()2120 IDocumentContentOperations* SwNode::getIDocumentContentOperations() { return GetDoc(); }
getIDocumentStyleAccess()2121 IStyleAccess& SwNode::getIDocumentStyleAccess() { return GetDoc()->GetIStyleAccess(); }
2122 // --> OD 2007-10-31 #i83479#
getIDocumentListItems()2123 IDocumentListItems& SwNode::getIDocumentListItems()
2124 {
2125     return *GetDoc();
2126 }
2127 // <--
2128 
IsInRedlines() const2129 sal_Bool SwNode::IsInRedlines() const
2130 {
2131     const SwDoc * pDoc = GetDoc();
2132     sal_Bool bResult = sal_False;
2133 
2134     if (pDoc != NULL)
2135         bResult = pDoc->IsInRedlines(*this);
2136 
2137     return bResult;
2138 }
2139