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 additionaly )
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( !this, "Was ist das fuer ein 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