xref: /aoo42x/main/sw/source/core/docnode/section.cxx (revision 713b4dcd)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <stdlib.h>
32 #include <hintids.hxx>
33 #include <svl/intitem.hxx>
34 #include <svl/stritem.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/docfilt.hxx>
37 #include <editeng/protitem.hxx>
38 #include <sfx2/linkmgr.hxx>
39 #include <tools/urlobj.hxx>
40 #include <sfx2/sfxsids.hrc>
41 #include <sfx2/fcontnr.hxx>
42 #include <docary.hxx>
43 #include <fmtcntnt.hxx>
44 #include <fmtpdsc.hxx>
45 #include <errhdl.hxx>
46 #include <doc.hxx>
47 #include <IDocumentUndoRedo.hxx>
48 #include <node.hxx>
49 #include <pam.hxx>
50 #include <frmtool.hxx>
51 #include <editsh.hxx>
52 #include <hints.hxx>
53 #include <docsh.hxx>
54 #include <ndtxt.hxx>
55 #include <section.hxx>
56 #include <swserv.hxx>
57 #include <shellio.hxx>
58 #include <poolfmt.hxx>
59 #include <expfld.hxx>
60 #include <swbaslnk.hxx>
61 #include <mvsave.hxx>
62 #include <sectfrm.hxx>
63 #include <fmtftntx.hxx>
64 #include <ftnidx.hxx>
65 #include <doctxm.hxx>
66 #include <fmteiro.hxx>
67 #include <swerror.h>
68 #include <unosection.hxx>
69 #include <switerator.hxx>
70 #include <svl/smplhint.hxx>
71 
72 using namespace ::com::sun::star;
73 
74 
75 SV_IMPL_REF( SwServerObject )
76 
77 //static const char __FAR_DATA sSectionFmtNm[] = "Section";
78 #define sSectionFmtNm aEmptyStr
79 
80 class SwIntrnlSectRefLink : public SwBaseLink
81 {
82 	SwSectionFmt& rSectFmt;
83 public:
84 	SwIntrnlSectRefLink( SwSectionFmt& rFmt, sal_uInt16 nUpdateType, sal_uInt16 nFmt )
85 		: SwBaseLink( nUpdateType, nFmt ),
86 		rSectFmt( rFmt )
87 	{}
88 
89 	virtual void Closed();
90 	virtual void DataChanged( const String& rMimeType,
91                                 const uno::Any & rValue );
92 
93 	virtual const SwNode* GetAnchor() const;
94 	virtual sal_Bool IsInRange( sal_uLong nSttNd, sal_uLong nEndNd, xub_StrLen nStt = 0,
95 							xub_StrLen nEnd = STRING_NOTFOUND ) const;
96 
97     // --> OD 2007-02-14 #b6521322#
98     inline SwSectionNode* GetSectNode()
99     {
100         const SwNode* pSectNd( const_cast<SwIntrnlSectRefLink*>(this)->GetAnchor() );
101         return const_cast<SwSectionNode*>( dynamic_cast<const SwSectionNode*>( pSectNd ) );
102     }
103     // <--
104 };
105 
106 
107 TYPEINIT1(SwSectionFmt,SwFrmFmt );
108 TYPEINIT1(SwSection,SwClient );
109 
110 typedef SwSection* SwSectionPtr;
111 
112 SV_IMPL_PTRARR( SwSections, SwSection*)
113 SV_IMPL_PTRARR(SwSectionFmts,SwSectionFmt*)
114 
115 
116 SwSectionData::SwSectionData(SectionType const eType, String const& rName)
117     : m_eType(eType)
118     , m_sSectionName(rName)
119     , m_bHiddenFlag(false)
120     , m_bProtectFlag(false)
121     // --> FME 2004-06-22 #114856# edit in readonly sections
122     , m_bEditInReadonlyFlag(false)
123     // <--
124     , m_bHidden(false)
125     , m_bCondHiddenFlag(true)
126     , m_bConnectFlag(true)
127 {
128 }
129 
130 // this must have the same semantics as operator=()
131 SwSectionData::SwSectionData(SwSection const& rSection)
132     : m_eType(rSection.GetType())
133     , m_sSectionName(rSection.GetSectionName())
134     , m_sCondition(rSection.GetCondition())
135     , m_sLinkFileName(rSection.GetLinkFileName())
136     , m_sLinkFilePassword(rSection.GetLinkFilePassword())
137     , m_Password(rSection.GetPassword())
138     , m_bHiddenFlag(rSection.IsHiddenFlag())
139     , m_bProtectFlag(rSection.IsProtect())
140     // --> FME 2004-06-22 #114856# edit in readonly sections
141     , m_bEditInReadonlyFlag(rSection.IsEditInReadonly())
142     // <--
143     , m_bHidden(rSection.IsHidden())
144     , m_bCondHiddenFlag(true)
145     , m_bConnectFlag(rSection.IsConnectFlag())
146 {
147 }
148 
149 // this must have the same semantics as operator=()
150 SwSectionData::SwSectionData(SwSectionData const& rOther)
151     : m_eType(rOther.m_eType)
152     , m_sSectionName(rOther.m_sSectionName)
153     , m_sCondition(rOther.m_sCondition)
154     , m_sLinkFileName(rOther.m_sLinkFileName)
155     , m_sLinkFilePassword(rOther.m_sLinkFilePassword)
156     , m_Password(rOther.m_Password)
157     , m_bHiddenFlag(rOther.m_bHiddenFlag)
158     , m_bProtectFlag(rOther.m_bProtectFlag)
159     // --> FME 2004-06-22 #114856# edit in readonly sections
160     , m_bEditInReadonlyFlag(rOther.m_bEditInReadonlyFlag)
161     // <--
162     , m_bHidden(rOther.m_bHidden)
163     , m_bCondHiddenFlag(true)
164     , m_bConnectFlag(rOther.m_bConnectFlag)
165 {
166 }
167 
168 // the semantics here are weird for reasons of backward compatibility
169 SwSectionData & SwSectionData::operator= (SwSectionData const& rOther)
170 {
171     m_eType = rOther.m_eType;
172     m_sSectionName = rOther.m_sSectionName;
173     m_sCondition = rOther.m_sCondition;
174     m_sLinkFileName = rOther.m_sLinkFileName;
175     m_sLinkFilePassword = rOther.m_sLinkFilePassword;
176     m_bConnectFlag = rOther.m_bConnectFlag;
177     m_Password = rOther.m_Password;
178 
179     m_bEditInReadonlyFlag = rOther.m_bEditInReadonlyFlag;
180     m_bProtectFlag = rOther.m_bProtectFlag;
181 
182     m_bHidden = rOther.m_bHidden;
183     // FIXME: old code did not assign m_bHiddenFlag ?
184     // FIXME: why should m_bCondHiddenFlag always default to true?
185     m_bCondHiddenFlag = true;
186 
187     return *this;
188 }
189 
190 // the semantics here are weird for reasons of backward compatibility
191 bool SwSectionData::operator==(SwSectionData const& rOther) const
192 {
193     return (m_eType == rOther.m_eType)
194         && (m_sSectionName == rOther.m_sSectionName)
195         && (m_sCondition == rOther.m_sCondition)
196         && (m_bHidden == rOther.m_bHidden)
197         && (m_bProtectFlag == rOther.m_bProtectFlag)
198         && (m_bEditInReadonlyFlag == rOther.m_bEditInReadonlyFlag)
199         && (m_sLinkFileName == rOther.m_sLinkFileName)
200         && (m_sLinkFilePassword == rOther.m_sLinkFilePassword)
201         && (m_Password == rOther.m_Password);
202     // FIXME: old code ignored m_bCondHiddenFlag m_bHiddenFlag m_bConnectFlag
203 }
204 
205 // SwSection ===========================================================
206 
207 SwSection::SwSection(
208         SectionType const eType, String const& rName, SwSectionFmt & rFormat)
209     : SwClient(& rFormat)
210     , m_Data(eType, rName)
211 {
212     SwSection *const pParentSect = GetParent();
213 	if( pParentSect )
214 	{
215 		if( pParentSect->IsHiddenFlag() )
216         {
217             SetHidden( true );
218         }
219 
220         m_Data.SetProtectFlag( pParentSect->IsProtectFlag() );
221         // --> FME 2004-06-22 #114856# edit in readonly sections
222         m_Data.SetEditInReadonlyFlag( pParentSect->IsEditInReadonlyFlag() );
223         // <--
224     }
225 
226     if (!m_Data.IsProtectFlag())
227     {
228         m_Data.SetProtectFlag( rFormat.GetProtect().IsCntntProtected() );
229     }
230 
231     // --> FME 2004-06-22 #114856# edit in readonly sections
232     if (!m_Data.IsEditInReadonlyFlag())
233     {
234         m_Data.SetEditInReadonlyFlag( rFormat.GetEditInReadonly().GetValue() );
235     }
236     // <--
237 }
238 
239 
240 SwSection::~SwSection()
241 {
242 	SwSectionFmt* pFmt = GetFmt();
243 	if( !pFmt )
244 		return;
245 
246 	SwDoc* pDoc = pFmt->GetDoc();
247 	if( pDoc->IsInDtor() )
248 	{
249 		// dann melden wir noch schnell unser Format um ans dflt FrameFmt,
250 		// damit es keine Abhaengigkeiten gibt
251 		if( pFmt->DerivedFrom() != pDoc->GetDfltFrmFmt() )
252             pFmt->RegisterToFormat( *pDoc->GetDfltFrmFmt() );
253 	}
254 	else
255 	{
256 		pFmt->Remove( this );				// austragen,
257 
258         if (CONTENT_SECTION != m_Data.GetType())
259         {
260             pDoc->GetLinkManager().Remove( m_RefLink );
261         }
262 
263         if (m_RefObj.Is())
264         {
265             pDoc->GetLinkManager().RemoveServer( &m_RefObj );
266         }
267 
268 		// ist die Section der letzte Client im Format, kann dieses
269 		// geloescht werden
270 		SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt );
271 		pFmt->ModifyNotification( &aMsgHint, &aMsgHint );
272 		if( !pFmt->GetDepends() )
273 		{
274 			// Bug: 28191 - nicht ins Undo aufnehmen, sollte schon vorher
275 			//			geschehen sein!!
276             ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
277 			pDoc->DelSectionFmt( pFmt );	// und loeschen
278         }
279     }
280     if (m_RefObj.Is())
281     {
282         m_RefObj->Closed();
283     }
284 }
285 
286 void SwSection::SetSectionData(SwSectionData const& rData)
287 {
288     bool const bOldHidden( m_Data.IsHidden() );
289     m_Data = rData;
290     // now update format and reflink with new data
291 //    SetLinkFileName(m_Data.GetLinkFileName()); // old code did not do this?
292     // next 2 may actually overwrite m_Data.m_b{Protect,EditInReadonly}Flag
293     // in Modify, which should result in same flag value as the old code!
294     SetProtect(m_Data.IsProtectFlag());
295     SetEditInReadonly(m_Data.IsEditInReadonlyFlag());
296     if (bOldHidden != m_Data.IsHidden()) // check if changed...
297     {
298         ImplSetHiddenFlag(m_Data.IsHidden(), m_Data.IsCondHidden());
299     }
300 }
301 
302 bool SwSection::DataEquals(SwSectionData const& rCmp) const
303 {
304     // note that the old code compared the flags of the parameter with the
305     // format attributes of this; the following mess should do the same...
306     (void) GetLinkFileName(); // updates m_sLinkFileName
307     bool const bProtect(m_Data.IsProtectFlag());
308     bool const bEditInReadonly(m_Data.IsEditInReadonlyFlag());
309     const_cast<SwSection*>(this)->m_Data.SetProtectFlag(IsProtect());
310     const_cast<SwSection*>(this)->m_Data
311         .SetEditInReadonlyFlag(IsEditInReadonly());
312     bool const bResult( m_Data == rCmp );
313     const_cast<SwSection*>(this)->m_Data.SetProtectFlag(bProtect);
314     const_cast<SwSection*>(this)->m_Data.SetEditInReadonlyFlag(bEditInReadonly);
315     return bResult;
316 }
317 
318 
319 void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
320 {
321 	SwSectionFmt* pFmt = GetFmt();
322     ASSERT(pFmt, "ImplSetHiddenFlag: no format?");
323 	if( pFmt )
324 	{
325         const bool bHide = bTmpHidden && bCondition;
326 
327         if (bHide) // should be hidden
328         {
329             if (!m_Data.IsHiddenFlag()) // is not hidden
330             {
331 				// wie sieht es mit dem Parent aus, ist der versteckt ?
332 				// (eigentlich muesste das vom bHiddenFlag angezeigt werden!)
333 
334 				// erstmal allen Childs sagen, das sie versteckt sind
335 				SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN );
336 				pFmt->ModifyNotification( &aMsgItem, &aMsgItem );
337 
338 				// alle Frames loeschen
339 				pFmt->DelFrms();
340 			}
341         }
342         else if (m_Data.IsHiddenFlag()) // show Nodes again
343         {
344 			// alle Frames sichtbar machen ( Childs Sections werden vom
345 			// MakeFrms beruecksichtigt). Aber nur wenn die ParentSection
346 			// nichts dagegen hat !
347 			SwSection* pParentSect = pFmt->GetParentSection();
348 			if( !pParentSect || !pParentSect->IsHiddenFlag() )
349 			{
350 				// erstmal allen Childs sagen, das der Parent nicht mehr
351 				// versteckt ist
352 				SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN );
353 				pFmt->ModifyNotification( &aMsgItem, &aMsgItem );
354 
355 				pFmt->MakeFrms();
356 			}
357 		}
358 	}
359 }
360 
361 sal_Bool SwSection::CalcHiddenFlag() const
362 {
363 	const SwSection* pSect = this;
364 	do {
365 		if( pSect->IsHidden() && pSect->IsCondHidden() )
366 			return sal_True;
367 	} while( 0 != ( pSect = pSect->GetParent()) );
368 
369 	return sal_False;
370 }
371 
372 bool SwSection::IsProtect() const
373 {
374     SwSectionFmt *const pFmt( GetFmt() );
375     ASSERT(pFmt, "SwSection::IsProtect: no format?");
376     return (pFmt)
377         ?   pFmt->GetProtect().IsCntntProtected()
378         :   IsProtectFlag();
379 }
380 
381 // --> FME 2004-06-22 #114856# edit in readonly sections
382 bool SwSection::IsEditInReadonly() const
383 {
384     SwSectionFmt *const pFmt( GetFmt() );
385     ASSERT(pFmt, "SwSection::IsEditInReadonly: no format?");
386     return (pFmt)
387         ?   pFmt->GetEditInReadonly().GetValue()
388         :   IsEditInReadonlyFlag();
389 }
390 // <--
391 
392 void SwSection::SetHidden(bool const bFlag)
393 {
394     if (!m_Data.IsHidden() == !bFlag)
395 		return;
396 
397     m_Data.SetHidden(bFlag);
398     ImplSetHiddenFlag(bFlag, m_Data.IsCondHidden());
399 }
400 
401 
402 void SwSection::SetProtect(bool const bFlag)
403 {
404     SwSectionFmt *const pFormat( GetFmt() );
405     ASSERT(pFormat, "SwSection::SetProtect: no format?");
406     if (pFormat)
407     {
408         SvxProtectItem aItem( RES_PROTECT );
409 		aItem.SetCntntProtect( (sal_Bool)bFlag );
410         pFormat->SetFmtAttr( aItem );
411         // note: this will call m_Data.SetProtectFlag via Modify!
412     }
413     else
414     {
415         m_Data.SetProtectFlag(bFlag);
416     }
417 }
418 
419 // --> FME 2004-06-22 #114856# edit in readonly sections
420 void SwSection::SetEditInReadonly(bool const bFlag)
421 {
422     SwSectionFmt *const pFormat( GetFmt() );
423     ASSERT(pFormat, "SwSection::SetEditInReadonly: no format?");
424     if (pFormat)
425     {
426         SwFmtEditInReadonly aItem;
427         aItem.SetValue( (sal_Bool)bFlag );
428         pFormat->SetFmtAttr( aItem );
429         // note: this will call m_Data.SetEditInReadonlyFlag via Modify!
430     }
431     else
432     {
433         m_Data.SetEditInReadonlyFlag(bFlag);
434     }
435 }
436 // <--
437 
438 void SwSection::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
439 {
440     bool bRemake = false;
441     bool bUpdateFtn = false;
442 	switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
443 	{
444 	case RES_ATTRSET_CHG:
445 		{
446 			SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
447 			SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
448 			const SfxPoolItem* pItem;
449 
450 			if( SFX_ITEM_SET == pNewSet->GetItemState(
451 						RES_PROTECT, sal_False, &pItem ) )
452 			{
453                 m_Data.SetProtectFlag( static_cast<SvxProtectItem const*>(pItem)
454                         ->IsCntntProtected() );
455 				pNewSet->ClearItem( RES_PROTECT );
456 				pOldSet->ClearItem( RES_PROTECT );
457 			}
458 
459             // --> FME 2004-06-22 #114856# edit in readonly sections
460             if( SFX_ITEM_SET == pNewSet->GetItemState(
461                         RES_EDIT_IN_READONLY, sal_False, &pItem ) )
462             {
463                 m_Data.SetEditInReadonlyFlag(
464                     static_cast<SwFmtEditInReadonly const*>(pItem)->GetValue());
465                 pNewSet->ClearItem( RES_EDIT_IN_READONLY );
466                 pOldSet->ClearItem( RES_EDIT_IN_READONLY );
467             }
468             // <--
469 
470 			if( SFX_ITEM_SET == pNewSet->GetItemState(
471 						RES_FTN_AT_TXTEND, sal_False, &pItem ) ||
472 				SFX_ITEM_SET == pNewSet->GetItemState(
473 						RES_END_AT_TXTEND, sal_False, &pItem ))
474             {
475                     bUpdateFtn = true;
476             }
477 
478 			if( !pNewSet->Count() )
479 				return;
480 		}
481 		break;
482 
483 	case RES_PROTECT:
484 		if( pNew )
485 		{
486             bool bNewFlag =
487                 static_cast<const SvxProtectItem*>(pNew)->IsCntntProtected();
488 			if( !bNewFlag )
489 			{
490 				// Abschalten: teste ob nicht vielleich ueber die Parents
491 				// 				doch ein Schutzt besteht!
492 				const SwSection* pSect = this;
493 				do {
494 					if( pSect->IsProtect() )
495 					{
496                         bNewFlag = true;
497 						break;
498 					}
499                     pSect = pSect->GetParent();
500                 } while (pSect);
501             }
502 
503             m_Data.SetProtectFlag( bNewFlag );
504         }
505 		return;
506     // --> FME 2004-06-22 #114856# edit in readonly sections
507     case RES_EDIT_IN_READONLY:
508         if( pNew )
509         {
510             const bool bNewFlag =
511                 static_cast<const SwFmtEditInReadonly*>(pNew)->GetValue();
512             m_Data.SetEditInReadonlyFlag( bNewFlag );
513         }
514         return;
515     // <--
516 
517 	case RES_SECTION_HIDDEN:
518         m_Data.SetHiddenFlag(true);
519 		return;
520 
521 	case RES_SECTION_NOT_HIDDEN:
522 	case RES_SECTION_RESETHIDDENFLAG:
523         m_Data.SetHiddenFlag( m_Data.IsHidden() && m_Data.IsCondHidden() );
524 		return;
525 
526 	case RES_COL:
527 		/* wird ggf. vom Layout erledigt */
528 		break;
529 
530 	case RES_FTN_AT_TXTEND:
531 		if( pNew && pOld )
532         {
533             bUpdateFtn = true;
534         }
535 		break;
536 
537 	case RES_END_AT_TXTEND:
538 		if( pNew && pOld )
539         {
540             bUpdateFtn = true;
541         }
542 		break;
543 
544     default:
545 		CheckRegistration( pOld, pNew );
546         break;
547 	}
548 
549 	if( bRemake )
550 	{
551 		GetFmt()->DelFrms();
552 		GetFmt()->MakeFrms();
553 	}
554 
555 	if( bUpdateFtn )
556 	{
557 		SwSectionNode* pSectNd = GetFmt()->GetSectionNode( sal_False );
558 		if( pSectNd )
559 			pSectNd->GetDoc()->GetFtnIdxs().UpdateFtn(SwNodeIndex( *pSectNd ));
560 	}
561 }
562 
563 void SwSection::SetRefObject( SwServerObject* pObj )
564 {
565     m_RefObj = pObj;
566 }
567 
568 
569 void SwSection::SetCondHidden(bool const bFlag)
570 {
571     if (!m_Data.IsCondHidden() == !bFlag)
572 		return;
573 
574     m_Data.SetCondHidden(bFlag);
575     ImplSetHiddenFlag(m_Data.IsHidden(), bFlag);
576 }
577 
578 
579 // setze/erfrage den gelinkten FileNamen
580 const String& SwSection::GetLinkFileName() const
581 {
582     if (m_RefLink.Is())
583     {
584 		String sTmp;
585         switch (m_Data.GetType())
586 		{
587 		case DDE_LINK_SECTION:
588             sTmp = m_RefLink->GetLinkSourceName();
589 			break;
590 
591 		case FILE_LINK_SECTION:
592 			{
593 				String sRange, sFilter;
594                 if (m_RefLink->GetLinkManager() &&
595                     m_RefLink->GetLinkManager()->GetDisplayNames(
596                         m_RefLink, 0, &sTmp, &sRange, &sFilter ))
597                 {
598                     ( sTmp += sfx2::cTokenSeperator ) += sFilter;
599                     ( sTmp += sfx2::cTokenSeperator ) += sRange;
600 				}
601 				else if( GetFmt() && !GetFmt()->GetSectionNode() )
602 				{
603 					// ist die Section im UndoNodesArray, dann steht
604 					// der Link nicht im LinkManager, kann also auch nicht
605 					// erfragt werden. Dann returne den akt. Namen
606                     return m_Data.GetLinkFileName();
607 				}
608 			}
609 			break;
610         default: break;
611 		}
612         const_cast<SwSection*>(this)->m_Data.SetLinkFileName(sTmp);
613     }
614     return m_Data.GetLinkFileName();
615 }
616 
617 
618 void SwSection::SetLinkFileName(const String& rNew, String const*const pPassWd)
619 {
620     if (m_RefLink.Is())
621     {
622         m_RefLink->SetLinkSourceName( rNew );
623     }
624     m_Data.SetLinkFileName(rNew);
625 	if( pPassWd )
626     {
627         SetLinkFilePassword( *pPassWd );
628     }
629 }
630 
631 // falls es ein gelinkter Bereich war, dann muessen alle
632 // Child-Verknuepfungen sichtbar bemacht werden.
633 void SwSection::MakeChildLinksVisible( const SwSectionNode& rSectNd )
634 {
635 	const SwNode* pNd;
636     const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->GetLinkManager().GetLinks();
637 	for( sal_uInt16 n = rLnks.Count(); n; )
638 	{
639         ::sfx2::SvBaseLink* pBLnk = &(*rLnks[ --n ]);
640 		if( pBLnk && !pBLnk->IsVisible() &&
641 			pBLnk->ISA( SwBaseLink ) &&
642 			0 != ( pNd = ((SwBaseLink*)pBLnk)->GetAnchor() ) )
643 		{
644             pNd = pNd->StartOfSectionNode();    // falls SectionNode ist!
645 			const SwSectionNode* pParent;
646 			while( 0 != ( pParent = pNd->FindSectionNode() ) &&
647 					( CONTENT_SECTION == pParent->GetSection().GetType()
648 						|| pNd == &rSectNd ))
649                     pNd = pParent->StartOfSectionNode();
650 
651 			// steht nur noch in einer normalen Section, also
652 			// wieder anzeigen
653 			if( !pParent )
654 				pBLnk->SetVisible( sal_True );
655 		}
656 	}
657 }
658 
659 const SwTOXBase* SwSection::GetTOXBase() const
660 {
661 	const SwTOXBase* pRet = 0;
662 	if( TOX_CONTENT_SECTION == GetType() )
663 		pRet = PTR_CAST( SwTOXBaseSection, this );
664 	return pRet;
665 }
666 
667 // SwSectionFmt ========================================================
668 
669 SwSectionFmt::SwSectionFmt( SwSectionFmt* pDrvdFrm, SwDoc *pDoc )
670 	: SwFrmFmt( pDoc->GetAttrPool(), sSectionFmtNm, pDrvdFrm )
671 {
672 	LockModify();
673     SetFmtAttr( *GetDfltAttr( RES_COL ) );
674 	UnlockModify();
675 }
676 
677 SwSectionFmt::~SwSectionFmt()
678 {
679 	if( !GetDoc()->IsInDtor() )
680 	{
681 		SwSectionNode* pSectNd;
682 		const SwNodeIndex* pIdx = GetCntnt( sal_False ).GetCntntIdx();
683 		if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
684 			0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
685 		{
686 			SwSection& rSect = pSectNd->GetSection();
687 			// falls es ein gelinkter Bereich war, dann muessen alle
688 			// Child-Verknuepfungen sichtbar bemacht werden.
689 			if( rSect.IsConnected() )
690 				rSect.MakeChildLinksVisible( *pSectNd );
691 
692 			// vorm loeschen der Nodes pruefe, ob wir uns nicht
693 			// noch anzeigen muessen!
694 			if( rSect.IsHiddenFlag() )
695 			{
696 				SwSectionPtr pParentSect = rSect.GetParent();
697 				if( !pParentSect || !pParentSect->IsHiddenFlag() )
698 				{
699 					// Nodes wieder anzeigen
700                     rSect.SetHidden(false);
701 				}
702 			}
703             // mba: test iteration; objects are removed while iterating
704             // --> OD #i117863#
705             // use hint which allows to specify, if the content shall be saved or not
706             CallSwClientNotify( SwSectionFrmMoveAndDeleteHint( sal_True ) );
707             // <--
708 
709 			// hebe die Section doch mal auf
710 			SwNodeRange aRg( *pSectNd, 0, *pSectNd->EndOfSectionNode() );
711 			GetDoc()->GetNodes().SectionUp( &aRg );
712 		}
713 		LockModify();
714         ResetFmtAttr( RES_CNTNT );
715 		UnlockModify();
716 	}
717 }
718 
719 
720 SwSection * SwSectionFmt::GetSection() const
721 {
722 	return SwIterator<SwSection,SwSectionFmt>::FirstElement( *this );
723 }
724 
725 extern void lcl_DeleteFtn( SwSectionNode *pNd, sal_uLong nStt, sal_uLong nEnd );
726 
727 //Vernichtet alle Frms in aDepend (Frms werden per PTR_CAST erkannt).
728 void SwSectionFmt::DelFrms()
729 {
730 	SwSectionNode* pSectNd;
731 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
732 	if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
733 		0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
734 	{
735         // #147431# : First delete the <SwSectionFrm> of the <SwSectionFmt> instance
736         // mba: test iteration as objects are removed in iteration
737         // --> OD #i117863#
738         // use hint which allows to specify, if the content shall be saved or not
739         CallSwClientNotify( SwSectionFrmMoveAndDeleteHint( sal_False ) );
740         // <--
741 
742         // Then delete frames of the nested <SwSectionFmt> instances
743         SwIterator<SwSectionFmt,SwSectionFmt> aIter( *this );
744         SwSectionFmt *pLast = aIter.First();
745         while ( pLast )
746         {
747             pLast->DelFrms();
748             pLast = aIter.Next();
749         }
750 
751 		sal_uLong nEnde = pSectNd->EndOfSectionIndex();
752 		sal_uLong nStart = pSectNd->GetIndex()+1;
753 		lcl_DeleteFtn( pSectNd, nStart, nEnde );
754 	}
755 	if( pIdx )
756 	{
757 		//JP 22.09.98:
758 		//Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im
759 		//Paste der Frames selbst erledigen, aber das fuehrt dann wiederum
760 		//zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden
761 		//muesten. #56977# #55001# #56135#
762 		SwNodeIndex aNextNd( *pIdx );
763 		SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, sal_True, sal_False );
764 		if( pCNd )
765 		{
766 			const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC );
767 			pCNd->ModifyNotification( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem );
768 		}
769 	}
770 }
771 
772 
773 //Erzeugt die Ansichten
774 void SwSectionFmt::MakeFrms()
775 {
776 	SwSectionNode* pSectNd;
777 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
778 
779 	if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
780 		0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
781 	{
782 		SwNodeIndex aIdx( *pIdx );
783 		pSectNd->MakeFrms( &aIdx );
784 	}
785 }
786 
787 void SwSectionFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
788 {
789 	sal_Bool bClients = sal_False;
790 	sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
791 	switch( nWhich )
792 	{
793 	case RES_ATTRSET_CHG:
794 		if( GetDepends() )
795 		{
796 			SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
797 			SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
798 			const SfxPoolItem *pItem;
799 			if( SFX_ITEM_SET == pNewSet->GetItemState(
800 										RES_PROTECT, sal_False, &pItem ))
801 			{
802 				ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
803 				pNewSet->ClearItem( RES_PROTECT );
804 				pOldSet->ClearItem( RES_PROTECT );
805 			}
806 
807             // --> FME 2004-06-22 #114856# edit in readonly sections
808             if( SFX_ITEM_SET == pNewSet->GetItemState(
809                         RES_EDIT_IN_READONLY, sal_False, &pItem ) )
810             {
811 				ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
812                 pNewSet->ClearItem( RES_EDIT_IN_READONLY );
813                 pOldSet->ClearItem( RES_EDIT_IN_READONLY );
814             }
815             // <--
816 
817 			if( SFX_ITEM_SET == pNewSet->GetItemState(
818 									RES_FTN_AT_TXTEND, sal_False, &pItem ))
819 			{
820 				ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_FTN_AT_TXTEND ), (SfxPoolItem*)pItem );
821 				pNewSet->ClearItem( RES_FTN_AT_TXTEND );
822 				pOldSet->ClearItem( RES_FTN_AT_TXTEND );
823 			}
824 			if( SFX_ITEM_SET == pNewSet->GetItemState(
825 									RES_END_AT_TXTEND, sal_False, &pItem ))
826 			{
827 				ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_END_AT_TXTEND ), (SfxPoolItem*)pItem );
828 				pNewSet->ClearItem( RES_END_AT_TXTEND );
829 				pOldSet->ClearItem( RES_END_AT_TXTEND );
830 			}
831 			if( !((SwAttrSetChg*)pOld)->GetChgSet()->Count() )
832 				return;
833 		}
834 		break;
835 
836 	case RES_SECTION_RESETHIDDENFLAG:
837 	case RES_FTN_AT_TXTEND:
838 	case RES_END_AT_TXTEND : bClients = sal_True;
839 							// no break !!
840 	case RES_SECTION_HIDDEN:
841 	case RES_SECTION_NOT_HIDDEN:
842 		{
843 			SwSection* pSect = GetSection();
844 			if( pSect && ( bClients || ( RES_SECTION_HIDDEN == nWhich ?
845 							!pSect->IsHiddenFlag() : pSect->IsHiddenFlag() ) ) )
846 			{
847                 ModifyBroadcast( pOld, pNew );
848 			}
849 		}
850 		return ;
851 
852 
853 	case RES_PROTECT:
854     // --> FME 2004-06-22 #114856# edit in readonly sections
855     case RES_EDIT_IN_READONLY:
856     // <--
857         // diese Messages bis zum Ende des Baums durchreichen !
858 		if( GetDepends() )
859 		{
860             ModifyBroadcast( pOld, pNew );
861 		}
862 		return; 	// das wars
863 
864     case RES_OBJECTDYING:
865 		if( !GetDoc()->IsInDtor() &&
866 			((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() )
867 		{
868 			// mein Parent wird vernichtet, dann an den Parent vom Parent
869 			// umhaengen und wieder aktualisieren
870 			SwFrmFmt::Modify( pOld, pNew ); 	//	erst umhaengen !!!
871 			UpdateParent();
872 			return;
873 		}
874 		break;
875 
876 	case RES_FMT_CHG:
877 		if( !GetDoc()->IsInDtor() &&
878 			((SwFmtChg*)pNew)->pChangedFmt == (void*)GetRegisteredIn() &&
879 			((SwFmtChg*)pNew)->pChangedFmt->IsA( TYPE( SwSectionFmt )) )
880 		{
881 			// mein Parent wird veraendert, muss mich aktualisieren
882 			SwFrmFmt::Modify( pOld, pNew ); 	//	erst umhaengen !!!
883 			UpdateParent();
884 			return;
885 		}
886 		break;
887 	}
888 	SwFrmFmt::Modify( pOld, pNew );
889 
890     if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
891     {   // invalidate cached uno object
892         SetXTextSection(uno::Reference<text::XTextSection>(0));
893     }
894 }
895 
896 		// erfrage vom Format Informationen
897 sal_Bool SwSectionFmt::GetInfo( SfxPoolItem& rInfo ) const
898 {
899 	switch( rInfo.Which() )
900 	{
901 	case RES_FINDNEARESTNODE:
902         if( ((SwFmtPageDesc&)GetFmtAttr( RES_PAGEDESC )).GetPageDesc() )
903 		{
904 			const SwSectionNode* pNd = GetSectionNode();
905 			if( pNd )
906 				((SwFindNearestNode&)rInfo).CheckNode( *pNd );
907 		}
908 		return sal_True;
909 
910 	case RES_CONTENT_VISIBLE:
911 		{
912 			SwFrm* pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*this);
913 			// if the current section has no own frame search for the children
914 			if(!pFrm)
915 			{
916                 SwIterator<SwSectionFmt,SwSectionFmt> aFormatIter(*this);
917 				SwSectionFmt* pChild = aFormatIter.First();
918 				while(pChild && !pFrm)
919 				{
920         			pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*pChild);
921 					pChild = aFormatIter.Next();
922 				}
923 			}
924 			((SwPtrMsgPoolItem&)rInfo).pObject = pFrm;
925 		}
926 		return sal_False;
927 	}
928 	return SwModify::GetInfo( rInfo );
929 }
930 
931 extern "C" {
932 
933 	int
934 #if defined( WNT )
935  	__cdecl
936 #endif
937 #if defined( ICC )
938  	_Optlink
939 #endif
940 		lcl_SectionCmpPos( const void *pFirst, const void *pSecond)
941 	{
942 		const SwSectionFmt* pFSectFmt = (*(SwSectionPtr*)pFirst)->GetFmt();
943 		const SwSectionFmt* pSSectFmt = (*(SwSectionPtr*)pSecond)->GetFmt();
944 		ASSERT( pFSectFmt && pSSectFmt &&
945 				pFSectFmt->GetCntnt(sal_False).GetCntntIdx() &&
946 				pSSectFmt->GetCntnt(sal_False).GetCntntIdx(),
947 					"ungueltige Sections" );
948 		return (int)((long)pFSectFmt->GetCntnt(sal_False).GetCntntIdx()->GetIndex()) -
949 				  	pSSectFmt->GetCntnt(sal_False).GetCntntIdx()->GetIndex();
950 	}
951 
952 	int
953 #if defined( WNT )
954  	__cdecl
955 #endif
956 #if defined( ICC )
957  	_Optlink
958 #endif
959 		lcl_SectionCmpNm( const void *pFirst, const void *pSecond)
960 	{
961 		const SwSectionPtr pFSect = *(SwSectionPtr*)pFirst;
962 		const SwSectionPtr pSSect = *(SwSectionPtr*)pSecond;
963 		ASSERT( pFSect && pSSect, "ungueltige Sections" );
964         StringCompare const eCmp =
965             pFSect->GetSectionName().CompareTo( pSSect->GetSectionName() );
966 		return eCmp == COMPARE_EQUAL ? 0
967 							: eCmp == COMPARE_LESS ? 1 : -1;
968 	}
969 }
970 
971 	// alle Sections, die von dieser abgeleitet sind
972 sal_uInt16 SwSectionFmt::GetChildSections( SwSections& rArr,
973 										SectionSort eSort,
974 										sal_Bool bAllSections ) const
975 {
976 	rArr.Remove( 0, rArr.Count() );
977 
978 	if( GetDepends() )
979 	{
980         SwIterator<SwSectionFmt,SwSectionFmt> aIter(*this);
981 		const SwNodeIndex* pIdx;
982 		for( SwSectionFmt* pLast = aIter.First(); pLast; pLast = aIter.Next() )
983 			if( bAllSections ||
984 				( 0 != ( pIdx = pLast->GetCntnt(sal_False).
985 				GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
986 			{
987 				const SwSection* Dummy = pLast->GetSection();
988 				rArr.C40_INSERT( SwSection,
989 					Dummy,
990 					rArr.Count() );
991 			}
992 
993 		// noch eine Sortierung erwuenscht ?
994 		if( 1 < rArr.Count() )
995 			switch( eSort )
996 			{
997 			case SORTSECT_NAME:
998 				qsort( (void*)rArr.GetData(),
999 						rArr.Count(),
1000 						sizeof( SwSectionPtr ),
1001 						lcl_SectionCmpNm );
1002 				break;
1003 
1004 			case SORTSECT_POS:
1005 				qsort( (void*)rArr.GetData(),
1006 						rArr.Count(),
1007 						sizeof( SwSectionPtr ),
1008 						lcl_SectionCmpPos );
1009 				break;
1010             case SORTSECT_NOT: break;
1011 			}
1012 	}
1013 	return rArr.Count();
1014 }
1015 
1016 	// erfrage, ob sich die Section im Nodes-Array oder UndoNodes-Array
1017 	// befindet.
1018 sal_Bool SwSectionFmt::IsInNodesArr() const
1019 {
1020 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
1021 	return pIdx && &pIdx->GetNodes() == &GetDoc()->GetNodes();
1022 }
1023 
1024 
1025 void SwSectionFmt::UpdateParent()		// Parent wurde veraendert
1026 {
1027 	if( !GetDepends() )
1028 		return;
1029 
1030 	SwSectionPtr pSection = 0;
1031 	const SvxProtectItem* pProtect(0);
1032     // --> FME 2004-06-22 #114856# edit in readonly sections
1033     const SwFmtEditInReadonly* pEditInReadonly = 0;
1034     // <--
1035     bool bIsHidden = false;
1036 
1037 	SwClientIter aIter( *this );    // TODO
1038 	::SwClient * pLast = aIter.GoStart();
1039 	if( pLast ) 	// konnte zum Anfang gesprungen werden ??
1040 		do {
1041 			if( pLast->IsA( TYPE(SwSectionFmt) ) )
1042 			{
1043 				if( !pSection )
1044 				{
1045 					pSection = GetSection();
1046 					if( GetRegisteredIn() )
1047 					{
1048 						const SwSectionPtr pPS = GetParentSection();
1049 						pProtect = &pPS->GetFmt()->GetProtect();
1050                         // --> FME 2004-06-22 #114856# edit in readonly sections
1051                         pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly();
1052                         // <--
1053 						bIsHidden = pPS->IsHiddenFlag();
1054 					}
1055 					else
1056 					{
1057 						pProtect = &GetProtect();
1058                         // --> FME 2004-06-22 #114856# edit in readonly sections
1059                         pEditInReadonly = &GetEditInReadonly();
1060                         // <--
1061                         bIsHidden = pSection->IsHidden();
1062 					}
1063 				}
1064                 if (!pProtect->IsCntntProtected() !=
1065                     !pSection->IsProtectFlag())
1066                 {
1067 					pLast->ModifyNotification( (SfxPoolItem*)pProtect,
1068 									(SfxPoolItem*)pProtect );
1069                 }
1070 
1071                 // --> FME 2004-06-22 #114856# edit in readonly sections
1072                 if (!pEditInReadonly->GetValue() !=
1073                     !pSection->IsEditInReadonlyFlag())
1074                 {
1075                     pLast->ModifyNotification( (SfxPoolItem*)pEditInReadonly,
1076                                     (SfxPoolItem*)pEditInReadonly );
1077                 }
1078                 // <--
1079 
1080 				if( bIsHidden == pSection->IsHiddenFlag() )
1081 				{
1082 					SwMsgPoolItem aMsgItem( static_cast<sal_uInt16>(bIsHidden
1083 								? RES_SECTION_HIDDEN
1084 								: RES_SECTION_NOT_HIDDEN ) );
1085 					pLast->ModifyNotification( &aMsgItem, &aMsgItem );
1086 				}
1087 			}
1088 			else if( !pSection &&
1089 					pLast->IsA( TYPE(SwSection) ) )
1090 			{
1091 				pSection = (SwSectionPtr)pLast;
1092 				if( GetRegisteredIn() )
1093 				{
1094 					const SwSectionPtr pPS = GetParentSection();
1095 					pProtect = &pPS->GetFmt()->GetProtect();
1096                     // --> FME 2004-06-22 #114856# edit in readonly sections
1097                     pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly();
1098                     // <--
1099 					bIsHidden = pPS->IsHiddenFlag();
1100 				}
1101 				else
1102 				{
1103 					pProtect = &GetProtect();
1104                     // --> FME 2004-06-22 #114856# edit in readonly sections
1105                     pEditInReadonly = &GetEditInReadonly();
1106                     // <--
1107                     bIsHidden = pSection->IsHidden();
1108 				}
1109 			}
1110 		} while( 0 != ( pLast = aIter++ ));
1111 }
1112 
1113 
1114 SwSectionNode* SwSectionFmt::GetSectionNode(bool const bAlways)
1115 {
1116 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
1117 	if( pIdx && ( bAlways || &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
1118 		return pIdx->GetNode().GetSectionNode();
1119 	return 0;
1120 }
1121 
1122 	// ist die Section eine gueltige fuers GlobalDocument?
1123 const SwSection* SwSectionFmt::GetGlobalDocSection() const
1124 {
1125 	const SwSectionNode* pNd = GetSectionNode();
1126 	if( pNd &&
1127 		( FILE_LINK_SECTION == pNd->GetSection().GetType() ||
1128 		  TOX_CONTENT_SECTION == pNd->GetSection().GetType() ) &&
1129 		pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() &&
1130         !pNd->StartOfSectionNode()->IsSectionNode() &&
1131         !pNd->StartOfSectionNode()->FindSectionNode() )
1132 		return &pNd->GetSection();
1133 	return 0;
1134 }
1135 
1136 // sw::Metadatable
1137 ::sfx2::IXmlIdRegistry& SwSectionFmt::GetRegistry()
1138 {
1139     return GetDoc()->GetXmlIdRegistry();
1140 }
1141 
1142 bool SwSectionFmt::IsInClipboard() const
1143 {
1144     return GetDoc()->IsClipBoard();
1145 }
1146 
1147 bool SwSectionFmt::IsInUndo() const
1148 {
1149     return !IsInNodesArr();
1150 }
1151 
1152 bool SwSectionFmt::IsInContent() const
1153 {
1154     SwNodeIndex const*const pIdx = GetCntnt(sal_False).GetCntntIdx();
1155     OSL_ENSURE(pIdx, "SwSectionFmt::IsInContent: no index?");
1156     return (pIdx) ? !GetDoc()->IsInHeaderFooter(*pIdx) : true;
1157 }
1158 
1159 // n.b.: if the section format represents an index, then there is both a
1160 // SwXDocumentIndex and a SwXTextSection instance for this single core object.
1161 // these two can both implement XMetadatable and forward to the same core
1162 // section format.  but here only one UNO object can be returned,
1163 // so always return the text section.
1164 uno::Reference< rdf::XMetadatable >
1165 SwSectionFmt::MakeUnoObject()
1166 {
1167     uno::Reference<rdf::XMetadatable> xMeta;
1168     SwSection *const pSection( GetSection() );
1169     if (pSection)
1170     {
1171         xMeta.set(  SwXTextSection::CreateXTextSection(this,
1172                         TOX_HEADER_SECTION == pSection->GetType()),
1173                     uno::UNO_QUERY );
1174     }
1175     return xMeta;
1176 }
1177 
1178 
1179 // --> OD 2007-02-14 #b6521322#
1180 // Method to break section links inside a linked section
1181 void lcl_BreakSectionLinksInSect( const SwSectionNode& rSectNd )
1182 {
1183     if ( !rSectNd.GetDoc() )
1184     {
1185         ASSERT( false,
1186                 "method <lcl_RemoveSectionLinksInSect(..)> - no Doc at SectionNode" );
1187         return;
1188     }
1189 
1190     if ( !rSectNd.GetSection().IsConnected() )
1191     {
1192         ASSERT( false,
1193                 "method <lcl_RemoveSectionLinksInSect(..)> - no Link at Section of SectionNode" );
1194         return;
1195     }
1196     const ::sfx2::SvBaseLink* pOwnLink( &(rSectNd.GetSection().GetBaseLink() ) );
1197     const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->GetLinkManager().GetLinks();
1198     for ( sal_uInt16 n = rLnks.Count(); n > 0; )
1199     {
1200         SwIntrnlSectRefLink* pSectLnk = dynamic_cast<SwIntrnlSectRefLink*>(&(*rLnks[ --n ]));
1201         if ( pSectLnk && pSectLnk != pOwnLink &&
1202              pSectLnk->IsInRange( rSectNd.GetIndex(), rSectNd.EndOfSectionIndex() ) )
1203         {
1204             // break the link of the corresponding section.
1205             // the link is also removed from the link manager
1206             pSectLnk->GetSectNode()->GetSection().BreakLink();
1207 
1208             // for robustness, because link is removed from the link manager
1209             if ( n > rLnks.Count() )
1210             {
1211                 n = rLnks.Count();
1212             }
1213         }
1214     }
1215 }
1216 // <--
1217 
1218 void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd )
1219 {
1220 	SwDoc* pDoc = rSectNd.GetDoc();
1221 	SwDocShell* pDShell = pDoc->GetDocShell();
1222 	if( !pDShell || !pDShell->GetMedium() )
1223 		return ;
1224 
1225 	String sName( pDShell->GetMedium()->GetName() );
1226 	SwBaseLink* pBLink;
1227 	String sMimeType( SotExchange::GetFormatMimeType( FORMAT_FILE ));
1228     uno::Any aValue;
1229 	aValue <<= ::rtl::OUString( sName );						// beliebiger Name
1230 
1231     const ::sfx2::SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks();
1232 	for( sal_uInt16 n = rLnks.Count(); n; )
1233 	{
1234         ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
1235 		if( pLnk && pLnk != &rUpdLnk &&
1236 			OBJECT_CLIENT_FILE == pLnk->GetObjType() &&
1237 			pLnk->ISA( SwBaseLink ) &&
1238 			( pBLink = (SwBaseLink*)pLnk )->IsInRange( rSectNd.GetIndex(),
1239 												rSectNd.EndOfSectionIndex() ) )
1240 		{
1241 			// liegt in dem Bereich: also updaten. Aber nur wenns nicht
1242 			// im gleichen File liegt
1243 			String sFName;
1244 			pDoc->GetLinkManager().GetDisplayNames( pBLink, 0, &sFName, 0, 0 );
1245 			if( sFName != sName )
1246 			{
1247 				pBLink->DataChanged( sMimeType, aValue );
1248 
1249 				// ggfs. neu den Link-Pointer wieder suchen, damit nicht einer
1250 				// ausgelassen oder doppelt gerufen wird.
1251 				if( n >= rLnks.Count() && 0 != ( n = rLnks.Count() ))
1252 					--n;
1253 
1254 				if( n && pLnk != &(*rLnks[ n ]) )
1255 				{
1256 					// suchen - kann nur davor liegen!!
1257 					while( n )
1258 						if( pLnk == &(*rLnks[ --n ] ) )
1259 							break;
1260 				}
1261 			}
1262 		}
1263 	}
1264 }
1265 
1266 
1267 // sucht sich die richtige DocShell raus oder erzeugt eine neue:
1268 // Der Return-Wert gibt an, was mit der Shell zu geschehen hat:
1269 //	0 - Fehler, konnte DocShell nicht finden
1270 //	1 - DocShell ist ein existieren Document
1271 //	2 - DocShell wurde neu angelegt, muss also wieder geschlossen werden ( will be assigned to xLockRef additionaly )
1272 
1273 int lcl_FindDocShell( SfxObjectShellRef& xDocSh,
1274                         SfxObjectShellLock& xLockRef,
1275 						const String& rFileName,
1276 						const String& rPasswd,
1277 						String& rFilter,
1278 						sal_Int16 nVersion,
1279 						SwDocShell* pDestSh )
1280 {
1281 	if( !rFileName.Len() )
1282 		return 0;
1283 
1284 	// 1. existiert die Datei schon in der Liste aller Dokumente?
1285 	INetURLObject aTmpObj( rFileName );
1286 	aTmpObj.SetMark( aEmptyStr );
1287 
1288 	// erstmal nur ueber die DocumentShells laufen und die mit dem
1289 	// Namen heraussuchen:
1290 	TypeId aType( TYPE(SwDocShell) );
1291 
1292 	SfxObjectShell* pShell = pDestSh;
1293 	sal_Bool bFirst = 0 != pShell;
1294 
1295 	if( !bFirst )
1296 		// keine DocShell uebergeben, also beginne mit der ersten aus der
1297 		// DocShell Liste
1298 		pShell = SfxObjectShell::GetFirst( &aType );
1299 
1300 	while( pShell )
1301 	{
1302 		// die wollen wir haben
1303 		SfxMedium* pMed = pShell->GetMedium();
1304 		if( pMed && pMed->GetURLObject() == aTmpObj )
1305 		{
1306 			const SfxPoolItem* pItem;
1307 			if( ( SFX_ITEM_SET == pMed->GetItemSet()->GetItemState(
1308 											SID_VERSION, sal_False, &pItem ) )
1309 					? (nVersion == ((SfxInt16Item*)pItem)->GetValue())
1310 					: !nVersion )
1311 			{
1312 				// gefunden also returnen
1313 				xDocSh = pShell;
1314 				return 1;
1315 			}
1316 		}
1317 
1318 		if( bFirst )
1319 		{
1320 			bFirst = sal_False;
1321 			pShell = SfxObjectShell::GetFirst( &aType );
1322 		}
1323 		else
1324 			pShell = SfxObjectShell::GetNext( *pShell, &aType );
1325 	}
1326 
1327 	// 2. selbst die Date oeffnen
1328 	SfxMedium* pMed = new SfxMedium( aTmpObj.GetMainURL(
1329 							 INetURLObject::NO_DECODE ), STREAM_READ, sal_True );
1330 	if( INET_PROT_FILE == aTmpObj.GetProtocol() )
1331 		pMed->DownLoad(); 	  // nur mal das Medium anfassen (DownLoaden)
1332 
1333 	const SfxFilter* pSfxFlt = 0;
1334 	if( !pMed->GetError() )
1335 	{
1336         String sFactory(String::CreateFromAscii(SwDocShell::Factory().GetShortName()));
1337         SfxFilterMatcher aMatcher( sFactory );
1338 
1339         // kein Filter, dann suche ihn. Ansonsten teste, ob der angegebene
1340 		// ein gueltiger ist
1341 		if( rFilter.Len() )
1342 		{
1343             pSfxFlt = aMatcher.GetFilter4FilterName( rFilter );
1344 		}
1345 
1346 		if( nVersion )
1347 			pMed->GetItemSet()->Put( SfxInt16Item( SID_VERSION, nVersion ));
1348 
1349 		if( rPasswd.Len() )
1350 			pMed->GetItemSet()->Put( SfxStringItem( SID_PASSWORD, rPasswd ));
1351 
1352 		if( !pSfxFlt )
1353             aMatcher.DetectFilter( *pMed, &pSfxFlt, sal_False, sal_False );
1354 
1355 		if( pSfxFlt )
1356 		{
1357 			// ohne Filter geht gar nichts
1358 			pMed->SetFilter( pSfxFlt );
1359 
1360             // if the new shell is created, SfxObjectShellLock should be used to let it be closed later for sure
1361 			xLockRef = new SwDocShell( SFX_CREATE_MODE_INTERNAL );
1362             xDocSh = (SfxObjectShell*)xLockRef;
1363 			if( xDocSh->DoLoad( pMed ) )
1364 				return 2;
1365 		}
1366 	}
1367 
1368 	if( !xDocSh.Is() )		// Medium muss noch geloescht werden
1369 		delete pMed;
1370 
1371 	return 0;	// das war wohl nichts
1372 }
1373 
1374 
1375 void SwIntrnlSectRefLink::DataChanged( const String& rMimeType,
1376                                 const uno::Any & rValue )
1377 {
1378 	SwSectionNode* pSectNd = rSectFmt.GetSectionNode( sal_False );
1379 	SwDoc* pDoc = rSectFmt.GetDoc();
1380 
1381 	sal_uLong nDataFormat = SotExchange::GetFormatIdFromMimeType( rMimeType );
1382 
1383 	if( !pSectNd || !pDoc || pDoc->IsInDtor() || ChkNoDataFlag() ||
1384 		sfx2::LinkManager::RegisterStatusInfoId() == nDataFormat )
1385 	{
1386 		// sollten wir schon wieder im Undo stehen?
1387 		return ;
1388 	}
1389 
1390     // --> OD 2005-02-11 #i38810# - Due to possible existing signatures, the
1391     // document has to be modified after updating a link.
1392     pDoc->SetModified();
1393     // set additional flag that links have been updated, in order to check this
1394     // during load.
1395     pDoc->SetLinksUpdated( sal_True );
1396     // <--
1397 
1398 	// Undo immer abschalten
1399     bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
1400     pDoc->GetIDocumentUndoRedo().DoUndo(false);
1401 	sal_Bool bWasVisibleLinks = pDoc->IsVisibleLinks();
1402 	pDoc->SetVisibleLinks( sal_False );
1403 
1404 	SwPaM* pPam;
1405 	ViewShell* pVSh = 0;
1406 	SwEditShell* pESh = pDoc->GetEditShell( &pVSh );
1407 	pDoc->LockExpFlds();
1408 	{
1409 		// am Anfang des Bereichs einen leeren TextNode einfuegen
1410 		SwNodeIndex aIdx( *pSectNd, +1 );
1411 		SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
1412 		SwTxtNode* pNewNd = pDoc->GetNodes().MakeTxtNode( aIdx,
1413 						pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
1414 
1415 		if( pESh )
1416 			pESh->StartAllAction();
1417 		else if( pVSh )
1418 			pVSh->StartAction();
1419 
1420 		SwPosition aPos( aIdx, SwIndex( pNewNd, 0 ));
1421 		aPos.nNode--;
1422 		pDoc->CorrAbs( aIdx, aEndIdx, aPos, sal_True );
1423 
1424 		pPam = new SwPaM( aPos );
1425 
1426 		//und alles dahinter liegende loeschen
1427 		aIdx--;
1428 		DelFlyInRange( aIdx, aEndIdx );
1429 		_DelBookmarks(aIdx, aEndIdx);
1430 		aIdx++;
1431 
1432 		pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() );
1433 	}
1434 
1435 	SwSection& rSection = pSectNd->GetSection();
1436     rSection.SetConnectFlag(false);
1437 
1438 	::rtl::OUString sNewFileName;
1439 	Reader* pRead = 0;
1440 	switch( nDataFormat )
1441 	{
1442 	case FORMAT_STRING:
1443 		pRead = ReadAscii;
1444 		break;
1445 
1446 	case FORMAT_RTF:
1447 		pRead = SwReaderWriter::GetReader( READER_WRITER_RTF );
1448 		break;
1449 
1450 	case FORMAT_FILE:
1451 		if( rValue.hasValue() && ( rValue >>= sNewFileName ) )
1452 		{
1453 			String sFilter, sRange, sFileName( sNewFileName );
1454 			pDoc->GetLinkManager().GetDisplayNames( this, 0, &sFileName,
1455 													&sRange, &sFilter );
1456 
1457             RedlineMode_t eOldRedlineMode = nsRedlineMode_t::REDLINE_NONE;
1458 			SfxObjectShellRef xDocSh;
1459             SfxObjectShellLock xLockRef;
1460 			int nRet;
1461 			if( !sFileName.Len() )
1462 			{
1463 				xDocSh = pDoc->GetDocShell();
1464 				nRet = 1;
1465 			}
1466 			else
1467 			{
1468 				nRet = lcl_FindDocShell( xDocSh, xLockRef, sFileName,
1469                                     rSection.GetLinkFilePassword(),
1470 									sFilter, 0, pDoc->GetDocShell() );
1471 				if( nRet )
1472 				{
1473 					SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
1474 					eOldRedlineMode = pSrcDoc->GetRedlineMode();
1475 					pSrcDoc->SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_INSERT );
1476 				}
1477 			}
1478 
1479 			if( nRet )
1480 			{
1481                 rSection.SetConnectFlag(true);
1482 
1483 				SwNodeIndex aSave( pPam->GetPoint()->nNode, -1 );
1484 				SwNodeRange* pCpyRg = 0;
1485 
1486 				if( xDocSh->GetMedium() &&
1487                     !rSection.GetLinkFilePassword().Len() )
1488 				{
1489 					const SfxPoolItem* pItem;
1490 					if( SFX_ITEM_SET == xDocSh->GetMedium()->GetItemSet()->
1491 						GetItemState( SID_PASSWORD, sal_False, &pItem ) )
1492                         rSection.SetLinkFilePassword(
1493 								((SfxStringItem*)pItem)->GetValue() );
1494 				}
1495 
1496 				SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
1497 
1498 				if( sRange.Len() )
1499 				{
1500 					// Rekursionen abfangen
1501 					sal_Bool bRecursion = sal_False;
1502 					if( pSrcDoc == pDoc )
1503 					{
1504 						SwServerObjectRef refObj( (SwServerObject*)
1505 										pDoc->CreateLinkSource( sRange ));
1506 						if( refObj.Is() )
1507 						{
1508 							bRecursion = refObj->IsLinkInServer( this ) ||
1509 										ChkNoDataFlag();
1510 						}
1511 					}
1512 
1513 					SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
1514 
1515 					SwPaM* pCpyPam = 0;
1516 					if( !bRecursion &&
1517 						pSrcDoc->SelectServerObj( sRange, pCpyPam, pCpyRg )
1518 						&& pCpyPam )
1519 					{
1520 						if( pSrcDoc != pDoc ||
1521 							pCpyPam->Start()->nNode > rInsPos ||
1522 							rInsPos >= pCpyPam->End()->nNode )
1523                         {
1524                             pSrcDoc->CopyRange( *pCpyPam, *pPam->GetPoint(),
1525                                     false );
1526                         }
1527 						delete pCpyPam;
1528 					}
1529 					if( pCpyRg && pSrcDoc == pDoc &&
1530 						pCpyRg->aStart < rInsPos && rInsPos < pCpyRg->aEnd )
1531 						delete pCpyRg, pCpyRg = 0;
1532 				}
1533 				else if( pSrcDoc != pDoc )
1534 					pCpyRg = new SwNodeRange( pSrcDoc->GetNodes().GetEndOfExtras(), 2,
1535 										  pSrcDoc->GetNodes().GetEndOfContent() );
1536 
1537                 // --> OD 2007-11-30 #i81653#
1538                 // Update links of extern linked document or extern linked
1539                 // document section, if section is protected.
1540                 if ( pSrcDoc != pDoc &&
1541                      rSection.IsProtectFlag() )
1542                 {
1543                     pSrcDoc->GetLinkManager().UpdateAllLinks( sal_False, sal_True, sal_False, 0 );
1544                 }
1545                 // <--
1546 				if( pCpyRg )
1547 				{
1548 					SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
1549 					sal_Bool bCreateFrm = rInsPos.GetIndex() <=
1550 								pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
1551 								rInsPos.GetNode().FindTableNode();
1552 
1553 					SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc );
1554 
1555                     pSrcDoc->CopyWithFlyInFly( *pCpyRg, 0, rInsPos, bCreateFrm );
1556 					aSave++;
1557 
1558 					if( !bCreateFrm )
1559 						::MakeFrms( pDoc, aSave, rInsPos );
1560 
1561 					// den letzten Node noch loeschen, aber nur wenn
1562 					// erfolgreich kopiert werden konnte, also der Bereich
1563 					// mehr als 1 Node enthaelt
1564 					if( 2 < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() )
1565 					{
1566 						aSave = rInsPos;
1567 						pPam->Move( fnMoveBackward, fnGoNode );
1568 						pPam->SetMark();	// beide SwPositions ummelden!
1569 
1570 						pDoc->CorrAbs( aSave, *pPam->GetPoint(), 0, sal_True );
1571 						pDoc->GetNodes().Delete( aSave, 1 );
1572 					}
1573 					delete pCpyRg;
1574 				}
1575 
1576                 // --> OD 2007-02-14 #b6521322#
1577                 lcl_BreakSectionLinksInSect( *pSectNd );
1578                 // <--
1579 
1580                 // update alle Links in diesem Bereich
1581 				lcl_UpdateLinksInSect( *this, *pSectNd );
1582 			}
1583 			if( xDocSh.Is() )
1584 			{
1585 				if( 2 == nRet )
1586 					xDocSh->DoClose();
1587                 else if( ((SwDocShell*)&xDocSh)->GetDoc() )
1588 					((SwDocShell*)&xDocSh)->GetDoc()->SetRedlineMode(
1589 								eOldRedlineMode );
1590 			}
1591 		}
1592 		break;
1593 	}
1594 
1595 	// !!!! DDE nur updaten wenn Shell vorhanden ist??
1596     uno::Sequence< sal_Int8 > aSeq;
1597 	if( pRead && rValue.hasValue() && ( rValue >>= aSeq ) )
1598 	{
1599 		if( pESh )
1600 		{
1601 			pESh->Push();
1602 			SwPaM* pCrsr = pESh->GetCrsr();
1603 			*pCrsr->GetPoint() = *pPam->GetPoint();
1604 			delete pPam;
1605 			pPam = pCrsr;
1606 		}
1607 
1608 		SvMemoryStream aStrm( (void*)aSeq.getConstArray(), aSeq.getLength(),
1609 								STREAM_READ );
1610 		aStrm.Seek( 0 );
1611 
1612 #if OSL_DEBUG_LEVEL > 1
1613 		{
1614 			SvFileStream aDeb( String::CreateFromAscii(
1615 					"file:///d|/temp/update.txt" ), STREAM_WRITE );
1616 			aDeb << aStrm;
1617 		}
1618 		aStrm.Seek( 0 );
1619 #endif
1620 
1621         // TODO/MBA: it's impossible to set a BaseURL here!
1622         SwReader aTmpReader( aStrm, aEmptyStr, pDoc->GetDocShell()->GetMedium()->GetBaseURL(), *pPam );
1623 
1624 		if( !IsError( aTmpReader.Read( *pRead ) ))
1625         {
1626             rSection.SetConnectFlag(true);
1627         }
1628 
1629 		if( pESh )
1630 		{
1631 			pESh->Pop( sal_False );
1632 			pPam = 0;			        // pam is deleted before
1633 		}
1634 	}
1635 
1636 
1637     // remove all undo actions and turn undo on again
1638     pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
1639     pDoc->GetIDocumentUndoRedo().DoUndo(bWasUndo);
1640 	pDoc->SetVisibleLinks( bWasVisibleLinks );
1641 
1642 	pDoc->UnlockExpFlds();
1643 	if( !pDoc->IsExpFldsLocked() )
1644 		pDoc->UpdateExpFlds(NULL, true);
1645 
1646 	if( pESh )
1647 		pESh->EndAllAction();
1648 	else if( pVSh )
1649 		pVSh->EndAction();
1650 	delete pPam;			// wurde am Anfang angelegt
1651 }
1652 
1653 
1654 void SwIntrnlSectRefLink::Closed()
1655 {
1656 	SwDoc* pDoc = rSectFmt.GetDoc();
1657 	if( pDoc && !pDoc->IsInDtor() )
1658 	{
1659 		// Advise verabschiedet sich, den Bereich als nicht geschuetzt
1660 		// kennzeichnen und das Flag umsetzen
1661 
1662 		const SwSectionFmts& rFmts = pDoc->GetSections();
1663 		for( sal_uInt16 n = rFmts.Count(); n; )
1664 			if( rFmts[ --n ] == &rSectFmt )
1665 			{
1666 				ViewShell* pSh;
1667 				SwEditShell* pESh = pDoc->GetEditShell( &pSh );
1668 
1669 				if( pESh )
1670 					pESh->StartAllAction();
1671 				else
1672 					pSh->StartAction();
1673 
1674                 SwSectionData aSectionData(*rSectFmt.GetSection());
1675                 aSectionData.SetType( CONTENT_SECTION );
1676                 aSectionData.SetLinkFileName( aEmptyStr );
1677                 aSectionData.SetHidden( false );
1678                 aSectionData.SetProtectFlag( false );
1679                 // --> FME 2004-06-22 #114856# edit in readonly sections
1680                 aSectionData.SetEditInReadonlyFlag( false );
1681                 // <--
1682 
1683                 aSectionData.SetConnectFlag( false );
1684 
1685                 pDoc->UpdateSection( n, aSectionData );
1686 
1687 				// alle in der Section liegenden Links werden sichtbar
1688 				SwSectionNode* pSectNd = rSectFmt.GetSectionNode( sal_False );
1689 				if( pSectNd )
1690 					pSectNd->GetSection().MakeChildLinksVisible( *pSectNd );
1691 
1692 				if( pESh )
1693 					pESh->EndAllAction();
1694 				else
1695 					pSh->EndAction();
1696 				break;
1697 			}
1698 	}
1699 	SvBaseLink::Closed();
1700 }
1701 
1702 
1703 void SwSection::CreateLink( LinkCreateType eCreateType )
1704 {
1705 	SwSectionFmt* pFmt = GetFmt();
1706     ASSERT(pFmt, "SwSection::CreateLink: no format?");
1707     if (!pFmt || (CONTENT_SECTION == m_Data.GetType()))
1708 		return ;
1709 
1710     sal_uInt16 nUpdateType = sfx2::LINKUPDATE_ALWAYS;
1711 
1712     if (!m_RefLink.Is())
1713     {
1714         // create BaseLink
1715         m_RefLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF );
1716     }
1717     else
1718     {
1719         pFmt->GetDoc()->GetLinkManager().Remove( m_RefLink );
1720     }
1721 
1722     SwIntrnlSectRefLink *const pLnk =
1723         static_cast<SwIntrnlSectRefLink*>(& m_RefLink);
1724 
1725     String sCmd( m_Data.GetLinkFileName() );
1726 	xub_StrLen nPos;
1727 	while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( "  " )) )
1728 		sCmd.Erase( nPos, 1 );
1729 
1730 	pLnk->SetUpdateMode( nUpdateType );
1731 	pLnk->SetVisible( pFmt->GetDoc()->IsVisibleLinks() );
1732 
1733     switch (m_Data.GetType())
1734 	{
1735 	case DDE_LINK_SECTION:
1736 		pLnk->SetLinkSourceName( sCmd );
1737 		pFmt->GetDoc()->GetLinkManager().InsertDDELink( pLnk );
1738 		break;
1739 	case FILE_LINK_SECTION:
1740 		{
1741 			pLnk->SetContentType( FORMAT_FILE );
1742             String sFltr( sCmd.GetToken( 1, sfx2::cTokenSeperator ) );
1743             String sRange( sCmd.GetToken( 2, sfx2::cTokenSeperator ) );
1744 			pFmt->GetDoc()->GetLinkManager().InsertFileLink( *pLnk,
1745                                 static_cast<sal_uInt16>(m_Data.GetType()),
1746                                 sCmd.GetToken( 0, sfx2::cTokenSeperator ),
1747 								( sFltr.Len() ? &sFltr : 0 ),
1748 								( sRange.Len() ? &sRange : 0 ) );
1749 		}
1750 		break;
1751 	default:
1752 		ASSERT( !this, "Was ist das fuer ein Link?" )
1753 	}
1754 
1755 	switch( eCreateType )
1756 	{
1757 	case CREATE_CONNECT:			// Link gleich connecten
1758 		pLnk->Connect();
1759 		break;
1760 
1761 	case CREATE_UPDATE: 		// Link connecten und updaten
1762 		pLnk->Update();
1763 		break;
1764     case CREATE_NONE: break;
1765 	}
1766 }
1767 
1768 // --> OD 2007-02-14 #b6521322#
1769 void SwSection::BreakLink()
1770 {
1771     const SectionType eCurrentType( GetType() );
1772     if ( eCurrentType == CONTENT_SECTION ||
1773          eCurrentType == TOX_HEADER_SECTION ||
1774          eCurrentType == TOX_CONTENT_SECTION )
1775     {
1776         // nothing to do
1777         return;
1778     }
1779 
1780     // release link, if it exists
1781     if (m_RefLink.Is())
1782     {
1783         SwSectionFmt *const pFormat( GetFmt() );
1784         ASSERT(pFormat, "SwSection::BreakLink: no format?");
1785         if (pFormat)
1786         {
1787             pFormat->GetDoc()->GetLinkManager().Remove( m_RefLink );
1788         }
1789         m_RefLink.Clear();
1790     }
1791     // change type
1792     SetType( CONTENT_SECTION );
1793     // reset linked file data
1794     SetLinkFileName( aEmptyStr );
1795     SetLinkFilePassword( aEmptyStr );
1796 }
1797 // <--
1798 
1799 const SwNode* SwIntrnlSectRefLink::GetAnchor() const
1800 {
1801 	return rSectFmt.GetSectionNode( sal_False );
1802 }
1803 
1804 
1805 sal_Bool SwIntrnlSectRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd,
1806 									 xub_StrLen , xub_StrLen ) const
1807 {
1808 	SwStartNode* pSttNd = rSectFmt.GetSectionNode( sal_False );
1809 	return pSttNd &&
1810 			nSttNd < pSttNd->GetIndex() &&
1811 			pSttNd->EndOfSectionIndex() < nEndNd;
1812 }
1813 
1814 
1815 
1816