xref: /aoo41x/main/sw/source/core/docnode/section.cxx (revision cdf0e10c)
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             CallSwClientNotify( SfxSimpleHint(SFX_HINT_DYING) );
705 
706 			// hebe die Section doch mal auf
707 			SwNodeRange aRg( *pSectNd, 0, *pSectNd->EndOfSectionNode() );
708 			GetDoc()->GetNodes().SectionUp( &aRg );
709 		}
710 		LockModify();
711         ResetFmtAttr( RES_CNTNT );
712 		UnlockModify();
713 	}
714 }
715 
716 
717 SwSection * SwSectionFmt::GetSection() const
718 {
719 	return SwIterator<SwSection,SwSectionFmt>::FirstElement( *this );
720 }
721 
722 extern void lcl_DeleteFtn( SwSectionNode *pNd, sal_uLong nStt, sal_uLong nEnd );
723 
724 //Vernichtet alle Frms in aDepend (Frms werden per PTR_CAST erkannt).
725 void SwSectionFmt::DelFrms()
726 {
727 	SwSectionNode* pSectNd;
728 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
729 	if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
730 		0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
731 	{
732         // #147431# : First delete the <SwSectionFrm> of the <SwSectionFmt> instance
733         // mba: test iteration as objects are removed in iteration
734         CallSwClientNotify( SfxSimpleHint(SFX_HINT_DYING) );
735 
736         // Then delete frames of the nested <SwSectionFmt> instances
737         SwIterator<SwSectionFmt,SwSectionFmt> aIter( *this );
738         SwSectionFmt *pLast = aIter.First();
739         while ( pLast )
740         {
741             pLast->DelFrms();
742             pLast = aIter.Next();
743         }
744 
745 		sal_uLong nEnde = pSectNd->EndOfSectionIndex();
746 		sal_uLong nStart = pSectNd->GetIndex()+1;
747 		lcl_DeleteFtn( pSectNd, nStart, nEnde );
748 	}
749 	if( pIdx )
750 	{
751 		//JP 22.09.98:
752 		//Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im
753 		//Paste der Frames selbst erledigen, aber das fuehrt dann wiederum
754 		//zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden
755 		//muesten. #56977# #55001# #56135#
756 		SwNodeIndex aNextNd( *pIdx );
757 		SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, sal_True, sal_False );
758 		if( pCNd )
759 		{
760 			const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC );
761 			pCNd->ModifyNotification( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem );
762 		}
763 	}
764 }
765 
766 
767 //Erzeugt die Ansichten
768 void SwSectionFmt::MakeFrms()
769 {
770 	SwSectionNode* pSectNd;
771 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
772 
773 	if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
774 		0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
775 	{
776 		SwNodeIndex aIdx( *pIdx );
777 		pSectNd->MakeFrms( &aIdx );
778 	}
779 }
780 
781 void SwSectionFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
782 {
783 	sal_Bool bClients = sal_False;
784 	sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
785 	switch( nWhich )
786 	{
787 	case RES_ATTRSET_CHG:
788 		if( GetDepends() )
789 		{
790 			SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
791 			SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
792 			const SfxPoolItem *pItem;
793 			if( SFX_ITEM_SET == pNewSet->GetItemState(
794 										RES_PROTECT, sal_False, &pItem ))
795 			{
796 				ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
797 				pNewSet->ClearItem( RES_PROTECT );
798 				pOldSet->ClearItem( RES_PROTECT );
799 			}
800 
801             // --> FME 2004-06-22 #114856# edit in readonly sections
802             if( SFX_ITEM_SET == pNewSet->GetItemState(
803                         RES_EDIT_IN_READONLY, sal_False, &pItem ) )
804             {
805 				ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
806                 pNewSet->ClearItem( RES_EDIT_IN_READONLY );
807                 pOldSet->ClearItem( RES_EDIT_IN_READONLY );
808             }
809             // <--
810 
811 			if( SFX_ITEM_SET == pNewSet->GetItemState(
812 									RES_FTN_AT_TXTEND, sal_False, &pItem ))
813 			{
814 				ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_FTN_AT_TXTEND ), (SfxPoolItem*)pItem );
815 				pNewSet->ClearItem( RES_FTN_AT_TXTEND );
816 				pOldSet->ClearItem( RES_FTN_AT_TXTEND );
817 			}
818 			if( SFX_ITEM_SET == pNewSet->GetItemState(
819 									RES_END_AT_TXTEND, sal_False, &pItem ))
820 			{
821 				ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_END_AT_TXTEND ), (SfxPoolItem*)pItem );
822 				pNewSet->ClearItem( RES_END_AT_TXTEND );
823 				pOldSet->ClearItem( RES_END_AT_TXTEND );
824 			}
825 			if( !((SwAttrSetChg*)pOld)->GetChgSet()->Count() )
826 				return;
827 		}
828 		break;
829 
830 	case RES_SECTION_RESETHIDDENFLAG:
831 	case RES_FTN_AT_TXTEND:
832 	case RES_END_AT_TXTEND : bClients = sal_True;
833 							// no break !!
834 	case RES_SECTION_HIDDEN:
835 	case RES_SECTION_NOT_HIDDEN:
836 		{
837 			SwSection* pSect = GetSection();
838 			if( pSect && ( bClients || ( RES_SECTION_HIDDEN == nWhich ?
839 							!pSect->IsHiddenFlag() : pSect->IsHiddenFlag() ) ) )
840 			{
841                 ModifyBroadcast( pOld, pNew );
842 			}
843 		}
844 		return ;
845 
846 
847 	case RES_PROTECT:
848     // --> FME 2004-06-22 #114856# edit in readonly sections
849     case RES_EDIT_IN_READONLY:
850     // <--
851         // diese Messages bis zum Ende des Baums durchreichen !
852 		if( GetDepends() )
853 		{
854             ModifyBroadcast( pOld, pNew );
855 		}
856 		return; 	// das wars
857 
858     case RES_OBJECTDYING:
859 		if( !GetDoc()->IsInDtor() &&
860 			((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() )
861 		{
862 			// mein Parent wird vernichtet, dann an den Parent vom Parent
863 			// umhaengen und wieder aktualisieren
864 			SwFrmFmt::Modify( pOld, pNew ); 	//	erst umhaengen !!!
865 			UpdateParent();
866 			return;
867 		}
868 		break;
869 
870 	case RES_FMT_CHG:
871 		if( !GetDoc()->IsInDtor() &&
872 			((SwFmtChg*)pNew)->pChangedFmt == (void*)GetRegisteredIn() &&
873 			((SwFmtChg*)pNew)->pChangedFmt->IsA( TYPE( SwSectionFmt )) )
874 		{
875 			// mein Parent wird veraendert, muss mich aktualisieren
876 			SwFrmFmt::Modify( pOld, pNew ); 	//	erst umhaengen !!!
877 			UpdateParent();
878 			return;
879 		}
880 		break;
881 	}
882 	SwFrmFmt::Modify( pOld, pNew );
883 
884     if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
885     {   // invalidate cached uno object
886         SetXTextSection(uno::Reference<text::XTextSection>(0));
887     }
888 }
889 
890 		// erfrage vom Format Informationen
891 sal_Bool SwSectionFmt::GetInfo( SfxPoolItem& rInfo ) const
892 {
893 	switch( rInfo.Which() )
894 	{
895 	case RES_FINDNEARESTNODE:
896         if( ((SwFmtPageDesc&)GetFmtAttr( RES_PAGEDESC )).GetPageDesc() )
897 		{
898 			const SwSectionNode* pNd = GetSectionNode();
899 			if( pNd )
900 				((SwFindNearestNode&)rInfo).CheckNode( *pNd );
901 		}
902 		return sal_True;
903 
904 	case RES_CONTENT_VISIBLE:
905 		{
906 			SwFrm* pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*this);
907 			// if the current section has no own frame search for the children
908 			if(!pFrm)
909 			{
910                 SwIterator<SwSectionFmt,SwSectionFmt> aFormatIter(*this);
911 				SwSectionFmt* pChild = aFormatIter.First();
912 				while(pChild && !pFrm)
913 				{
914         			pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*pChild);
915 					pChild = aFormatIter.Next();
916 				}
917 			}
918 			((SwPtrMsgPoolItem&)rInfo).pObject = pFrm;
919 		}
920 		return sal_False;
921 	}
922 	return SwModify::GetInfo( rInfo );
923 }
924 
925 extern "C" {
926 
927 	int
928 #if defined( WNT )
929  	__cdecl
930 #endif
931 #if defined( ICC )
932  	_Optlink
933 #endif
934 		lcl_SectionCmpPos( const void *pFirst, const void *pSecond)
935 	{
936 		const SwSectionFmt* pFSectFmt = (*(SwSectionPtr*)pFirst)->GetFmt();
937 		const SwSectionFmt* pSSectFmt = (*(SwSectionPtr*)pSecond)->GetFmt();
938 		ASSERT( pFSectFmt && pSSectFmt &&
939 				pFSectFmt->GetCntnt(sal_False).GetCntntIdx() &&
940 				pSSectFmt->GetCntnt(sal_False).GetCntntIdx(),
941 					"ungueltige Sections" );
942 		return (int)((long)pFSectFmt->GetCntnt(sal_False).GetCntntIdx()->GetIndex()) -
943 				  	pSSectFmt->GetCntnt(sal_False).GetCntntIdx()->GetIndex();
944 	}
945 
946 	int
947 #if defined( WNT )
948  	__cdecl
949 #endif
950 #if defined( ICC )
951  	_Optlink
952 #endif
953 		lcl_SectionCmpNm( const void *pFirst, const void *pSecond)
954 	{
955 		const SwSectionPtr pFSect = *(SwSectionPtr*)pFirst;
956 		const SwSectionPtr pSSect = *(SwSectionPtr*)pSecond;
957 		ASSERT( pFSect && pSSect, "ungueltige Sections" );
958         StringCompare const eCmp =
959             pFSect->GetSectionName().CompareTo( pSSect->GetSectionName() );
960 		return eCmp == COMPARE_EQUAL ? 0
961 							: eCmp == COMPARE_LESS ? 1 : -1;
962 	}
963 }
964 
965 	// alle Sections, die von dieser abgeleitet sind
966 sal_uInt16 SwSectionFmt::GetChildSections( SwSections& rArr,
967 										SectionSort eSort,
968 										sal_Bool bAllSections ) const
969 {
970 	rArr.Remove( 0, rArr.Count() );
971 
972 	if( GetDepends() )
973 	{
974         SwIterator<SwSectionFmt,SwSectionFmt> aIter(*this);
975 		const SwNodeIndex* pIdx;
976 		for( SwSectionFmt* pLast = aIter.First(); pLast; pLast = aIter.Next() )
977 			if( bAllSections ||
978 				( 0 != ( pIdx = pLast->GetCntnt(sal_False).
979 				GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
980 			{
981 				const SwSection* Dummy = pLast->GetSection();
982 				rArr.C40_INSERT( SwSection,
983 					Dummy,
984 					rArr.Count() );
985 			}
986 
987 		// noch eine Sortierung erwuenscht ?
988 		if( 1 < rArr.Count() )
989 			switch( eSort )
990 			{
991 			case SORTSECT_NAME:
992 				qsort( (void*)rArr.GetData(),
993 						rArr.Count(),
994 						sizeof( SwSectionPtr ),
995 						lcl_SectionCmpNm );
996 				break;
997 
998 			case SORTSECT_POS:
999 				qsort( (void*)rArr.GetData(),
1000 						rArr.Count(),
1001 						sizeof( SwSectionPtr ),
1002 						lcl_SectionCmpPos );
1003 				break;
1004             case SORTSECT_NOT: break;
1005 			}
1006 	}
1007 	return rArr.Count();
1008 }
1009 
1010 	// erfrage, ob sich die Section im Nodes-Array oder UndoNodes-Array
1011 	// befindet.
1012 sal_Bool SwSectionFmt::IsInNodesArr() const
1013 {
1014 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
1015 	return pIdx && &pIdx->GetNodes() == &GetDoc()->GetNodes();
1016 }
1017 
1018 
1019 void SwSectionFmt::UpdateParent()		// Parent wurde veraendert
1020 {
1021 	if( !GetDepends() )
1022 		return;
1023 
1024 	SwSectionPtr pSection = 0;
1025 	const SvxProtectItem* pProtect(0);
1026     // --> FME 2004-06-22 #114856# edit in readonly sections
1027     const SwFmtEditInReadonly* pEditInReadonly = 0;
1028     // <--
1029     bool bIsHidden = false;
1030 
1031 	SwClientIter aIter( *this );    // TODO
1032 	::SwClient * pLast = aIter.GoStart();
1033 	if( pLast ) 	// konnte zum Anfang gesprungen werden ??
1034 		do {
1035 			if( pLast->IsA( TYPE(SwSectionFmt) ) )
1036 			{
1037 				if( !pSection )
1038 				{
1039 					pSection = GetSection();
1040 					if( GetRegisteredIn() )
1041 					{
1042 						const SwSectionPtr pPS = GetParentSection();
1043 						pProtect = &pPS->GetFmt()->GetProtect();
1044                         // --> FME 2004-06-22 #114856# edit in readonly sections
1045                         pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly();
1046                         // <--
1047 						bIsHidden = pPS->IsHiddenFlag();
1048 					}
1049 					else
1050 					{
1051 						pProtect = &GetProtect();
1052                         // --> FME 2004-06-22 #114856# edit in readonly sections
1053                         pEditInReadonly = &GetEditInReadonly();
1054                         // <--
1055                         bIsHidden = pSection->IsHidden();
1056 					}
1057 				}
1058                 if (!pProtect->IsCntntProtected() !=
1059                     !pSection->IsProtectFlag())
1060                 {
1061 					pLast->ModifyNotification( (SfxPoolItem*)pProtect,
1062 									(SfxPoolItem*)pProtect );
1063                 }
1064 
1065                 // --> FME 2004-06-22 #114856# edit in readonly sections
1066                 if (!pEditInReadonly->GetValue() !=
1067                     !pSection->IsEditInReadonlyFlag())
1068                 {
1069                     pLast->ModifyNotification( (SfxPoolItem*)pEditInReadonly,
1070                                     (SfxPoolItem*)pEditInReadonly );
1071                 }
1072                 // <--
1073 
1074 				if( bIsHidden == pSection->IsHiddenFlag() )
1075 				{
1076 					SwMsgPoolItem aMsgItem( static_cast<sal_uInt16>(bIsHidden
1077 								? RES_SECTION_HIDDEN
1078 								: RES_SECTION_NOT_HIDDEN ) );
1079 					pLast->ModifyNotification( &aMsgItem, &aMsgItem );
1080 				}
1081 			}
1082 			else if( !pSection &&
1083 					pLast->IsA( TYPE(SwSection) ) )
1084 			{
1085 				pSection = (SwSectionPtr)pLast;
1086 				if( GetRegisteredIn() )
1087 				{
1088 					const SwSectionPtr pPS = GetParentSection();
1089 					pProtect = &pPS->GetFmt()->GetProtect();
1090                     // --> FME 2004-06-22 #114856# edit in readonly sections
1091                     pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly();
1092                     // <--
1093 					bIsHidden = pPS->IsHiddenFlag();
1094 				}
1095 				else
1096 				{
1097 					pProtect = &GetProtect();
1098                     // --> FME 2004-06-22 #114856# edit in readonly sections
1099                     pEditInReadonly = &GetEditInReadonly();
1100                     // <--
1101                     bIsHidden = pSection->IsHidden();
1102 				}
1103 			}
1104 		} while( 0 != ( pLast = aIter++ ));
1105 }
1106 
1107 
1108 SwSectionNode* SwSectionFmt::GetSectionNode(bool const bAlways)
1109 {
1110 	const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx();
1111 	if( pIdx && ( bAlways || &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
1112 		return pIdx->GetNode().GetSectionNode();
1113 	return 0;
1114 }
1115 
1116 	// ist die Section eine gueltige fuers GlobalDocument?
1117 const SwSection* SwSectionFmt::GetGlobalDocSection() const
1118 {
1119 	const SwSectionNode* pNd = GetSectionNode();
1120 	if( pNd &&
1121 		( FILE_LINK_SECTION == pNd->GetSection().GetType() ||
1122 		  TOX_CONTENT_SECTION == pNd->GetSection().GetType() ) &&
1123 		pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() &&
1124         !pNd->StartOfSectionNode()->IsSectionNode() &&
1125         !pNd->StartOfSectionNode()->FindSectionNode() )
1126 		return &pNd->GetSection();
1127 	return 0;
1128 }
1129 
1130 // sw::Metadatable
1131 ::sfx2::IXmlIdRegistry& SwSectionFmt::GetRegistry()
1132 {
1133     return GetDoc()->GetXmlIdRegistry();
1134 }
1135 
1136 bool SwSectionFmt::IsInClipboard() const
1137 {
1138     return GetDoc()->IsClipBoard();
1139 }
1140 
1141 bool SwSectionFmt::IsInUndo() const
1142 {
1143     return !IsInNodesArr();
1144 }
1145 
1146 bool SwSectionFmt::IsInContent() const
1147 {
1148     SwNodeIndex const*const pIdx = GetCntnt(sal_False).GetCntntIdx();
1149     OSL_ENSURE(pIdx, "SwSectionFmt::IsInContent: no index?");
1150     return (pIdx) ? !GetDoc()->IsInHeaderFooter(*pIdx) : true;
1151 }
1152 
1153 // n.b.: if the section format represents an index, then there is both a
1154 // SwXDocumentIndex and a SwXTextSection instance for this single core object.
1155 // these two can both implement XMetadatable and forward to the same core
1156 // section format.  but here only one UNO object can be returned,
1157 // so always return the text section.
1158 uno::Reference< rdf::XMetadatable >
1159 SwSectionFmt::MakeUnoObject()
1160 {
1161     uno::Reference<rdf::XMetadatable> xMeta;
1162     SwSection *const pSection( GetSection() );
1163     if (pSection)
1164     {
1165         xMeta.set(  SwXTextSection::CreateXTextSection(this,
1166                         TOX_HEADER_SECTION == pSection->GetType()),
1167                     uno::UNO_QUERY );
1168     }
1169     return xMeta;
1170 }
1171 
1172 
1173 // --> OD 2007-02-14 #b6521322#
1174 // Method to break section links inside a linked section
1175 void lcl_BreakSectionLinksInSect( const SwSectionNode& rSectNd )
1176 {
1177     if ( !rSectNd.GetDoc() )
1178     {
1179         ASSERT( false,
1180                 "method <lcl_RemoveSectionLinksInSect(..)> - no Doc at SectionNode" );
1181         return;
1182     }
1183 
1184     if ( !rSectNd.GetSection().IsConnected() )
1185     {
1186         ASSERT( false,
1187                 "method <lcl_RemoveSectionLinksInSect(..)> - no Link at Section of SectionNode" );
1188         return;
1189     }
1190     const ::sfx2::SvBaseLink* pOwnLink( &(rSectNd.GetSection().GetBaseLink() ) );
1191     const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->GetLinkManager().GetLinks();
1192     for ( sal_uInt16 n = rLnks.Count(); n > 0; )
1193     {
1194         SwIntrnlSectRefLink* pSectLnk = dynamic_cast<SwIntrnlSectRefLink*>(&(*rLnks[ --n ]));
1195         if ( pSectLnk && pSectLnk != pOwnLink &&
1196              pSectLnk->IsInRange( rSectNd.GetIndex(), rSectNd.EndOfSectionIndex() ) )
1197         {
1198             // break the link of the corresponding section.
1199             // the link is also removed from the link manager
1200             pSectLnk->GetSectNode()->GetSection().BreakLink();
1201 
1202             // for robustness, because link is removed from the link manager
1203             if ( n > rLnks.Count() )
1204             {
1205                 n = rLnks.Count();
1206             }
1207         }
1208     }
1209 }
1210 // <--
1211 
1212 void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd )
1213 {
1214 	SwDoc* pDoc = rSectNd.GetDoc();
1215 	SwDocShell* pDShell = pDoc->GetDocShell();
1216 	if( !pDShell || !pDShell->GetMedium() )
1217 		return ;
1218 
1219 	String sName( pDShell->GetMedium()->GetName() );
1220 	SwBaseLink* pBLink;
1221 	String sMimeType( SotExchange::GetFormatMimeType( FORMAT_FILE ));
1222     uno::Any aValue;
1223 	aValue <<= ::rtl::OUString( sName );						// beliebiger Name
1224 
1225     const ::sfx2::SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks();
1226 	for( sal_uInt16 n = rLnks.Count(); n; )
1227 	{
1228         ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
1229 		if( pLnk && pLnk != &rUpdLnk &&
1230 			OBJECT_CLIENT_FILE == pLnk->GetObjType() &&
1231 			pLnk->ISA( SwBaseLink ) &&
1232 			( pBLink = (SwBaseLink*)pLnk )->IsInRange( rSectNd.GetIndex(),
1233 												rSectNd.EndOfSectionIndex() ) )
1234 		{
1235 			// liegt in dem Bereich: also updaten. Aber nur wenns nicht
1236 			// im gleichen File liegt
1237 			String sFName;
1238 			pDoc->GetLinkManager().GetDisplayNames( pBLink, 0, &sFName, 0, 0 );
1239 			if( sFName != sName )
1240 			{
1241 				pBLink->DataChanged( sMimeType, aValue );
1242 
1243 				// ggfs. neu den Link-Pointer wieder suchen, damit nicht einer
1244 				// ausgelassen oder doppelt gerufen wird.
1245 				if( n >= rLnks.Count() && 0 != ( n = rLnks.Count() ))
1246 					--n;
1247 
1248 				if( n && pLnk != &(*rLnks[ n ]) )
1249 				{
1250 					// suchen - kann nur davor liegen!!
1251 					while( n )
1252 						if( pLnk == &(*rLnks[ --n ] ) )
1253 							break;
1254 				}
1255 			}
1256 		}
1257 	}
1258 }
1259 
1260 
1261 // sucht sich die richtige DocShell raus oder erzeugt eine neue:
1262 // Der Return-Wert gibt an, was mit der Shell zu geschehen hat:
1263 //	0 - Fehler, konnte DocShell nicht finden
1264 //	1 - DocShell ist ein existieren Document
1265 //	2 - DocShell wurde neu angelegt, muss also wieder geschlossen werden ( will be assigned to xLockRef additionaly )
1266 
1267 int lcl_FindDocShell( SfxObjectShellRef& xDocSh,
1268                         SfxObjectShellLock& xLockRef,
1269 						const String& rFileName,
1270 						const String& rPasswd,
1271 						String& rFilter,
1272 						sal_Int16 nVersion,
1273 						SwDocShell* pDestSh )
1274 {
1275 	if( !rFileName.Len() )
1276 		return 0;
1277 
1278 	// 1. existiert die Datei schon in der Liste aller Dokumente?
1279 	INetURLObject aTmpObj( rFileName );
1280 	aTmpObj.SetMark( aEmptyStr );
1281 
1282 	// erstmal nur ueber die DocumentShells laufen und die mit dem
1283 	// Namen heraussuchen:
1284 	TypeId aType( TYPE(SwDocShell) );
1285 
1286 	SfxObjectShell* pShell = pDestSh;
1287 	sal_Bool bFirst = 0 != pShell;
1288 
1289 	if( !bFirst )
1290 		// keine DocShell uebergeben, also beginne mit der ersten aus der
1291 		// DocShell Liste
1292 		pShell = SfxObjectShell::GetFirst( &aType );
1293 
1294 	while( pShell )
1295 	{
1296 		// die wollen wir haben
1297 		SfxMedium* pMed = pShell->GetMedium();
1298 		if( pMed && pMed->GetURLObject() == aTmpObj )
1299 		{
1300 			const SfxPoolItem* pItem;
1301 			if( ( SFX_ITEM_SET == pMed->GetItemSet()->GetItemState(
1302 											SID_VERSION, sal_False, &pItem ) )
1303 					? (nVersion == ((SfxInt16Item*)pItem)->GetValue())
1304 					: !nVersion )
1305 			{
1306 				// gefunden also returnen
1307 				xDocSh = pShell;
1308 				return 1;
1309 			}
1310 		}
1311 
1312 		if( bFirst )
1313 		{
1314 			bFirst = sal_False;
1315 			pShell = SfxObjectShell::GetFirst( &aType );
1316 		}
1317 		else
1318 			pShell = SfxObjectShell::GetNext( *pShell, &aType );
1319 	}
1320 
1321 	// 2. selbst die Date oeffnen
1322 	SfxMedium* pMed = new SfxMedium( aTmpObj.GetMainURL(
1323 							 INetURLObject::NO_DECODE ), STREAM_READ, sal_True );
1324 	if( INET_PROT_FILE == aTmpObj.GetProtocol() )
1325 		pMed->DownLoad(); 	  // nur mal das Medium anfassen (DownLoaden)
1326 
1327 	const SfxFilter* pSfxFlt = 0;
1328 	if( !pMed->GetError() )
1329 	{
1330         String sFactory(String::CreateFromAscii(SwDocShell::Factory().GetShortName()));
1331         SfxFilterMatcher aMatcher( sFactory );
1332 
1333         // kein Filter, dann suche ihn. Ansonsten teste, ob der angegebene
1334 		// ein gueltiger ist
1335 		if( rFilter.Len() )
1336 		{
1337             pSfxFlt = aMatcher.GetFilter4FilterName( rFilter );
1338 		}
1339 
1340 		if( nVersion )
1341 			pMed->GetItemSet()->Put( SfxInt16Item( SID_VERSION, nVersion ));
1342 
1343 		if( rPasswd.Len() )
1344 			pMed->GetItemSet()->Put( SfxStringItem( SID_PASSWORD, rPasswd ));
1345 
1346 		if( !pSfxFlt )
1347             aMatcher.DetectFilter( *pMed, &pSfxFlt, sal_False, sal_False );
1348 
1349 		if( pSfxFlt )
1350 		{
1351 			// ohne Filter geht gar nichts
1352 			pMed->SetFilter( pSfxFlt );
1353 
1354             // if the new shell is created, SfxObjectShellLock should be used to let it be closed later for sure
1355 			xLockRef = new SwDocShell( SFX_CREATE_MODE_INTERNAL );
1356             xDocSh = (SfxObjectShell*)xLockRef;
1357 			if( xDocSh->DoLoad( pMed ) )
1358 				return 2;
1359 		}
1360 	}
1361 
1362 	if( !xDocSh.Is() )		// Medium muss noch geloescht werden
1363 		delete pMed;
1364 
1365 	return 0;	// das war wohl nichts
1366 }
1367 
1368 
1369 void SwIntrnlSectRefLink::DataChanged( const String& rMimeType,
1370                                 const uno::Any & rValue )
1371 {
1372 	SwSectionNode* pSectNd = rSectFmt.GetSectionNode( sal_False );
1373 	SwDoc* pDoc = rSectFmt.GetDoc();
1374 
1375 	sal_uLong nDataFormat = SotExchange::GetFormatIdFromMimeType( rMimeType );
1376 
1377 	if( !pSectNd || !pDoc || pDoc->IsInDtor() || ChkNoDataFlag() ||
1378 		sfx2::LinkManager::RegisterStatusInfoId() == nDataFormat )
1379 	{
1380 		// sollten wir schon wieder im Undo stehen?
1381 		return ;
1382 	}
1383 
1384     // --> OD 2005-02-11 #i38810# - Due to possible existing signatures, the
1385     // document has to be modified after updating a link.
1386     pDoc->SetModified();
1387     // set additional flag that links have been updated, in order to check this
1388     // during load.
1389     pDoc->SetLinksUpdated( sal_True );
1390     // <--
1391 
1392 	// Undo immer abschalten
1393     bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
1394     pDoc->GetIDocumentUndoRedo().DoUndo(false);
1395 	sal_Bool bWasVisibleLinks = pDoc->IsVisibleLinks();
1396 	pDoc->SetVisibleLinks( sal_False );
1397 
1398 	SwPaM* pPam;
1399 	ViewShell* pVSh = 0;
1400 	SwEditShell* pESh = pDoc->GetEditShell( &pVSh );
1401 	pDoc->LockExpFlds();
1402 	{
1403 		// am Anfang des Bereichs einen leeren TextNode einfuegen
1404 		SwNodeIndex aIdx( *pSectNd, +1 );
1405 		SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
1406 		SwTxtNode* pNewNd = pDoc->GetNodes().MakeTxtNode( aIdx,
1407 						pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
1408 
1409 		if( pESh )
1410 			pESh->StartAllAction();
1411 		else if( pVSh )
1412 			pVSh->StartAction();
1413 
1414 		SwPosition aPos( aIdx, SwIndex( pNewNd, 0 ));
1415 		aPos.nNode--;
1416 		pDoc->CorrAbs( aIdx, aEndIdx, aPos, sal_True );
1417 
1418 		pPam = new SwPaM( aPos );
1419 
1420 		//und alles dahinter liegende loeschen
1421 		aIdx--;
1422 		DelFlyInRange( aIdx, aEndIdx );
1423 		_DelBookmarks(aIdx, aEndIdx);
1424 		aIdx++;
1425 
1426 		pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() );
1427 	}
1428 
1429 	SwSection& rSection = pSectNd->GetSection();
1430     rSection.SetConnectFlag(false);
1431 
1432 	::rtl::OUString sNewFileName;
1433 	Reader* pRead = 0;
1434 	switch( nDataFormat )
1435 	{
1436 	case FORMAT_STRING:
1437 		pRead = ReadAscii;
1438 		break;
1439 
1440 	case FORMAT_RTF:
1441 		pRead = SwReaderWriter::GetReader( READER_WRITER_RTF );
1442 		break;
1443 
1444 	case FORMAT_FILE:
1445 		if( rValue.hasValue() && ( rValue >>= sNewFileName ) )
1446 		{
1447 			String sFilter, sRange, sFileName( sNewFileName );
1448 			pDoc->GetLinkManager().GetDisplayNames( this, 0, &sFileName,
1449 													&sRange, &sFilter );
1450 
1451             RedlineMode_t eOldRedlineMode = nsRedlineMode_t::REDLINE_NONE;
1452 			SfxObjectShellRef xDocSh;
1453             SfxObjectShellLock xLockRef;
1454 			int nRet;
1455 			if( !sFileName.Len() )
1456 			{
1457 				xDocSh = pDoc->GetDocShell();
1458 				nRet = 1;
1459 			}
1460 			else
1461 			{
1462 				nRet = lcl_FindDocShell( xDocSh, xLockRef, sFileName,
1463                                     rSection.GetLinkFilePassword(),
1464 									sFilter, 0, pDoc->GetDocShell() );
1465 				if( nRet )
1466 				{
1467 					SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
1468 					eOldRedlineMode = pSrcDoc->GetRedlineMode();
1469 					pSrcDoc->SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_INSERT );
1470 				}
1471 			}
1472 
1473 			if( nRet )
1474 			{
1475                 rSection.SetConnectFlag(true);
1476 
1477 				SwNodeIndex aSave( pPam->GetPoint()->nNode, -1 );
1478 				SwNodeRange* pCpyRg = 0;
1479 
1480 				if( xDocSh->GetMedium() &&
1481                     !rSection.GetLinkFilePassword().Len() )
1482 				{
1483 					const SfxPoolItem* pItem;
1484 					if( SFX_ITEM_SET == xDocSh->GetMedium()->GetItemSet()->
1485 						GetItemState( SID_PASSWORD, sal_False, &pItem ) )
1486                         rSection.SetLinkFilePassword(
1487 								((SfxStringItem*)pItem)->GetValue() );
1488 				}
1489 
1490 				SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
1491 
1492 				if( sRange.Len() )
1493 				{
1494 					// Rekursionen abfangen
1495 					sal_Bool bRecursion = sal_False;
1496 					if( pSrcDoc == pDoc )
1497 					{
1498 						SwServerObjectRef refObj( (SwServerObject*)
1499 										pDoc->CreateLinkSource( sRange ));
1500 						if( refObj.Is() )
1501 						{
1502 							bRecursion = refObj->IsLinkInServer( this ) ||
1503 										ChkNoDataFlag();
1504 						}
1505 					}
1506 
1507 					SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
1508 
1509 					SwPaM* pCpyPam = 0;
1510 					if( !bRecursion &&
1511 						pSrcDoc->SelectServerObj( sRange, pCpyPam, pCpyRg )
1512 						&& pCpyPam )
1513 					{
1514 						if( pSrcDoc != pDoc ||
1515 							pCpyPam->Start()->nNode > rInsPos ||
1516 							rInsPos >= pCpyPam->End()->nNode )
1517                         {
1518                             pSrcDoc->CopyRange( *pCpyPam, *pPam->GetPoint(),
1519                                     false );
1520                         }
1521 						delete pCpyPam;
1522 					}
1523 					if( pCpyRg && pSrcDoc == pDoc &&
1524 						pCpyRg->aStart < rInsPos && rInsPos < pCpyRg->aEnd )
1525 						delete pCpyRg, pCpyRg = 0;
1526 				}
1527 				else if( pSrcDoc != pDoc )
1528 					pCpyRg = new SwNodeRange( pSrcDoc->GetNodes().GetEndOfExtras(), 2,
1529 										  pSrcDoc->GetNodes().GetEndOfContent() );
1530 
1531                 // --> OD 2007-11-30 #i81653#
1532                 // Update links of extern linked document or extern linked
1533                 // document section, if section is protected.
1534                 if ( pSrcDoc != pDoc &&
1535                      rSection.IsProtectFlag() )
1536                 {
1537                     pSrcDoc->GetLinkManager().UpdateAllLinks( sal_False, sal_True, sal_False, 0 );
1538                 }
1539                 // <--
1540 				if( pCpyRg )
1541 				{
1542 					SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
1543 					sal_Bool bCreateFrm = rInsPos.GetIndex() <=
1544 								pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
1545 								rInsPos.GetNode().FindTableNode();
1546 
1547 					SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc );
1548 
1549                     pSrcDoc->CopyWithFlyInFly( *pCpyRg, 0, rInsPos, bCreateFrm );
1550 					aSave++;
1551 
1552 					if( !bCreateFrm )
1553 						::MakeFrms( pDoc, aSave, rInsPos );
1554 
1555 					// den letzten Node noch loeschen, aber nur wenn
1556 					// erfolgreich kopiert werden konnte, also der Bereich
1557 					// mehr als 1 Node enthaelt
1558 					if( 2 < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() )
1559 					{
1560 						aSave = rInsPos;
1561 						pPam->Move( fnMoveBackward, fnGoNode );
1562 						pPam->SetMark();	// beide SwPositions ummelden!
1563 
1564 						pDoc->CorrAbs( aSave, *pPam->GetPoint(), 0, sal_True );
1565 						pDoc->GetNodes().Delete( aSave, 1 );
1566 					}
1567 					delete pCpyRg;
1568 				}
1569 
1570                 // --> OD 2007-02-14 #b6521322#
1571                 lcl_BreakSectionLinksInSect( *pSectNd );
1572                 // <--
1573 
1574                 // update alle Links in diesem Bereich
1575 				lcl_UpdateLinksInSect( *this, *pSectNd );
1576 			}
1577 			if( xDocSh.Is() )
1578 			{
1579 				if( 2 == nRet )
1580 					xDocSh->DoClose();
1581                 else if( ((SwDocShell*)&xDocSh)->GetDoc() )
1582 					((SwDocShell*)&xDocSh)->GetDoc()->SetRedlineMode(
1583 								eOldRedlineMode );
1584 			}
1585 		}
1586 		break;
1587 	}
1588 
1589 	// !!!! DDE nur updaten wenn Shell vorhanden ist??
1590     uno::Sequence< sal_Int8 > aSeq;
1591 	if( pRead && rValue.hasValue() && ( rValue >>= aSeq ) )
1592 	{
1593 		if( pESh )
1594 		{
1595 			pESh->Push();
1596 			SwPaM* pCrsr = pESh->GetCrsr();
1597 			*pCrsr->GetPoint() = *pPam->GetPoint();
1598 			delete pPam;
1599 			pPam = pCrsr;
1600 		}
1601 
1602 		SvMemoryStream aStrm( (void*)aSeq.getConstArray(), aSeq.getLength(),
1603 								STREAM_READ );
1604 		aStrm.Seek( 0 );
1605 
1606 #if OSL_DEBUG_LEVEL > 1
1607 		{
1608 			SvFileStream aDeb( String::CreateFromAscii(
1609 					"file:///d|/temp/update.txt" ), STREAM_WRITE );
1610 			aDeb << aStrm;
1611 		}
1612 		aStrm.Seek( 0 );
1613 #endif
1614 
1615         // TODO/MBA: it's impossible to set a BaseURL here!
1616         SwReader aTmpReader( aStrm, aEmptyStr, pDoc->GetDocShell()->GetMedium()->GetBaseURL(), *pPam );
1617 
1618 		if( !IsError( aTmpReader.Read( *pRead ) ))
1619         {
1620             rSection.SetConnectFlag(true);
1621         }
1622 
1623 		if( pESh )
1624 		{
1625 			pESh->Pop( sal_False );
1626 			pPam = 0;			        // pam is deleted before
1627 		}
1628 	}
1629 
1630 
1631     // remove all undo actions and turn undo on again
1632     pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
1633     pDoc->GetIDocumentUndoRedo().DoUndo(bWasUndo);
1634 	pDoc->SetVisibleLinks( bWasVisibleLinks );
1635 
1636 	pDoc->UnlockExpFlds();
1637 	if( !pDoc->IsExpFldsLocked() )
1638 		pDoc->UpdateExpFlds(NULL, true);
1639 
1640 	if( pESh )
1641 		pESh->EndAllAction();
1642 	else if( pVSh )
1643 		pVSh->EndAction();
1644 	delete pPam;			// wurde am Anfang angelegt
1645 }
1646 
1647 
1648 void SwIntrnlSectRefLink::Closed()
1649 {
1650 	SwDoc* pDoc = rSectFmt.GetDoc();
1651 	if( pDoc && !pDoc->IsInDtor() )
1652 	{
1653 		// Advise verabschiedet sich, den Bereich als nicht geschuetzt
1654 		// kennzeichnen und das Flag umsetzen
1655 
1656 		const SwSectionFmts& rFmts = pDoc->GetSections();
1657 		for( sal_uInt16 n = rFmts.Count(); n; )
1658 			if( rFmts[ --n ] == &rSectFmt )
1659 			{
1660 				ViewShell* pSh;
1661 				SwEditShell* pESh = pDoc->GetEditShell( &pSh );
1662 
1663 				if( pESh )
1664 					pESh->StartAllAction();
1665 				else
1666 					pSh->StartAction();
1667 
1668                 SwSectionData aSectionData(*rSectFmt.GetSection());
1669                 aSectionData.SetType( CONTENT_SECTION );
1670                 aSectionData.SetLinkFileName( aEmptyStr );
1671                 aSectionData.SetHidden( false );
1672                 aSectionData.SetProtectFlag( false );
1673                 // --> FME 2004-06-22 #114856# edit in readonly sections
1674                 aSectionData.SetEditInReadonlyFlag( false );
1675                 // <--
1676 
1677                 aSectionData.SetConnectFlag( false );
1678 
1679                 pDoc->UpdateSection( n, aSectionData );
1680 
1681 				// alle in der Section liegenden Links werden sichtbar
1682 				SwSectionNode* pSectNd = rSectFmt.GetSectionNode( sal_False );
1683 				if( pSectNd )
1684 					pSectNd->GetSection().MakeChildLinksVisible( *pSectNd );
1685 
1686 				if( pESh )
1687 					pESh->EndAllAction();
1688 				else
1689 					pSh->EndAction();
1690 				break;
1691 			}
1692 	}
1693 	SvBaseLink::Closed();
1694 }
1695 
1696 
1697 void SwSection::CreateLink( LinkCreateType eCreateType )
1698 {
1699 	SwSectionFmt* pFmt = GetFmt();
1700     ASSERT(pFmt, "SwSection::CreateLink: no format?");
1701     if (!pFmt || (CONTENT_SECTION == m_Data.GetType()))
1702 		return ;
1703 
1704     sal_uInt16 nUpdateType = sfx2::LINKUPDATE_ALWAYS;
1705 
1706     if (!m_RefLink.Is())
1707     {
1708         // create BaseLink
1709         m_RefLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF );
1710     }
1711     else
1712     {
1713         pFmt->GetDoc()->GetLinkManager().Remove( m_RefLink );
1714     }
1715 
1716     SwIntrnlSectRefLink *const pLnk =
1717         static_cast<SwIntrnlSectRefLink*>(& m_RefLink);
1718 
1719     String sCmd( m_Data.GetLinkFileName() );
1720 	xub_StrLen nPos;
1721 	while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( "  " )) )
1722 		sCmd.Erase( nPos, 1 );
1723 
1724 	pLnk->SetUpdateMode( nUpdateType );
1725 	pLnk->SetVisible( pFmt->GetDoc()->IsVisibleLinks() );
1726 
1727     switch (m_Data.GetType())
1728 	{
1729 	case DDE_LINK_SECTION:
1730 		pLnk->SetLinkSourceName( sCmd );
1731 		pFmt->GetDoc()->GetLinkManager().InsertDDELink( pLnk );
1732 		break;
1733 	case FILE_LINK_SECTION:
1734 		{
1735 			pLnk->SetContentType( FORMAT_FILE );
1736             String sFltr( sCmd.GetToken( 1, sfx2::cTokenSeperator ) );
1737             String sRange( sCmd.GetToken( 2, sfx2::cTokenSeperator ) );
1738 			pFmt->GetDoc()->GetLinkManager().InsertFileLink( *pLnk,
1739                                 static_cast<sal_uInt16>(m_Data.GetType()),
1740                                 sCmd.GetToken( 0, sfx2::cTokenSeperator ),
1741 								( sFltr.Len() ? &sFltr : 0 ),
1742 								( sRange.Len() ? &sRange : 0 ) );
1743 		}
1744 		break;
1745 	default:
1746 		ASSERT( !this, "Was ist das fuer ein Link?" )
1747 	}
1748 
1749 	switch( eCreateType )
1750 	{
1751 	case CREATE_CONNECT:			// Link gleich connecten
1752 		pLnk->Connect();
1753 		break;
1754 
1755 	case CREATE_UPDATE: 		// Link connecten und updaten
1756 		pLnk->Update();
1757 		break;
1758     case CREATE_NONE: break;
1759 	}
1760 }
1761 
1762 // --> OD 2007-02-14 #b6521322#
1763 void SwSection::BreakLink()
1764 {
1765     const SectionType eCurrentType( GetType() );
1766     if ( eCurrentType == CONTENT_SECTION ||
1767          eCurrentType == TOX_HEADER_SECTION ||
1768          eCurrentType == TOX_CONTENT_SECTION )
1769     {
1770         // nothing to do
1771         return;
1772     }
1773 
1774     // release link, if it exists
1775     if (m_RefLink.Is())
1776     {
1777         SwSectionFmt *const pFormat( GetFmt() );
1778         ASSERT(pFormat, "SwSection::BreakLink: no format?");
1779         if (pFormat)
1780         {
1781             pFormat->GetDoc()->GetLinkManager().Remove( m_RefLink );
1782         }
1783         m_RefLink.Clear();
1784     }
1785     // change type
1786     SetType( CONTENT_SECTION );
1787     // reset linked file data
1788     SetLinkFileName( aEmptyStr );
1789     SetLinkFilePassword( aEmptyStr );
1790 }
1791 // <--
1792 
1793 const SwNode* SwIntrnlSectRefLink::GetAnchor() const
1794 {
1795 	return rSectFmt.GetSectionNode( sal_False );
1796 }
1797 
1798 
1799 sal_Bool SwIntrnlSectRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd,
1800 									 xub_StrLen , xub_StrLen ) const
1801 {
1802 	SwStartNode* pSttNd = rSectFmt.GetSectionNode( sal_False );
1803 	return pSttNd &&
1804 			nSttNd < pSttNd->GetIndex() &&
1805 			pSttNd->EndOfSectionIndex() < nEndNd;
1806 }
1807 
1808 
1809 
1810