1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ndsect.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <svx/linkmgr.hxx>
37 #include <svtools/itemiter.hxx>
38 #include <tools/resid.hxx>
39 #include <fmtcntnt.hxx>
40 #include <fmtanchr.hxx>
42 #include <fmtclds.hxx>
44 #include <rootfrm.hxx>
47 #include <section.hxx>
51 #include <swtable.hxx>
54 #include <frmtool.hxx>
57 #include <redline.hxx>
58 #include <sectfrm.hxx>
59 #include <pagefrm.hxx>
61 #include <node2lay.hxx>
63 #include <fmtftntx.hxx>
65 #include <comcore.hrc>
67 // --> OD 2005-12-01 #i27138#
73 // OD 04.11.2003 #i21457# - new implementation of local method <lcl_IsInSameTblBox(..)>.
74 // Method now determines the previous/next on its own. Thus, it can be controlled,
75 // for which previous/next is checked, if it's visible.
76 bool lcl_IsInSameTblBox( SwNodes
& _rNds
,
80 const SwTableNode
* pTblNd
= _rNd
.FindTableNode();
86 // determine index to be checked. Its assumed that a previous/next exist.
87 SwNodeIndex
aChkIdx( _rNd
);
89 // determine index of previous/next - skip hidden ones, which are
91 // If found one is before/after table, this one isn't in the same
92 // table box as <_rNd>.
97 ? !_rNds
.GoPrevSection( &aChkIdx
, FALSE
, FALSE
)
98 : !_rNds
.GoNextSection( &aChkIdx
, FALSE
, FALSE
) )
100 ASSERT( false, "<lcl_IsInSameTblBox(..)> - no previous/next!" );
105 if ( aChkIdx
< pTblNd
->GetIndex() ||
106 aChkIdx
> pTblNd
->EndOfSectionNode()->GetIndex() )
112 // check, if found one isn't inside a hidden section, which
113 // is also inside the table.
114 SwSectionNode
* pSectNd
= aChkIdx
.GetNode().FindSectionNode();
116 pSectNd
->GetIndex() < pTblNd
->GetIndex() ||
117 !pSectNd
->GetSection().IsHiddenFlag() )
126 // dann suche den StartNode der Box
127 const SwTableSortBoxes
& rSortBoxes
= pTblNd
->GetTable().GetTabSortBoxes();
128 ULONG nIdx
= _rNd
.GetIndex();
129 for( USHORT n
= 0; n
< rSortBoxes
.Count(); ++n
)
131 const SwStartNode
* pNd
= rSortBoxes
[ n
]->GetSttNd();
132 if ( pNd
->GetIndex() < nIdx
&& nIdx
< pNd
->EndOfSectionIndex() )
134 // dann muss der andere Index in derselben Section liegen
135 nIdx
= aChkIdx
.GetIndex();
136 return pNd
->GetIndex() < nIdx
&& nIdx
< pNd
->EndOfSectionIndex();
143 void lcl_CheckEmptyLayFrm( SwNodes
& rNds
, SwSection
& rSect
,
144 const SwNode
& rStt
, const SwNode
& rEnd
)
146 SwNodeIndex
aIdx( rStt
);
147 if( !rNds
.GoPrevSection( &aIdx
, TRUE
, FALSE
) ||
148 !CheckNodesRange( rStt
, aIdx
, TRUE
) ||
149 // OD 04.11.2003 #i21457#
150 !lcl_IsInSameTblBox( rNds
, rStt
, true ))
153 if( !rNds
.GoNextSection( &aIdx
, TRUE
, FALSE
) ||
154 !CheckNodesRange( rEnd
, aIdx
, TRUE
) ||
155 // OD 04.11.2003 #i21457#
156 !lcl_IsInSameTblBox( rNds
, rEnd
, false ))
157 rSect
.SetHidden( FALSE
);
161 SwSection
* SwDoc::InsertSwSection( const SwPaM
& rRange
, const SwSection
& rNew
,
162 const SfxItemSet
* pAttr
, bool bUpdate
)
164 const SwNode
* pPrvNd
= 0;
165 USHORT nRegionRet
= 0;
166 if( rRange
.HasMark() &&
167 0 == ( nRegionRet
= IsInsRegionAvailable( rRange
, &pPrvNd
) ))
169 ASSERT( !this, "Selection ueber verschiedene Sections" );
173 // Teste ob das gesamte Dokument versteckt werden soll,
174 // koennen wir zur Zeit nicht !!!!
175 if( rNew
.IsHidden() && rRange
.HasMark() )
177 const SwPosition
*pStt
= rRange
.Start(), *pEnd
= rRange
.End();
178 if( !pStt
->nContent
.GetIndex() &&
179 pEnd
->nNode
.GetNode().GetCntntNode()->Len() ==
180 pEnd
->nContent
.GetIndex() )
182 ::lcl_CheckEmptyLayFrm( GetNodes(), const_cast<SwSection
&>(rNew
),
183 pStt
->nNode
.GetNode(),
184 pEnd
->nNode
.GetNode() );
188 SwUndoInsSection
* pUndoInsSect
= 0;
192 pUndoInsSect
= new SwUndoInsSection( rRange
, rNew
, pAttr
);
193 AppendUndo( pUndoInsSect
);
197 SwSectionFmt
* const pFmt
= MakeSectionFmt( 0 );
200 pFmt
->SetFmtAttr( *pAttr
);
203 SwSectionNode
* pNewSectNode
= 0;
205 RedlineMode_t eOld
= GetRedlineMode();
206 SetRedlineMode_intern( (RedlineMode_t
)((eOld
& ~nsRedlineMode_t::REDLINE_SHOW_MASK
) | nsRedlineMode_t::REDLINE_IGNORE
));
208 if( rRange
.HasMark() )
210 SwPosition
*pSttPos
= (SwPosition
*)rRange
.Start(),
211 *pEndPos
= (SwPosition
*)rRange
.End();
212 if( pPrvNd
&& 3 == nRegionRet
)
214 ASSERT( pPrvNd
, "der SectionNode fehlt" );
215 SwNodeIndex
aStt( pSttPos
->nNode
), aEnd( pEndPos
->nNode
, +1 );
216 while( pPrvNd
!= aStt
.GetNode().StartOfSectionNode() )
218 while( pPrvNd
!= aEnd
.GetNode().StartOfSectionNode() )
221 --aEnd
; // im InsertSection ist Ende inclusive
222 pNewSectNode
= GetNodes().InsertSection( aStt
, *pFmt
, rNew
, &aEnd
);
228 if( !( pPrvNd
&& 1 == nRegionRet
) &&
229 pSttPos
->nContent
.GetIndex() )
231 SwTxtNode
* const pTNd
=
232 pSttPos
->nNode
.GetNode().GetTxtNode();
235 pUndoInsSect
->SaveSplitNode( pTNd
, TRUE
);
239 if ( !( pPrvNd
&& 2 == nRegionRet
) )
241 SwTxtNode
*const pTNd
=
242 pEndPos
->nNode
.GetNode().GetTxtNode();
244 (pTNd
->GetTxt().Len() != pEndPos
->nContent
.GetIndex()))
246 pUndoInsSect
->SaveSplitNode( pTNd
, FALSE
);
251 const SwCntntNode
* pCNd
;
252 if( pPrvNd
&& 1 == nRegionRet
)
254 pSttPos
->nNode
.Assign( *pPrvNd
);
255 pSttPos
->nContent
.Assign( pSttPos
->nNode
.GetNode().GetCntntNode(), 0 );
257 else if( pSttPos
->nContent
.GetIndex() )
259 SplitNode( *pSttPos
, false );
262 if( pPrvNd
&& 2 == nRegionRet
)
264 pEndPos
->nNode
.Assign( *pPrvNd
);
265 pEndPos
->nContent
.Assign( pEndPos
->nNode
.GetNode().GetCntntNode(), 0 );
269 pCNd
= pEndPos
->nNode
.GetNode().GetCntntNode();
270 if( pCNd
&& pCNd
->Len() != pEndPos
->nContent
.GetIndex() )
272 xub_StrLen nCntnt
= pSttPos
->nContent
.GetIndex();
273 SplitNode( *pEndPos
, false );
276 if( pEndPos
->nNode
.GetIndex() == pSttPos
->nNode
.GetIndex() )
280 pTNd
= pSttPos
->nNode
.GetNode().GetTxtNode();
281 pSttPos
->nContent
.Assign( pTNd
, nCntnt
);
285 // wieder ans Ende vom vorherigen setzen
287 pTNd
= pEndPos
->nNode
.GetNode().GetTxtNode();
289 if( pTNd
) nCntnt
= pTNd
->GetTxt().Len(); else nCntnt
= 0;
290 pEndPos
->nContent
.Assign( pTNd
, nCntnt
);
293 pNewSectNode
= GetNodes().InsertSection( pSttPos
->nNode
, *pFmt
, rNew
,
299 const SwPosition
* pPos
= rRange
.GetPoint();
300 const SwCntntNode
* pCNd
= pPos
->nNode
.GetNode().GetCntntNode();
301 if( !pPos
->nContent
.GetIndex() )
303 pNewSectNode
= GetNodes().InsertSection( pPos
->nNode
, *pFmt
, rNew
, 0, TRUE
);
305 else if( pPos
->nContent
.GetIndex() == pCNd
->Len() )
307 pNewSectNode
= GetNodes().InsertSection( pPos
->nNode
, *pFmt
, rNew
, 0, FALSE
);
311 if( pUndoInsSect
&& pCNd
->IsTxtNode() )
313 pUndoInsSect
->SaveSplitNode( (SwTxtNode
*)pCNd
, TRUE
);
315 SplitNode( *pPos
, false );
316 pNewSectNode
= GetNodes().InsertSection( pPos
->nNode
, *pFmt
, rNew
, 0, TRUE
);
321 pNewSectNode
->CheckSectionCondColl();
324 SetRedlineMode_intern( eOld
);
326 if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl
->Count() ))
328 SwPaM
aPam( *pNewSectNode
->EndOfSectionNode(), *pNewSectNode
, 1 );
331 AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT
, aPam
), true);
335 SplitRedline( aPam
);
339 // ist eine Condition gesetzt
340 if( rNew
.IsHidden() && rNew
.GetCondition().Len() )
342 // dann berechne bis zu dieser Position
343 SwCalc
aCalc( *this );
344 if( ! IsInReading() )
346 FldsToCalc( aCalc
, pNewSectNode
->GetIndex(), USHRT_MAX
);
348 SwSection
& rNewSect
= pNewSectNode
->GetSection();
349 rNewSect
.SetCondHidden( aCalc
.Calculate( rNewSect
.GetCondition() ).GetBool() );
352 BOOL bUpdateFtn
= FALSE
;
353 if( GetFtnIdxs().Count() && pAttr
)
355 USHORT nVal
= ((SwFmtFtnAtTxtEnd
&)pAttr
->Get(
356 RES_FTN_AT_TXTEND
)).GetValue();
357 if( ( FTNEND_ATTXTEND_OWNNUMSEQ
== nVal
||
358 FTNEND_ATTXTEND_OWNNUMANDFMT
== nVal
) ||
359 ( FTNEND_ATTXTEND_OWNNUMSEQ
== ( nVal
= ((SwFmtEndAtTxtEnd
&)
360 pAttr
->Get( RES_END_AT_TXTEND
)).GetValue() ) ||
361 FTNEND_ATTXTEND_OWNNUMANDFMT
== nVal
))
369 pUndoInsSect
->SetSectNdPos( pNewSectNode
->GetIndex() );
370 pUndoInsSect
->SetUpdtFtnFlag( bUpdateFtn
);
374 if( rNew
.IsLinkType() )
376 pNewSectNode
->GetSection().CreateLink( bUpdate
? CREATE_UPDATE
: CREATE_CONNECT
);
381 GetFtnIdxs().UpdateFtn( SwNodeIndex( *pNewSectNode
));
385 return &pNewSectNode
->GetSection();
388 USHORT
SwDoc::IsInsRegionAvailable( const SwPaM
& rRange
,
389 const SwNode
** ppSttNd
) const
392 if( rRange
.HasMark() )
394 // teste ob es sich um eine gueltige Selektion handelt
395 const SwPosition
* pStt
= rRange
.Start(),
396 * pEnd
= rRange
.End();
398 const SwCntntNode
* pCNd
= pEnd
->nNode
.GetNode().GetCntntNode();
399 const SwNode
* pNd
= &pStt
->nNode
.GetNode();
400 const SwSectionNode
* pSectNd
= pNd
->FindSectionNode();
401 const SwSectionNode
* pEndSectNd
= pCNd
? pCNd
->FindSectionNode() : 0;
402 if( pSectNd
&& pEndSectNd
&& pSectNd
!= pEndSectNd
)
404 // versuche eine umschliessende Section zu erzeugen
405 // Aber, nur wenn der Start am Sectionanfang und das Ende am
406 // Section Ende liegt!
408 if( !pStt
->nContent
.GetIndex() && pSectNd
->GetIndex()
409 == pStt
->nNode
.GetIndex() - 1 && pEnd
->nContent
.GetIndex() ==
412 SwNodeIndex
aIdx( pStt
->nNode
, -1 );
413 ULONG nCmp
= pEnd
->nNode
.GetIndex();
414 const SwStartNode
* pPrvNd
;
415 const SwEndNode
* pNxtNd
;
416 while( 0 != ( pPrvNd
= (pNd
= &aIdx
.GetNode())->GetSectionNode() ) &&
417 !( aIdx
.GetIndex() < nCmp
&&
418 nCmp
< pPrvNd
->EndOfSectionIndex() ) )
423 pPrvNd
= pNd
->IsStartNode() ? (SwStartNode
*)pNd
424 : pNd
->StartOfSectionNode();
426 aIdx
= pEnd
->nNode
.GetIndex() + 1;
427 nCmp
= pStt
->nNode
.GetIndex();
428 while( 0 != ( pNxtNd
= (pNd
= &aIdx
.GetNode())->GetEndNode() ) &&
429 pNxtNd
->StartOfSectionNode()->IsSectionNode() &&
430 !( pNxtNd
->StartOfSectionIndex() < nCmp
&&
431 nCmp
< aIdx
.GetIndex() ) )
436 pNxtNd
= pNd
->EndOfSectionNode();
438 if( pPrvNd
&& pNxtNd
&& pPrvNd
== pNxtNd
->StartOfSectionNode() )
447 else if( !pSectNd
&& pEndSectNd
)
449 // versuche eine umschliessende Section zu erzeugen
450 // Aber, nur wenn das Ende am Section Ende liegt!
452 if( pEnd
->nContent
.GetIndex() == pCNd
->Len() )
454 SwNodeIndex
aIdx( pEnd
->nNode
, 1 );
455 if( aIdx
.GetNode().IsEndNode() &&
456 0 != aIdx
.GetNode().FindSectionNode() )
460 } while( aIdx
.GetNode().IsEndNode() &&
461 0 != aIdx
.GetNode().FindSectionNode() );
462 // if( !aIdx.GetNode().IsEndNode() )
468 *ppSttNd
= &aIdx
.GetNode();
474 else if( pSectNd
&& !pEndSectNd
)
476 // versuche eine umschliessende Section zu erzeugen
477 // Aber, nur wenn der Start am Section Anfang liegt!
479 if( !pStt
->nContent
.GetIndex() )
481 SwNodeIndex
aIdx( pStt
->nNode
, -1 );
482 if( aIdx
.GetNode().IsSectionNode() )
486 } while( aIdx
.GetNode().IsSectionNode() );
487 if( !aIdx
.GetNode().IsSectionNode() )
493 *ppSttNd
= &aIdx
.GetNode();
503 SwSection
* SwDoc::GetCurrSection( const SwPosition
& rPos
) const
505 const SwSectionNode
* pSectNd
= rPos
.nNode
.GetNode().FindSectionNode();
507 return (SwSection
*)&pSectNd
->GetSection();
511 SwSectionFmt
* SwDoc::MakeSectionFmt( SwSectionFmt
*pDerivedFrom
)
514 pDerivedFrom
= (SwSectionFmt
*)pDfltFrmFmt
;
515 SwSectionFmt
* pNew
= new SwSectionFmt( pDerivedFrom
, this );
516 pSectionFmtTbl
->Insert( pNew
, pSectionFmtTbl
->Count() );
520 void SwDoc::DelSectionFmt( SwSectionFmt
*pFmt
, BOOL bDelNodes
)
522 USHORT nPos
= pSectionFmtTbl
->GetPos( pFmt
);
524 StartUndo(UNDO_DELSECTION
, NULL
);
526 if( USHRT_MAX
!= nPos
)
528 const SwNodeIndex
* pIdx
= pFmt
->GetCntnt( FALSE
).GetCntntIdx();
529 const SfxPoolItem
* pFtnEndAtTxtEnd
;
530 if( SFX_ITEM_SET
!= pFmt
->GetItemState(
531 RES_FTN_AT_TXTEND
, TRUE
, &pFtnEndAtTxtEnd
) ||
532 SFX_ITEM_SET
!= pFmt
->GetItemState(
533 RES_END_AT_TXTEND
, TRUE
, &pFtnEndAtTxtEnd
))
536 const SwSectionNode
* pSectNd
;
541 if( bDelNodes
&& pIdx
&& &GetNodes() == &pIdx
->GetNodes() &&
542 0 != (pSectNd
= pIdx
->GetNode().GetSectionNode() ))
544 SwNodeIndex
aUpdIdx( *pIdx
);
546 SwPaM
aPaM( *pSectNd
->EndOfSectionNode(), *pSectNd
);
547 AppendUndo( new SwUndoDelete( aPaM
));
548 if( pFtnEndAtTxtEnd
)
549 GetFtnIdxs().UpdateFtn( aUpdIdx
);
551 //#126178# start/end undo have to be pairs!
552 EndUndo(UNDO_DELSECTION
, NULL
);
555 AppendUndo( new SwUndoDelSection( *pFmt
) );
557 else if( bDelNodes
&& pIdx
&& &GetNodes() == &pIdx
->GetNodes() &&
558 0 != (pSectNd
= pIdx
->GetNode().GetSectionNode() ))
560 SwNodeIndex
aUpdIdx( *pIdx
);
561 DeleteSection( (SwNode
*)pSectNd
);
562 if( pFtnEndAtTxtEnd
)
563 GetFtnIdxs().UpdateFtn( aUpdIdx
);
565 //#126178# start/end undo have to be pairs!
566 EndUndo(UNDO_DELSECTION
, NULL
);
571 SwPtrMsgPoolItem
aMsgHint( RES_REMOVE_UNO_OBJECT
, pFmt
);
572 pFmt
->Modify( &aMsgHint
, &aMsgHint
);
575 // A ClearRedo could result in a rekursive call of this function and delete some section
576 // formats => the position iside the SectionFmtTbl could have changed
577 nPos
= pSectionFmtTbl
->GetPos( pFmt
);
579 // ACHTUNG: erst aus dem Array entfernen und dann loeschen.
580 // Der Section-DTOR versucht selbst noch sein Format
582 pSectionFmtTbl
->Remove( nPos
);
584 ULONG nCnt
= 0, nSttNd
= 0;
585 if( pIdx
&& &GetNodes() == &pIdx
->GetNodes() &&
586 0 != (pSectNd
= pIdx
->GetNode().GetSectionNode() ))
588 nSttNd
= pSectNd
->GetIndex();
589 nCnt
= pSectNd
->EndOfSectionIndex() - nSttNd
- 1;
595 if( nSttNd
&& pFtnEndAtTxtEnd
)
597 SwNodeIndex
aUpdIdx( GetNodes(), nSttNd
);
598 GetFtnIdxs().UpdateFtn( aUpdIdx
);
603 for( ; nCnt
--; ++nSttNd
)
604 if( 0 != (pCNd
= GetNodes()[ nSttNd
]->GetCntntNode() ) &&
605 RES_CONDTXTFMTCOLL
== pCNd
->GetFmtColl()->Which() )
610 EndUndo(UNDO_DELSECTION
, NULL
);
615 void SwDoc::ChgSection( USHORT nPos
, const SwSection
& rSect
,
616 const SfxItemSet
* pAttr
,
617 sal_Bool bPreventLinkUpdate
)
619 SwSectionFmt
* pFmt
= (*pSectionFmtTbl
)[ nPos
];
620 SwSection
* pSection
= pFmt
->GetSection();
621 /// OD 04.10.2002 #102894#
622 /// remember hidden condition flag of SwSection before changes
623 bool bOldCondHidden
= pSection
->IsCondHidden() ? true : false;
625 if( *pSection
== rSect
)
627 // die Attribute ueberpruefen
628 BOOL bOnlyAttrChg
= FALSE
;
629 if( pAttr
&& pAttr
->Count() )
631 SfxItemIter
aIter( *pAttr
);
632 USHORT nWhich
= aIter
.GetCurItem()->Which();
635 if( pFmt
->GetFmtAttr( nWhich
) != *aIter
.GetCurItem() )
641 if( aIter
.IsAtEnd() )
643 nWhich
= aIter
.NextItem()->Which();
649 const BOOL bDoesUndo
= DoesUndo();
653 AppendUndo( new SwUndoChgSection( *pFmt
, TRUE
) );
654 // --> FME 2004-10-13 #i32968#
655 // Inserting columns in the section causes MakeFrmFmt to put two
656 // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
660 pFmt
->SetFmtAttr( *pAttr
);
663 // --> FME 2004-10-13 #i32968#
670 // Teste ob eine gesamte Content-Section (Dokument/TabellenBox/Fly)
671 // versteckt werden soll, koennen wir zur Zeit nicht !!!!
672 const SwNodeIndex
* pIdx
= 0;
674 const SwSectionNode
* pSectNd
;
675 if( rSect
.IsHidden() && 0 != (pIdx
= pFmt
->GetCntnt().GetCntntIdx() )
676 && 0 != (pSectNd
= pIdx
->GetNode().GetSectionNode() ) )
678 ::lcl_CheckEmptyLayFrm( GetNodes(), (SwSection
&)rSect
,
679 *pSectNd
, *pSectNd
->EndOfSectionNode() );
683 const BOOL bDoesUndo
= DoesUndo();
687 AppendUndo( new SwUndoChgSection( *pFmt
, FALSE
) );
688 // --> FME 2004-10-13 #i32968#
689 // Inserting columns in the section causes MakeFrmFmt to put two
690 // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
695 // #56167# Der LinkFileName koennte auch nur aus Separatoren bestehen
696 String sCompareString
= sfx2::cTokenSeperator
;
697 sCompareString
+= sfx2::cTokenSeperator
;
698 BOOL bUpdate
= ( !pSection
->IsLinkType() && rSect
.IsLinkType() ) ||
699 ( rSect
.GetLinkFileName().Len() &&
700 rSect
.GetLinkFileName() != sCompareString
&&
701 rSect
.GetLinkFileName() !=
702 pSection
->GetLinkFileName());
704 String
sSectName( rSect
.GetName() );
705 if( sSectName
!= pSection
->GetName() )
706 GetUniqueSectionName( &sSectName
);
710 /// OD 04.10.2002 #102894# - NOTE
711 /// In SwSection::operator=(..) class member bCondHiddenFlag is always set to TRUE.
712 /// IMHO this have to be changed, but I can't estimate the consequences:
713 /// Either it is set to TRUE using corresponding method <SwSection.SetCondHidden(..)>,
714 /// or it is set to the value of SwSection which is assigned to it.
715 /// Discussion with AMA results that the adjustment to the assignment operator
716 /// could be very risky -> see notes in bug #102894#.
720 pSection
->GetFmt()->SetFmtAttr( *pAttr
);
722 if( sSectName
.Len() )
723 pSection
->SetName( sSectName
);
725 // ist eine Condition gesetzt
726 if( pSection
->IsHidden() && pSection
->GetCondition().Len() )
728 // dann berechne bis zu dieser Position
729 SwCalc
aCalc( *this );
731 pIdx
= pFmt
->GetCntnt().GetCntntIdx();
732 FldsToCalc( aCalc
, pIdx
->GetIndex(), USHRT_MAX
);
733 /// OD 04.10.2002 #102894#
734 /// Because on using SwSection::operator=() to set up <pSection>
735 /// with <rSect> and the above given note, the hidden condition flag
736 /// has to be set to FALSE, if hidden condition flag of <pFmt->GetSection()>
737 /// (SwSection before the changes) is FALSE (already saved in <bOldCondHidden>)
738 /// and new calculated condition is TRUE.
739 /// This is necessary, because otherwise the <SetCondHidden> would have
741 bool bCalculatedCondHidden
=
742 aCalc
.Calculate( pSection
->GetCondition() ).GetBool() ? true : false;
743 if ( bCalculatedCondHidden
&& !bOldCondHidden
)
745 pSection
->SetCondHidden( false );
747 pSection
->SetCondHidden( bCalculatedCondHidden
);
751 pSection
->CreateLink( bPreventLinkUpdate
? CREATE_CONNECT
: CREATE_UPDATE
);
752 else if( !pSection
->IsLinkType() && pSection
->IsConnected() )
754 pSection
->Disconnect();
755 GetLinkManager().Remove( &pSection
->GetBaseLink() );
760 // --> FME 2004-10-13 #i32968#
765 /* -----------------19.02.99 09:31-------------------
766 * LockFrms wurde im InsertSection genutzt, um zu verhindern, dass
767 * SectionFrms durch das DelFrms zerstoert werden. Dies ist durch
768 * den Destroy-Listen-Mechanismus ueberfluessig geworden.
769 * Falls diese Methode doch noch einmal reanimiert wird, bietet es
770 * sich vielleicht an, beim Entlocken die SectionFrms auf Inhalt zu
771 * pruefen und dann ggf. zur Zerstoerung anzumelden.
772 * --------------------------------------------------*/
774 // und dann waren da noch die Fussnoten:
775 void lcl_DeleteFtn( SwSectionNode
*pNd
, ULONG nStt
, ULONG nEnd
)
777 SwFtnIdxs
& rFtnArr
= pNd
->GetDoc()->GetFtnIdxs();
778 if( rFtnArr
.Count() )
781 rFtnArr
.SeekEntry( SwNodeIndex( *pNd
), &nPos
);
784 // loesche erstmal alle, die dahinter stehen
785 while( nPos
< rFtnArr
.Count() &&
786 _SwTxtFtn_GetIndex( (pSrch
= rFtnArr
[ nPos
]) ) <= nEnd
)
788 // Werden die Nodes nicht geloescht mussen sie bei den Seiten
789 // abmeldet (Frms loeschen) werden, denn sonst bleiben sie
790 // stehen (Undo loescht sie nicht!)
796 _SwTxtFtn_GetIndex( (pSrch
= rFtnArr
[ nPos
]) ) >= nStt
)
798 // Werden die Nodes nicht geloescht mussen sie bei den Seiten
799 // abmeldet (Frms loeschen) werden, denn sonst bleiben sie
800 // stehen (Undo loescht sie nicht!)
806 inline BOOL
lcl_IsTOXSection( const SwSection
& rSection
)
808 return TOX_CONTENT_SECTION
== rSection
.GetType() ||
809 TOX_HEADER_SECTION
== rSection
.GetType();
812 SwSectionNode
* SwNodes::InsertSection( const SwNodeIndex
& rNdIdx
,
813 SwSectionFmt
& rSectionFmt
,
814 const SwSection
& rSection
,
815 const SwNodeIndex
* pEnde
,
816 BOOL bInsAtStart
, BOOL bCreateFrms
)
818 SwNodeIndex
aInsPos( rNdIdx
);
819 if( !pEnde
) // kein Bereich also neue Section davor/hinter anlegen
822 ASSERT(!pEnde
|| rNdIdx
<= *pEnde
,
823 "Section start and end in wrong order!");
827 if( !lcl_IsTOXSection( rSection
))
831 } while( aInsPos
.GetNode().IsSectionNode() );
839 if( !lcl_IsTOXSection( rSection
))
840 while( aInsPos
.GetIndex() < Count() - 1 &&
841 ( pNd
= &aInsPos
.GetNode())->IsEndNode() &&
842 pNd
->StartOfSectionNode()->IsSectionNode())
847 SwSectionNode
* pSectNd
= new SwSectionNode( aInsPos
, rSectionFmt
);
850 // Sonderfall fuer die Reader/Writer
851 if( &pEnde
->GetNode() != &GetEndOfContent() )
852 aInsPos
= pEnde
->GetIndex()+1;
853 // #i58710: We created a RTF document with a section break inside a table cell
854 // We are not able to handle a section start inside a table and the section end outside.
855 const SwNode
* pLastNode
= pSectNd
->StartOfSectionNode()->EndOfSectionNode();
856 if( aInsPos
> pLastNode
->GetIndex() )
857 aInsPos
= pLastNode
->GetIndex();
858 // Another way round: if the section starts outside a table but the end is inside...
859 // aInsPos is at the moment the Position where my EndNode will be inserted
860 const SwStartNode
* pStartNode
= aInsPos
.GetNode().StartOfSectionNode();
861 // This StartNode should be in front of me, but if not, I wanna survive
862 ULONG nMyIndex
= pSectNd
->GetIndex();
863 if( pStartNode
->GetIndex() > nMyIndex
) // Suspicious!
868 pTemp
= pStartNode
; // pTemp is a suspicious one
869 pStartNode
= pStartNode
->StartOfSectionNode();
871 while( pStartNode
->GetIndex() > nMyIndex
);
872 pTemp
= pTemp
->EndOfSectionNode();
873 // If it starts behind me but ends behind my end...
874 if( pTemp
->GetIndex() >= aInsPos
.GetIndex() )
875 aInsPos
= pTemp
->GetIndex()+1; // ...I have to correct my end position
881 SwTxtNode
* pCpyTNd
= rNdIdx
.GetNode().GetTxtNode();
884 SwTxtNode
* pTNd
= new SwTxtNode( aInsPos
, pCpyTNd
->GetTxtColl() );
885 if( pCpyTNd
->HasSwAttrSet() )
887 // Task 70955 - move PageDesc/Break to the first Node of the
889 const SfxItemSet
& rSet
= *pCpyTNd
->GetpSwAttrSet();
890 if( SFX_ITEM_SET
== rSet
.GetItemState( RES_BREAK
) ||
891 SFX_ITEM_SET
== rSet
.GetItemState( RES_PAGEDESC
))
893 SfxItemSet
aSet( rSet
);
895 pCpyTNd
->ResetAttr( RES_PAGEDESC
, RES_BREAK
);
898 aSet
.ClearItem( RES_PAGEDESC
);
899 aSet
.ClearItem( RES_BREAK
);
901 pTNd
->SetAttr( aSet
);
904 pTNd
->SetAttr( rSet
);
906 // den Frame anlegen nicht vergessen !!
907 pCpyTNd
->MakeFrms( *pTNd
);
910 new SwTxtNode( aInsPos
, (SwTxtFmtColl
*)GetDoc()->GetDfltTxtFmtColl() );
912 new SwEndNode( aInsPos
, *pSectNd
);
914 pSectNd
->GetSection() = rSection
;
915 SwSectionFmt
* pSectFmt
= pSectNd
->GetSection().GetFmt();
917 // Hier bietet sich als Optimierung an, vorhandene Frames nicht zu
918 // zerstoeren und wieder neu anzulegen, sondern nur umzuhaengen.
919 BOOL bInsFrm
= bCreateFrms
&& !pSectNd
->GetSection().IsHidden() &&
920 GetDoc()->GetRootFrm();
921 SwNode2Layout
*pNode2Layout
= NULL
;
924 SwNodeIndex
aTmp( *pSectNd
);
925 if( !pSectNd
->GetNodes().FindPrvNxtFrmNode( aTmp
, pSectNd
->EndOfSectionNode() ) )
926 // dann sammel mal alle Uppers ein
927 pNode2Layout
= new SwNode2Layout( *pSectNd
);
930 // jetzt noch bei allen im Bereich den richtigen StartNode setzen
931 ULONG nEnde
= pSectNd
->EndOfSectionIndex();
932 ULONG nStart
= pSectNd
->GetIndex()+1;
933 ULONG nSkipIdx
= ULONG_MAX
;
934 for( ULONG n
= nStart
; n
< nEnde
; ++n
)
936 SwNode
* pNd
= (*this)[n
];
938 //JP 30.04.99: Bug 65644 - alle in der NodeSection liegenden
939 // Sections unter die neue haengen
940 if( ULONG_MAX
== nSkipIdx
)
941 pNd
->pStartOfSection
= pSectNd
;
942 else if( n
>= nSkipIdx
)
943 nSkipIdx
= ULONG_MAX
;
945 if( pNd
->IsStartNode() )
947 // die Verschachtelung der Formate herstellen!
948 if( pNd
->IsSectionNode() )
950 ((SwSectionNode
*)pNd
)->GetSection().GetFmt()->
951 SetDerivedFrom( pSectFmt
);
952 ((SwSectionNode
*)pNd
)->DelFrms();
953 n
= pNd
->EndOfSectionIndex();
957 if( pNd
->IsTableNode() )
958 ((SwTableNode
*)pNd
)->DelFrms();
960 if( ULONG_MAX
== nSkipIdx
)
961 nSkipIdx
= pNd
->EndOfSectionIndex();
964 else if( pNd
->IsCntntNode() )
965 ((SwCntntNode
*)pNd
)->DelFrms();
968 lcl_DeleteFtn( pSectNd
, nStart
, nEnde
);
974 ULONG nIdx
= pSectNd
->GetIndex();
975 pNode2Layout
->RestoreUpperFrms( pSectNd
->GetNodes(), nIdx
, nIdx
+ 1 );
979 pSectNd
->MakeFrms( &aInsPos
);
985 SwSectionNode
* SwNode::FindSectionNode()
987 if( IsSectionNode() )
988 return GetSectionNode();
989 SwStartNode
* pTmp
= pStartOfSection
;
990 while( !pTmp
->IsSectionNode() && pTmp
->GetIndex() )
991 #if defined( ALPHA ) && defined( UNX )
992 pTmp
= ((SwNode
*)pTmp
)->pStartOfSection
;
994 pTmp
= pTmp
->pStartOfSection
;
996 return pTmp
->GetSectionNode();
1004 SwSectionNode::SwSectionNode( const SwNodeIndex
& rIdx
, SwSectionFmt
& rFmt
)
1005 : SwStartNode( rIdx
, ND_SECTIONNODE
)
1007 SwSectionNode
* pParent
= StartOfSectionNode()->FindSectionNode();
1010 // das Format beim richtigen Parent anmelden.
1011 rFmt
.SetDerivedFrom( pParent
->GetSection().GetFmt() );
1013 pSection
= new SwSection( CONTENT_SECTION
, rFmt
.GetName(), &rFmt
);
1015 // jetzt noch die Verbindung von Format zum Node setzen
1016 // Modify unterdruecken, interresiert keinen
1018 rFmt
.SetFmtAttr( SwFmtCntnt( this ) );
1019 rFmt
.UnlockModify();
1022 #if OSL_DEBUG_LEVEL > 1
1023 //Hier werden ueberfluessige SectionFrms entfernt
1024 SwFrm
* SwClearDummies( SwFrm
* pFrm
)
1029 ASSERT( !pTmp
->GetUpper(), "SwClearDummies: No Upper allowed!" );
1030 if( pTmp
->IsSctFrm() )
1032 SwSectionFrm
* pSectFrm
= (SwSectionFrm
*)pFrm
;
1033 pTmp
= pTmp
->GetNext();
1034 if( !pSectFrm
->GetLower() )
1036 if( pSectFrm
->GetPrev() )
1037 pSectFrm
->GetPrev()->pNext
= pTmp
;
1041 pTmp
->pPrev
= pSectFrm
->GetPrev();
1046 pTmp
= pTmp
->GetNext();
1052 SwSectionNode::~SwSectionNode()
1055 SwClientIter
aIter( *(pSection
->GetFmt()) );
1056 SwClient
*pLast
= aIter
.GoStart();
1059 if ( pLast
->IsA( TYPE(SwFrm
) ) )
1061 SwSectionFrm
*pSectFrm
= (SwSectionFrm
*)pLast
;
1062 SwSectionFrm::MoveCntntAndDelete( pSectFrm
, TRUE
);
1063 pLast
= aIter
.GoStart();
1069 SwDoc
* pDoc
= GetDoc();
1071 SwSectionFmt
* pFmt
= pSection
->GetFmt();
1074 // das Attribut entfernen, weil die Section ihr Format loescht
1075 // und falls das Cntnt-Attribut vorhanden ist, die Section aufhebt.
1077 pFmt
->ResetFmtAttr( RES_CNTNT
);
1078 pFmt
->UnlockModify();
1081 BOOL bUndo
= pDoc
->DoesUndo();
1082 // verhinder beim Loeschen aus der Undo/Redo-History einen rekursiven Aufruf
1083 if( bUndo
&& &pDoc
->GetNodes() != &GetNodes() )
1084 pDoc
->DoUndo( FALSE
);
1085 DELETEZ( pSection
);
1086 pDoc
->DoUndo( bUndo
);
1089 // setze ein neues SectionObject. Erstmal nur gedacht fuer die
1090 // neuen VerzeichnisSections. Der geht ueber in den Besitz des Nodes!
1091 void SwSectionNode::SetNewSection( SwSection
* pNewSection
)
1093 ASSERT( pNewSection
, "ohne Pointer geht hier nichts" );
1096 SwNode2Layout
aN2L( *this );
1098 // einige Flags sollten ueber nommen werden!
1099 pNewSection
->bProtectFlag
= pSection
->bProtectFlag
;
1100 pNewSection
->bHiddenFlag
= pSection
->bHiddenFlag
;
1101 pNewSection
->bHidden
= pSection
->bHidden
;
1102 pNewSection
->bCondHiddenFlag
= pSection
->bCondHiddenFlag
;
1104 // The section frame contains a pointer to the section. That for,
1105 // the frame must be destroyed before deleting the section.
1109 pSection
= pNewSection
;
1111 ULONG nIdx
= GetIndex();
1112 aN2L
.RestoreUpperFrms( GetNodes(), nIdx
, nIdx
+ 1 );
1116 SwFrm
*SwSectionNode::MakeFrm()
1118 pSection
->bHiddenFlag
= FALSE
;
1119 return new SwSectionFrm( *pSection
);
1122 //Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
1123 //Dokument. Die erzeugten Contentframes werden in das entsprechende
1125 void SwSectionNode::MakeFrms(const SwNodeIndex
& rIdx
)
1127 // also nehme meinen nachfolgenden oder vorhergehenden ContentFrame:
1128 SwNodes
& rNds
= GetNodes();
1129 if( rNds
.IsDocNodes() && rNds
.GetDoc()->GetRootFrm() )
1131 if( GetSection().IsHidden() || IsCntntHidden() )
1133 SwNodeIndex
aIdx( *EndOfSectionNode() );
1134 SwCntntNode
* pCNd
= rNds
.GoNextSection( &aIdx
, TRUE
, FALSE
);
1138 if( 0 == ( pCNd
= rNds
.GoPrevSection( &aIdx
, TRUE
, FALSE
)) )
1141 pCNd
= rNds
[ aIdx
]->GetCntntNode();
1142 pCNd
->MakeFrms( (SwCntntNode
&)rIdx
.GetNode() );
1146 SwNode2Layout
aNode2Layout( *this, rIdx
.GetIndex() );
1148 while( 0 != (pFrm
= aNode2Layout
.NextFrm()) )
1150 ASSERT( pFrm
->IsSctFrm(), "Depend von Section keine Section." );
1151 pNew
= rIdx
.GetNode().GetCntntNode()->MakeFrm();
1153 SwSectionNode
* pS
= rIdx
.GetNode().FindSectionNode();
1154 // --> OD 2008-06-23 #156927#
1155 // Assure that node is not inside a table, which is inside the
1159 SwTableNode
* pTableNode
= rIdx
.GetNode().FindTableNode();
1161 pTableNode
->GetIndex() > pS
->GetIndex() )
1167 // if the node is in a section, the sectionframe now
1168 // has to be created..
1169 // OD 14.11.2002 #104684# - boolean to control <Init()> of a new
1171 bool bInitNewSect
= false;
1174 SwSectionFrm
*pSct
= new SwSectionFrm( pS
->GetSection() );
1175 // OD 14.11.2002 #104684# - prepare <Init()> of new section frame.
1176 bInitNewSect
= true;
1177 SwLayoutFrm
* pUp
= pSct
;
1178 while( pUp
->Lower() ) // for columned sections
1180 ASSERT( pUp
->Lower()->IsLayoutFrm(),"Who's in there?" );
1181 pUp
= (SwLayoutFrm
*)pUp
->Lower();
1183 pNew
->Paste( pUp
, NULL
);
1184 // --> OD 2005-12-01 #i27138#
1185 // notify accessibility paragraphs objects about changed
1186 // CONTENT_FLOWS_FROM/_TO relation.
1187 // Relation CONTENT_FLOWS_FROM for next paragraph will change
1188 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1189 if ( pNew
->IsTxtFrm() )
1191 ViewShell
* pViewShell( pNew
->GetShell() );
1192 if ( pViewShell
&& pViewShell
->GetLayout() &&
1193 pViewShell
->GetLayout()->IsAnyShellAccessible() )
1195 pViewShell
->InvalidateAccessibleParaFlowRelation(
1196 dynamic_cast<SwTxtFrm
*>(pNew
->FindNextCnt( true )),
1197 dynamic_cast<SwTxtFrm
*>(pNew
->FindPrevCnt( true )) );
1204 // wird ein Node vorher oder nachher mit Frames versehen
1205 if ( rIdx
< GetIndex() )
1206 // der neue liegt vor mir
1207 pNew
->Paste( pFrm
->GetUpper(), pFrm
);
1209 // der neue liegt hinter mir
1210 pNew
->Paste( pFrm
->GetUpper(), pFrm
->GetNext() );
1211 // --> OD 2005-12-01 #i27138#
1212 // notify accessibility paragraphs objects about changed
1213 // CONTENT_FLOWS_FROM/_TO relation.
1214 // Relation CONTENT_FLOWS_FROM for next paragraph will change
1215 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1216 if ( pNew
->IsTxtFrm() )
1218 ViewShell
* pViewShell( pNew
->GetShell() );
1219 if ( pViewShell
&& pViewShell
->GetLayout() &&
1220 pViewShell
->GetLayout()->IsAnyShellAccessible() )
1222 pViewShell
->InvalidateAccessibleParaFlowRelation(
1223 dynamic_cast<SwTxtFrm
*>(pNew
->FindNextCnt( true )),
1224 dynamic_cast<SwTxtFrm
*>(pNew
->FindPrevCnt( true )) );
1229 static_cast<SwSectionFrm
*>(pNew
)->Init();
1235 //Fuer jedes vorkommen im Layout einen SectionFrm anlegen und vor den
1236 //entsprechenden CntntFrm pasten.
1238 void SwSectionNode::MakeFrms( SwNodeIndex
* pIdxBehind
, SwNodeIndex
* pEndIdx
)
1240 ASSERT( pIdxBehind
, "kein Index" );
1241 SwNodes
& rNds
= GetNodes();
1242 SwDoc
* pDoc
= rNds
.GetDoc();
1244 *pIdxBehind
= *this;
1246 pSection
->bHiddenFlag
= TRUE
;
1248 if( rNds
.IsDocNodes() )
1250 SwNodeIndex
*pEnd
= pEndIdx
? pEndIdx
:
1251 new SwNodeIndex( *EndOfSectionNode(), 1 );
1252 ::MakeFrms( pDoc
, *pIdxBehind
, *pEnd
);
1259 void SwSectionNode::DelFrms()
1261 ULONG nStt
= GetIndex()+1, nEnd
= EndOfSectionIndex();
1264 // unser Flag muessen wir noch aktualisieren
1265 // pSection->bHiddenFlag = TRUE;
1269 SwNodes
& rNds
= GetNodes();
1270 pSection
->GetFmt()->DelFrms();
1272 // unser Flag muessen wir noch aktualisieren
1273 pSection
->bHiddenFlag
= TRUE
;
1275 // Bug 30582: falls der Bereich in Fly oder TabellenBox ist, dann
1276 // kann er nur "gehiddet" werden, wenn weiterer Content
1277 // vorhanden ist, der "Frames" haelt. Sonst hat der
1278 // Fly/TblBox-Frame keinen Lower !!!
1280 SwNodeIndex
aIdx( *this );
1281 if( !rNds
.GoPrevSection( &aIdx
, TRUE
, FALSE
) ||
1282 !CheckNodesRange( *this, aIdx
, TRUE
) ||
1283 // OD 04.11.2003 #i21457#
1284 !lcl_IsInSameTblBox( rNds
, *this, true ))
1286 aIdx
= *EndOfSectionNode();
1287 if( !rNds
.GoNextSection( &aIdx
, TRUE
, FALSE
) ||
1288 !CheckNodesRange( *EndOfSectionNode(), aIdx
, TRUE
) ||
1289 // OD 04.11.2003 #i21457#
1290 !lcl_IsInSameTblBox( rNds
, *EndOfSectionNode(), false ))
1291 pSection
->bHiddenFlag
= FALSE
;
1296 SwSectionNode
* SwSectionNode::MakeCopy( SwDoc
* pDoc
, const SwNodeIndex
& rIdx
) const
1298 // in welchen Array steht ich denn: Nodes, UndoNodes ??
1299 const SwNodes
& rNds
= GetNodes();
1301 // das SectionFrmFmt kopieren
1302 SwSectionFmt
* pSectFmt
= pDoc
->MakeSectionFmt( 0 );
1303 pSectFmt
->CopyAttrs( *GetSection().GetFmt() );
1305 SwSectionNode
* pSectNd
= new SwSectionNode( rIdx
, *pSectFmt
);
1306 SwEndNode
* pEndNd
= new SwEndNode( rIdx
, *pSectNd
);
1307 SwNodeIndex
aInsPos( *pEndNd
);
1309 // Werte uebertragen
1310 SwSection
* pNewSect
= pSectNd
->pSection
;
1312 switch( GetSection().GetType() )
1314 case TOX_CONTENT_SECTION
:
1316 ASSERT( GetSection().ISA( SwTOXBaseSection
), "keine TOXBaseSection!" );
1317 SwTOXBaseSection
& rTOXSect
= (SwTOXBaseSection
&)GetSection();
1318 SwTOXBase
aTmp( rTOXSect
, pDoc
);
1320 SwTOXBaseSection
* pNew
= new SwTOXBaseSection( aTmp
);
1323 pSectFmt
->Add( pNewSect
);
1324 pSectNd
->SetNewSection( pNew
);
1329 // beim Move den Namen beibehalten
1330 if( rNds
.GetDoc() == pDoc
&& pDoc
->IsCopyIsMove() )
1331 pNewSect
->SetName( GetSection().GetName() );
1333 pNewSect
->SetName( pDoc
->GetUniqueSectionName(
1334 &GetSection().GetName() ) );
1339 pNewSect
->SetType( GetSection().GetType() );
1340 pNewSect
->SetCondition( GetSection().GetCondition() );
1341 pNewSect
->SetLinkFileName( GetSection().GetLinkFileName() );
1342 if( !pNewSect
->IsHiddenFlag() && GetSection().IsHidden() )
1343 pNewSect
->SetHidden( TRUE
);
1344 if( !pNewSect
->IsProtectFlag() && GetSection().IsProtect() )
1345 pNewSect
->SetProtect( TRUE
);
1346 // --> FME 2004-06-22 #114856# edit in readonly sections
1347 if( !pNewSect
->IsEditInReadonlyFlag() && GetSection().IsEditInReadonly() )
1348 pNewSect
->SetEditInReadonly( TRUE
);
1351 SwNodeRange
aRg( *this, +1, *EndOfSectionNode() ); // (wo stehe in denn nun ??)
1352 rNds
._Copy( aRg
, aInsPos
, FALSE
);
1354 // loesche alle Frames vom kopierten Bereich, diese werden beim
1355 // erzeugen des SectionFrames angelegt !
1358 // dann kopiere auch noch die Links/Server
1359 if( pNewSect
->IsLinkType() ) // den Link eintragen
1360 pNewSect
->CreateLink( pDoc
->GetRootFrm() ? CREATE_CONNECT
1363 // falls als Server aus dem Undo kopiert wird, wieder eintragen
1364 if( pSection
->IsServer() && pDoc
->GetUndoNds() == &rNds
)
1366 pNewSect
->SetRefObject( pSection
->GetObject() );
1367 pDoc
->GetLinkManager().InsertServer( pNewSect
->GetObject() );
1373 BOOL
SwSectionNode::IsCntntHidden() const
1375 ASSERT( !pSection
->IsHidden(), "That's simple: Hidden Section => Hidden Content" );
1376 SwNodeIndex
aTmp( *this, 1 );
1377 ULONG nEnd
= EndOfSectionIndex();
1378 while( aTmp
< nEnd
)
1380 if( aTmp
.GetNode().IsSectionNode() )
1382 const SwSection
& rSect
= ((SwSectionNode
&)aTmp
.GetNode()).GetSection();
1383 if( rSect
.IsHiddenFlag() )
1384 // dann diese Section ueberspringen
1385 aTmp
= *aTmp
.GetNode().EndOfSectionNode();
1389 if( aTmp
.GetNode().IsCntntNode() || aTmp
.GetNode().IsTableNode() )
1390 return FALSE
; // Nicht versteckter Inhalt wurde gefunden
1391 ASSERT( aTmp
.GetNode().IsEndNode(), "EndNode expected" );
1395 return TRUE
; // Alles versteckt
1399 void SwSectionNode::NodesArrChgd()
1401 SwSectionFmt
* pFmt
= pSection
->GetFmt();
1404 SwNodes
& rNds
= GetNodes();
1405 SwDoc
* pDoc
= pFmt
->GetDoc();
1407 if( !rNds
.IsDocNodes() )
1409 SwPtrMsgPoolItem
aMsgHint( RES_REMOVE_UNO_OBJECT
, pFmt
);
1410 pFmt
->Modify( &aMsgHint
, &aMsgHint
);
1414 pFmt
->SetFmtAttr( SwFmtCntnt( this ));
1415 pFmt
->UnlockModify();
1417 SwSectionNode
* pSectNd
= StartOfSectionNode()->FindSectionNode();
1418 // set the correct parent from the new section
1419 pFmt
->SetDerivedFrom( pSectNd
? pSectNd
->GetSection().GetFmt()
1420 : pDoc
->GetDfltFrmFmt() );
1422 // jetzt noch bei allen im Bereich den richtigen StartNode setzen
1423 ULONG nStart
= GetIndex()+1, nEnde
= EndOfSectionIndex();
1424 for( ULONG n
= nStart
; n
< nEnde
; ++n
)
1425 // die Verschachtelung der Formate herstellen!
1426 if( 0 != ( pSectNd
= rNds
[ n
]->GetSectionNode() ) )
1428 pSectNd
->GetSection().GetFmt()->SetDerivedFrom( pFmt
);
1429 n
= pSectNd
->EndOfSectionIndex();
1432 // verschieben vom Nodes- ins UndoNodes-Array?
1433 if( rNds
.IsDocNodes() )
1435 ASSERT( pDoc
== GetDoc(),
1436 "verschieben in unterschiedliche Documente?" );
1437 if( pSection
->IsLinkType() ) // den Link austragen
1438 pSection
->CreateLink( pDoc
->GetRootFrm() ? CREATE_CONNECT
1441 if( pSection
->IsServer() ) // als Server austragen
1442 pDoc
->GetLinkManager().InsertServer( pSection
->GetObject() );
1446 if( CONTENT_SECTION
!= pSection
->GetType() ) // den Link austragen
1447 pDoc
->GetLinkManager().Remove( &pSection
->GetBaseLink() );
1449 if( pSection
->IsServer() ) // als Server austragen
1450 pDoc
->GetLinkManager().RemoveServer( pSection
->GetObject() );
1456 String
SwDoc::GetUniqueSectionName( const String
* pChkStr
) const
1458 ResId
aId( STR_REGION_DEFNAME
, *pSwResMgr
);
1459 String
aName( aId
);
1460 xub_StrLen nNmLen
= aName
.Len();
1463 USHORT nTmp
, nFlagSize
= ( pSectionFmtTbl
->Count() / 8 ) +2;
1464 BYTE
* pSetFlags
= new BYTE
[ nFlagSize
];
1465 memset( pSetFlags
, 0, nFlagSize
);
1467 const SwSectionNode
* pSectNd
;
1470 for( n
= 0; n
< pSectionFmtTbl
->Count(); ++n
)
1471 if( 0 != ( pSectNd
= (*pSectionFmtTbl
)[ n
]->GetSectionNode( FALSE
) ))
1473 const String
& rNm
= pSectNd
->GetSection().GetName();
1474 if( rNm
.Match( aName
) == nNmLen
)
1476 // Nummer bestimmen und das Flag setzen
1477 nNum
= static_cast<USHORT
>(rNm
.Copy( nNmLen
).ToInt32());
1478 if( nNum
-- && nNum
< pSectionFmtTbl
->Count() )
1479 pSetFlags
[ nNum
/ 8 ] |= (0x01 << ( nNum
& 0x07 ));
1481 if( pChkStr
&& pChkStr
->Equals( rNm
) )
1487 // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
1488 nNum
= pSectionFmtTbl
->Count();
1489 for( n
= 0; n
< nFlagSize
; ++n
)
1490 if( 0xff != ( nTmp
= pSetFlags
[ n
] ))
1492 // also die Nummer bestimmen
1500 delete [] pSetFlags
;
1503 return aName
+= String::CreateFromInt32( ++nNum
);