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