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