1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <libxml/xmlstring.h>
21 #include <libxml/xmlwriter.h>
23 #include <hintids.hxx>
24 #include <osl/diagnose.h>
25 #include <sot/exchange.hxx>
26 #include <svl/stritem.hxx>
27 #include <sfx2/docfile.hxx>
28 #include <editeng/protitem.hxx>
29 #include <sfx2/linkmgr.hxx>
30 #include <sfx2/sfxsids.hrc>
32 #include <fmtcntnt.hxx>
33 #include <fmtpdsc.hxx>
35 #include <IDocumentUndoRedo.hxx>
36 #include <DocumentLinksAdministrationManager.hxx>
37 #include <DocumentContentOperationsManager.hxx>
38 #include <IDocumentRedlineAccess.hxx>
39 #include <IDocumentFieldsAccess.hxx>
40 #include <IDocumentStylePoolAccess.hxx>
41 #include <IDocumentState.hxx>
42 #include <IDocumentLayoutAccess.hxx>
46 #include <frmtool.hxx>
51 #include <section.hxx>
53 #include <shellio.hxx>
54 #include <poolfmt.hxx>
55 #include <swbaslnk.hxx>
59 #include <fmteiro.hxx>
60 #include <unosection.hxx>
62 #include <fmtclds.hxx>
67 using namespace ::com::sun::star
;
70 class SwIntrnlSectRefLink
: public SwBaseLink
72 SwSectionFormat
& m_rSectFormat
;
75 SwIntrnlSectRefLink(SwSectionFormat
& rFormat
, SfxLinkUpdateMode nUpdateType
)
76 : SwBaseLink(nUpdateType
, SotClipboardFormatId::RTF
)
77 , m_rSectFormat(rFormat
)
80 virtual void Closed() override
;
81 virtual ::sfx2::SvBaseLink::UpdateResult
DataChanged(
82 const OUString
& rMimeType
, const css::uno::Any
& rValue
) override
;
84 virtual const SwNode
* GetAnchor() const override
;
85 virtual bool IsInRange( SwNodeOffset nSttNd
, SwNodeOffset nEndNd
) const override
;
87 SwSectionNode
* GetSectNode()
89 const SwNode
* pSectNd( GetAnchor() );
90 return const_cast<SwSectionNode
*>( pSectNd
->GetSectionNode() );
95 SwSectionData::SwSectionData(SectionType
const eType
, OUString aName
)
97 , m_sSectionName(std::move(aName
))
98 , m_bHiddenFlag(false)
99 , m_bProtectFlag(false)
100 , m_bEditInReadonlyFlag(false) // edit in readonly sections
102 , m_bCondHiddenFlag(true)
103 , m_bConnectFlag(true)
107 // this must have the same semantics as operator=()
108 SwSectionData::SwSectionData(SwSection
const& rSection
)
109 : m_eType(rSection
.GetType())
110 , m_sSectionName(rSection
.GetSectionName())
111 , m_sCondition(rSection
.GetCondition())
112 , m_sLinkFileName(rSection
.GetLinkFileName())
113 , m_sLinkFilePassword(rSection
.GetLinkFilePassword())
114 , m_Password(rSection
.GetPassword())
115 , m_bHiddenFlag(rSection
.IsHiddenFlag())
116 , m_bProtectFlag(rSection
.IsProtect())
117 // edit in readonly sections
118 , m_bEditInReadonlyFlag(rSection
.IsEditInReadonly())
119 , m_bHidden(rSection
.IsHidden())
120 , m_bCondHiddenFlag(true)
121 , m_bConnectFlag(rSection
.IsConnectFlag())
125 // this must have the same semantics as operator=()
126 SwSectionData::SwSectionData(SwSectionData
const& rOther
)
127 : m_eType(rOther
.m_eType
)
128 , m_sSectionName(rOther
.m_sSectionName
)
129 , m_sCondition(rOther
.m_sCondition
)
130 , m_sLinkFileName(rOther
.m_sLinkFileName
)
131 , m_sLinkFilePassword(rOther
.m_sLinkFilePassword
)
132 , m_Password(rOther
.m_Password
)
133 , m_bHiddenFlag(rOther
.m_bHiddenFlag
)
134 , m_bProtectFlag(rOther
.m_bProtectFlag
)
135 // edit in readonly sections
136 , m_bEditInReadonlyFlag(rOther
.m_bEditInReadonlyFlag
)
137 , m_bHidden(rOther
.m_bHidden
)
138 , m_bCondHiddenFlag(true)
139 , m_bConnectFlag(rOther
.m_bConnectFlag
)
143 // the semantics here are weird for reasons of backward compatibility
144 SwSectionData
& SwSectionData::operator= (SwSectionData
const& rOther
)
146 m_eType
= rOther
.m_eType
;
147 m_sSectionName
= rOther
.m_sSectionName
;
148 m_sCondition
= rOther
.m_sCondition
;
149 m_sLinkFileName
= rOther
.m_sLinkFileName
;
150 m_sLinkFilePassword
= rOther
.m_sLinkFilePassword
;
151 m_bConnectFlag
= rOther
.m_bConnectFlag
;
152 m_Password
= rOther
.m_Password
;
154 m_bEditInReadonlyFlag
= rOther
.m_bEditInReadonlyFlag
;
155 m_bProtectFlag
= rOther
.m_bProtectFlag
;
157 m_bHidden
= rOther
.m_bHidden
;
158 // FIXME: old code did not assign m_bHiddenFlag ?
159 // FIXME: why should m_bCondHiddenFlag always default to true?
160 m_bCondHiddenFlag
= true;
165 // the semantics here are weird for reasons of backward compatibility
166 bool SwSectionData::operator==(SwSectionData
const& rOther
) const
168 return (m_eType
== rOther
.m_eType
)
169 && (m_sSectionName
== rOther
.m_sSectionName
)
170 && (m_sCondition
== rOther
.m_sCondition
)
171 && (m_bHidden
== rOther
.m_bHidden
)
172 && (m_bProtectFlag
== rOther
.m_bProtectFlag
)
173 && (m_bEditInReadonlyFlag
== rOther
.m_bEditInReadonlyFlag
)
174 && (m_sLinkFileName
== rOther
.m_sLinkFileName
)
175 && (m_sLinkFilePassword
== rOther
.m_sLinkFilePassword
)
176 && (m_Password
== rOther
.m_Password
);
177 // FIXME: old code ignored m_bCondHiddenFlag m_bHiddenFlag m_bConnectFlag
180 void SwSectionData::dumpAsXml(xmlTextWriterPtr pWriter
) const
182 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwSectionData"));
183 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
184 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("section-name"), BAD_CAST(m_sSectionName
.toUtf8().getStr()));
185 (void)xmlTextWriterEndElement(pWriter
);
188 SwSection::SwSection(
189 SectionType
const eType
, OUString
const& rName
, SwSectionFormat
& rFormat
)
190 : SwClient(& rFormat
)
191 , m_Data(eType
, rName
)
193 StartListening(rFormat
.GetNotifier());
195 SwSection
*const pParentSect
= GetParent();
198 // edit in readonly sections
199 m_Data
.SetEditInReadonlyFlag( pParentSect
->IsEditInReadonlyFlag() );
202 m_Data
.SetProtectFlag( rFormat
.GetProtect().IsContentProtected() );
204 if (!m_Data
.IsEditInReadonlyFlag()) // edit in readonly sections
206 m_Data
.SetEditInReadonlyFlag( rFormat
.GetEditInReadonly().GetValue() );
210 SwSection::~SwSection()
212 SwSectionFormat
* pFormat
= GetFormat();
216 SwDoc
* pDoc
= pFormat
->GetDoc();
217 if( pDoc
->IsInDtor() )
219 // We reattach our Format to the default FrameFormat
220 // to not get any dependencies
221 if( pFormat
->DerivedFrom() != pDoc
->GetDfltFrameFormat() )
222 pFormat
->RegisterToFormat( *pDoc
->GetDfltFrameFormat() );
226 pFormat
->Remove( this ); // remove
227 SvtListener::EndListeningAll();
229 if (SectionType::Content
!= m_Data
.GetType())
231 pDoc
->getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink
.get() );
236 pDoc
->getIDocumentLinksAdministration().GetLinkManager().RemoveServer( m_RefObj
.get() );
239 // If the Section is the last Client in the Format we can delete it
240 pFormat
->RemoveAllUnos();
241 if( !pFormat
->HasWriterListeners() )
243 // Do not add to the Undo. This should've happened earlier.
244 ::sw::UndoGuard
const undoGuard(pDoc
->GetIDocumentUndoRedo());
245 pDoc
->DelSectionFormat( pFormat
);
254 void SwSection::SetSectionData(SwSectionData
const& rData
)
256 bool const bOldHidden( m_Data
.IsHidden() );
258 // The next two may actually overwrite the m_Data.m_bProtect or EditInReadonly Flag
259 // in Modify, which should result in same flag value as the old code!
260 SetProtect(m_Data
.IsProtectFlag());
261 SetEditInReadonly(m_Data
.IsEditInReadonlyFlag());
262 if (bOldHidden
!= m_Data
.IsHidden()) // check if changed...
264 ImplSetHiddenFlag(m_Data
.IsHidden(), m_Data
.IsCondHidden());
268 bool SwSection::DataEquals(SwSectionData
const& rCmp
) const
270 // note that the old code compared the flags of the parameter with the
271 // format attributes of this; the following mess should do the same...
272 (void) GetLinkFileName(); // updates m_sLinkFileName
273 bool const bProtect(m_Data
.IsProtectFlag());
274 bool const bEditInReadonly(m_Data
.IsEditInReadonlyFlag());
275 m_Data
.SetProtectFlag(IsProtect());
276 m_Data
.SetEditInReadonlyFlag(IsEditInReadonly());
277 bool const bResult( m_Data
== rCmp
);
278 m_Data
.SetProtectFlag(bProtect
);
279 m_Data
.SetEditInReadonlyFlag(bEditInReadonly
);
283 void SwSection::ImplSetHiddenFlag(bool const bTmpHidden
, bool const bCondition
)
285 SwSectionFormat
* pFormat
= GetFormat();
286 OSL_ENSURE(pFormat
, "ImplSetHiddenFlag: no format?");
290 const bool bHide
= bTmpHidden
&& bCondition
;
292 if (bHide
) // should be hidden
294 if (!m_Data
.IsHiddenFlag()) // is not hidden
296 // Is the Parent hidden?
297 // This should be shown by the bHiddenFlag.
299 // Tell all Children that they are hidden
300 const sw::SectionHidden aHint
;
301 pFormat
->CallSwClientNotify(aHint
);
304 pFormat
->DelFrames();
307 else if (m_Data
.IsHiddenFlag()) // show Nodes again
309 // Show all Frames (Child Sections are accounted for by MakeFrames)
310 // Only if the Parent Section is not restricting us!
311 SwSection
* pParentSect
= pFormat
->GetParentSection();
312 if( !pParentSect
|| !pParentSect
->IsHiddenFlag() )
314 // Tell all Children that the Parent is not hidden anymore
315 const sw::SectionHidden
aHint(false);
316 pFormat
->CallSwClientNotify(aHint
);
318 pFormat
->MakeFrames();
323 bool SwSection::CalcHiddenFlag() const
325 const SwSection
* pSect
= this;
327 if( pSect
->IsHidden() && pSect
->IsCondHidden() )
329 } while( nullptr != ( pSect
= pSect
->GetParent()) );
334 bool SwSection::IsProtect() const
336 SwSectionFormat
const *const pFormat( GetFormat() );
337 OSL_ENSURE(pFormat
, "SwSection::IsProtect: no format?");
339 ? pFormat
->GetProtect().IsContentProtected()
343 // edit in readonly sections
344 bool SwSection::IsEditInReadonly() const
346 SwSectionFormat
const *const pFormat( GetFormat() );
347 OSL_ENSURE(pFormat
, "SwSection::IsEditInReadonly: no format?");
349 ? pFormat
->GetEditInReadonly().GetValue()
350 : IsEditInReadonlyFlag();
353 void SwSection::SetHidden(bool const bFlag
)
355 if (!m_Data
.IsHidden() == !bFlag
)
358 m_Data
.SetHidden(bFlag
);
359 ImplSetHiddenFlag(bFlag
, m_Data
.IsCondHidden());
362 void SwSection::SetProtect(bool const bFlag
)
364 SwSectionFormat
*const pFormat( GetFormat() );
365 OSL_ENSURE(pFormat
, "SwSection::SetProtect: no format?");
368 SvxProtectItem
aItem( RES_PROTECT
);
369 aItem
.SetContentProtect( bFlag
);
370 pFormat
->SetFormatAttr( aItem
);
371 // note: this will call m_Data.SetProtectFlag via Modify!
375 m_Data
.SetProtectFlag(bFlag
);
379 // edit in readonly sections
380 void SwSection::SetEditInReadonly(bool const bFlag
)
382 SwSectionFormat
*const pFormat( GetFormat() );
383 OSL_ENSURE(pFormat
, "SwSection::SetEditInReadonly: no format?");
386 SwFormatEditInReadonly aItem
;
387 aItem
.SetValue( bFlag
);
388 pFormat
->SetFormatAttr( aItem
);
389 // note: this will call m_Data.SetEditInReadonlyFlag via Modify!
393 m_Data
.SetEditInReadonlyFlag(bFlag
);
397 void SwSection::SwClientNotify(const SwModify
&, const SfxHint
& rHint
)
402 void SwSection::Notify(SfxHint
const& rHint
)
404 if (rHint
.GetId() == SfxHintId::SwSectionHidden
)
406 auto rSectionHidden
= static_cast<const sw::SectionHidden
&>(rHint
);
407 m_Data
.SetHiddenFlag(rSectionHidden
.m_isHidden
|| (m_Data
.IsHidden() && m_Data
.IsCondHidden()));
409 } else if (rHint
.GetId() != SfxHintId::SwLegacyModify
)
411 auto pLegacy
= static_cast<const sw::LegacyModifyHint
*>(&rHint
);
412 auto pOld
= pLegacy
->m_pOld
;
413 auto pNew
= pLegacy
->m_pNew
;
414 bool bUpdateFootnote
= false;
415 switch(pLegacy
->GetWhich())
417 case RES_ATTRSET_CHG
:
420 SfxItemSet
* pNewSet
= const_cast<SwAttrSetChg
*>(static_cast<const SwAttrSetChg
*>(pNew
))->GetChgSet();
421 SfxItemSet
* pOldSet
= const_cast<SwAttrSetChg
*>(static_cast<const SwAttrSetChg
*>(pOld
))->GetChgSet();
423 if( const SvxProtectItem
* pItem
= pNewSet
->GetItemIfSet(
424 RES_PROTECT
, false ) )
426 m_Data
.SetProtectFlag( pItem
->IsContentProtected() );
427 pNewSet
->ClearItem( RES_PROTECT
);
428 pOldSet
->ClearItem( RES_PROTECT
);
431 // --> edit in readonly sections
432 if( const SwFormatEditInReadonly
* pItem
= pNewSet
->GetItemIfSet(
433 RES_EDIT_IN_READONLY
, false ) )
435 m_Data
.SetEditInReadonlyFlag(pItem
->GetValue());
436 pNewSet
->ClearItem( RES_EDIT_IN_READONLY
);
437 pOldSet
->ClearItem( RES_EDIT_IN_READONLY
);
440 if( SfxItemState::SET
== pNewSet
->GetItemState(
441 RES_FTN_AT_TXTEND
, false ) ||
442 SfxItemState::SET
== pNewSet
->GetItemState(
443 RES_END_AT_TXTEND
, false ))
445 bUpdateFootnote
= true;
448 if( !pNewSet
->Count() )
457 static_cast<const SvxProtectItem
*>(pNew
)->IsContentProtected();
458 // this used to inherit the flag from the parent, but then there is
459 // no way to turn it off in an inner section
460 m_Data
.SetProtectFlag( bNewFlag
);
463 // edit in readonly sections
464 case RES_EDIT_IN_READONLY
:
467 const bool bNewFlag
=
468 static_cast<const SwFormatEditInReadonly
*>(pNew
)->GetValue();
469 m_Data
.SetEditInReadonlyFlag( bNewFlag
);
474 // Is handled by the Layout, if appropriate
477 case RES_FTN_AT_TXTEND
:
480 bUpdateFootnote
= true;
484 case RES_END_AT_TXTEND
:
487 bUpdateFootnote
= true;
492 CheckRegistration( pOld
);
496 if( bUpdateFootnote
)
498 SwSectionNode
* pSectNd
= GetFormat()->GetSectionNode();
500 pSectNd
->GetDoc().GetFootnoteIdxs().UpdateFootnote(*pSectNd
);
504 void SwSection::SetRefObject( SwServerObject
* pObj
)
509 void SwSection::SetCondHidden(bool const bFlag
)
511 if (!m_Data
.IsCondHidden() == !bFlag
)
514 m_Data
.SetCondHidden(bFlag
);
515 ImplSetHiddenFlag(m_Data
.IsHidden(), bFlag
);
518 // Set/remove the linked FileName
519 OUString
const & SwSection::GetLinkFileName() const
524 switch (m_Data
.GetType())
526 case SectionType::DdeLink
:
527 sTmp
= m_RefLink
->GetLinkSourceName();
530 case SectionType::FileLink
:
534 if (m_RefLink
->GetLinkManager() &&
535 sfx2::LinkManager::GetDisplayNames(
536 m_RefLink
.get(), nullptr, &sTmp
, &sRange
, &sFilter
))
538 sTmp
+= OUStringChar(sfx2::cTokenSeparator
) + sFilter
539 + OUStringChar(sfx2::cTokenSeparator
) + sRange
;
541 else if( GetFormat() && !GetFormat()->GetSectionNode() )
543 // If the Section is in the UndoNodesArray, the LinkManager
544 // does not contain the Link, thus it cannot be queried for it.
545 // Thus return the current Name.
546 return m_Data
.GetLinkFileName();
552 m_Data
.SetLinkFileName(sTmp
);
554 return m_Data
.GetLinkFileName();
557 void SwSection::SetLinkFileName(const OUString
& rNew
)
561 m_RefLink
->SetLinkSourceName( rNew
);
563 m_Data
.SetLinkFileName(rNew
);
566 // If it was a Linked Section, we need to make all Child Links visible
567 void SwSection::MakeChildLinksVisible( const SwSectionNode
& rSectNd
)
570 const ::sfx2::SvBaseLinks
& rLnks
= rSectNd
.GetDoc().getIDocumentLinksAdministration().GetLinkManager().GetLinks();
571 for( auto n
= rLnks
.size(); n
; )
573 sfx2::SvBaseLink
& rBLnk
= *rLnks
[--n
];
574 if (!rBLnk
.IsVisible() && dynamic_cast<const SwBaseLink
*>(&rBLnk
) != nullptr
575 && nullptr != (pNd
= static_cast<SwBaseLink
&>(rBLnk
).GetAnchor()))
577 pNd
= pNd
->StartOfSectionNode(); // If it's a SectionNode
578 const SwSectionNode
* pParent
;
579 while( nullptr != ( pParent
= pNd
->FindSectionNode() ) &&
580 ( SectionType::Content
== pParent
->GetSection().GetType()
581 || pNd
== &rSectNd
))
582 pNd
= pParent
->StartOfSectionNode();
584 // It's within a normal Section, so show again
586 rBLnk
.SetVisible(true);
591 const SwTOXBase
* SwSection::GetTOXBase() const
593 const SwTOXBase
* pRet
= nullptr;
594 if( SectionType::ToxContent
== GetType() )
595 pRet
= dynamic_cast<const SwTOXBaseSection
*>(this);
599 SwSectionFormat::SwSectionFormat( SwFrameFormat
* pDrvdFrame
, SwDoc
*pDoc
)
600 : SwFrameFormat( pDoc
->GetAttrPool(), OUString(), pDrvdFrame
)
603 SetFormatAttr( *GetDfltAttr( RES_COL
) );
607 SwSectionFormat::~SwSectionFormat()
609 if( GetDoc()->IsInDtor() )
612 SwSectionNode
* pSectNd
;
613 const SwNodeIndex
* pIdx
= GetContent( false ).GetContentIdx();
614 if( pIdx
&& &GetDoc()->GetNodes() == &pIdx
->GetNodes() &&
615 nullptr != (pSectNd
= pIdx
->GetNode().GetSectionNode() ))
617 SwSection
& rSect
= pSectNd
->GetSection();
618 // If it was a linked Section, we need to make all Child Links
620 if( rSect
.IsConnected() )
621 SwSection::MakeChildLinksVisible( *pSectNd
);
623 // Check whether we need to be visible, before deleting the Nodes
624 if( rSect
.IsHiddenFlag() )
626 SwSection
* pParentSect
= rSect
.GetParent();
627 if( !pParentSect
|| !pParentSect
->IsHiddenFlag() )
629 // Make Nodes visible again
630 rSect
.SetHidden(false);
633 // mba: test iteration; objects are removed while iterating
634 // use hint which allows to specify, if the content shall be saved or not
635 CallSwClientNotify( SwSectionFrameMoveAndDeleteHint( true ) );
637 // Raise the Section up
638 SwNodeRange
aRg( *pSectNd
, SwNodeOffset(0), *pSectNd
->EndOfSectionNode() );
639 GetDoc()->GetNodes().SectionUp( &aRg
);
642 ResetFormatAttr( RES_CNTNT
);
646 SwSection
* SwSectionFormat::GetSection() const
648 return SwIterator
<SwSection
,SwSectionFormat
>( *this ).First();
651 // Do not destroy all Frames in aDepend (Frames are recognized with a dynamic_cast).
652 void SwSectionFormat::DelFrames()
654 SwSectionNode
* pSectNd
;
655 const SwNodeIndex
* pIdx
= GetContent(false).GetContentIdx();
656 if( pIdx
&& &GetDoc()->GetNodes() == &pIdx
->GetNodes() &&
657 nullptr != (pSectNd
= pIdx
->GetNode().GetSectionNode() ))
659 // First delete the <SwSectionFrame> of the <SwSectionFormat> instance
660 // mba: test iteration as objects are removed in iteration
661 // use hint which allows to specify, if the content shall be saved or not
662 CallSwClientNotify( SwSectionFrameMoveAndDeleteHint( false ) );
664 // Then delete frames of the nested <SwSectionFormat> instances
665 SwIterator
<SwSectionFormat
,SwSectionFormat
> aIter( *this );
666 SwSectionFormat
*pLast
= aIter
.First();
670 pLast
= aIter
.Next();
673 SwNodeOffset nEnd
= pSectNd
->EndOfSectionIndex();
674 SwNodeOffset nStart
= pSectNd
->GetIndex()+1;
675 sw_DeleteFootnote( pSectNd
, nStart
, nEnd
);
680 // Send Hint for PageDesc. Actually the Layout contained in the
681 // Paste of the Frame itself would need to do this. But that leads
682 // to subsequent errors, which we'd need to solve at run-time.
683 SwNodeIndex
aNextNd( *pIdx
);
684 SwContentNode
* pCNd
= GetDoc()->GetNodes().GoNextSection( &aNextNd
, true, false );
687 const SfxPoolItem
& rItem
= pCNd
->GetSwAttrSet().Get(RES_PAGEDESC
);
688 pCNd
->CallSwClientNotify(sw::LegacyModifyHint(&rItem
, &rItem
));
693 void SwSectionFormat::MakeFrames()
695 SwSectionNode
* pSectNd
;
696 const SwNodeIndex
* pIdx
= GetContent(false).GetContentIdx();
698 if( pIdx
&& &GetDoc()->GetNodes() == &pIdx
->GetNodes() &&
699 nullptr != (pSectNd
= pIdx
->GetNode().GetSectionNode() ))
701 SwNodeIndex
aIdx( *pIdx
);
702 pSectNd
->MakeOwnFrames( &aIdx
);
706 void SwSectionFormat::SwClientNotify(const SwModify
& rMod
, const SfxHint
& rHint
)
708 if (rHint
.GetId() == SfxHintId::SwSectionHidden
)
710 auto rSectionHidden
= static_cast<const sw::SectionHidden
&>(rHint
);
711 auto pSect
= GetSection();
712 if(!pSect
|| rSectionHidden
.m_isHidden
== pSect
->IsHiddenFlag()) // already at target state, skipping.
714 GetNotifier().Broadcast(rSectionHidden
);
716 } else if (rHint
.GetId() != SfxHintId::SwLegacyModify
)
718 auto pLegacy
= static_cast<const sw::LegacyModifyHint
*>(&rHint
);
719 sal_uInt16 nWhich
= pLegacy
->GetWhich();
720 auto pOld
= pLegacy
->m_pOld
;
721 auto pNew
= pLegacy
->m_pNew
;
724 case RES_ATTRSET_CHG
:
725 if (HasWriterListeners() && pOld
&& pNew
)
727 SfxItemSet
* pNewSet
= const_cast<SwAttrSetChg
*>(static_cast<const SwAttrSetChg
*>(pNew
))->GetChgSet();
728 SfxItemSet
* pOldSet
= const_cast<SwAttrSetChg
*>(static_cast<const SwAttrSetChg
*>(pOld
))->GetChgSet();
729 const SfxPoolItem
*pItem
;
730 if( SfxItemState::SET
== pNewSet
->GetItemState(
731 RES_PROTECT
, false, &pItem
))
733 GetNotifier().Broadcast(sw::LegacyModifyHint(pItem
, pItem
));
734 pNewSet
->ClearItem( RES_PROTECT
);
735 pOldSet
->ClearItem( RES_PROTECT
);
738 // --> edit in readonly sections
739 if( SfxItemState::SET
== pNewSet
->GetItemState(
740 RES_EDIT_IN_READONLY
, false, &pItem
) )
742 GetNotifier().Broadcast(sw::LegacyModifyHint(pItem
, pItem
));
743 pNewSet
->ClearItem( RES_EDIT_IN_READONLY
);
744 pOldSet
->ClearItem( RES_EDIT_IN_READONLY
);
747 if( SfxItemState::SET
== pNewSet
->GetItemState(
748 RES_FTN_AT_TXTEND
, false, &pItem
))
750 GetNotifier().Broadcast(sw::LegacyModifyHint(pItem
, pItem
));
751 pNewSet
->ClearItem( RES_FTN_AT_TXTEND
);
752 pOldSet
->ClearItem( RES_FTN_AT_TXTEND
);
754 if( SfxItemState::SET
== pNewSet
->GetItemState(
755 RES_END_AT_TXTEND
, false, &pItem
))
757 GetNotifier().Broadcast(sw::LegacyModifyHint(pItem
, pItem
));
758 pNewSet
->ClearItem( RES_END_AT_TXTEND
);
759 pOldSet
->ClearItem( RES_END_AT_TXTEND
);
761 if( !static_cast<const SwAttrSetChg
*>(pOld
)->GetChgSet()->Count() )
766 case RES_FTN_AT_TXTEND
:
767 case RES_END_AT_TXTEND
:
768 GetNotifier().Broadcast(sw::LegacyModifyHint(pOld
, pNew
));
771 case RES_EDIT_IN_READONLY
: // edit in readonly sections
772 // Pass through these Messages until the End of the tree!
773 GetNotifier().Broadcast(sw::LegacyModifyHint(pOld
, pNew
));
774 return; // That's it!
776 case RES_OBJECTDYING
:
777 if( !GetDoc()->IsInDtor() && pOld
&&
778 static_cast<const SwPtrMsgPoolItem
*>(pOld
)->pObject
== static_cast<void*>(GetRegisteredIn()) )
780 // My Parents will be destroyed, so get the Parent's Parent
782 SwFrameFormat::SwClientNotify(rMod
, rHint
);
789 if( !GetDoc()->IsInDtor() &&
790 static_cast<const SwFormatChg
*>(pNew
)->pChangedFormat
== static_cast<void*>(GetRegisteredIn()) &&
791 dynamic_cast<const SwSectionFormat
*>(static_cast<const SwFormatChg
*>(pNew
)->pChangedFormat
) != nullptr )
793 // My Parent will be changed, thus I need to update
794 SwFrameFormat::SwClientNotify(rMod
, rHint
);
800 SwFrameFormat::SwClientNotify(rMod
, rHint
);
802 if (pOld
&& (RES_REMOVE_UNO_OBJECT
== pOld
->Which()))
803 { // invalidate cached uno object
804 SetXTextSection(nullptr);
808 void SwSectionFormat::SetXTextSection(rtl::Reference
<SwXTextSection
> const& xTextSection
)
810 m_wXTextSection
= xTextSection
.get();
813 bool SwSectionFormat::IsVisible() const
815 if(SwFrameFormat::IsVisible())
817 SwIterator
<SwSectionFormat
,SwSectionFormat
> aFormatIter(*this);
818 for(SwSectionFormat
* pChild
= aFormatIter
.First(); pChild
; pChild
= aFormatIter
.Next())
819 if(pChild
->IsVisible())
824 // Get info from the Format
825 bool SwSectionFormat::GetInfo(SfxPoolItem
& rInfo
) const
827 if(rInfo
.Which() == RES_FINDNEARESTNODE
)
829 if(GetFormatAttr( RES_PAGEDESC
).GetPageDesc())
831 const SwSectionNode
* pNd
= GetSectionNode();
833 static_cast<SwFindNearestNode
&>(rInfo
).CheckNode(*pNd
);
837 return sw::BroadcastingModify::GetInfo(rInfo
);
840 static bool lcl_SectionCmpPos( const SwSection
*pFirst
, const SwSection
*pSecond
)
842 const SwSectionFormat
* pFSectFormat
= pFirst
->GetFormat();
843 const SwSectionFormat
* pSSectFormat
= pSecond
->GetFormat();
844 OSL_ENSURE( pFSectFormat
&& pSSectFormat
&&
845 pFSectFormat
->GetContent(false).GetContentIdx() &&
846 pSSectFormat
->GetContent(false).GetContentIdx(),
847 "Invalid sections" );
848 return pFSectFormat
->GetContent(false).GetContentIdx()->GetIndex() <
849 pSSectFormat
->GetContent(false).GetContentIdx()->GetIndex();
852 // get all Sections that have been derived from this one
853 void SwSectionFormat::GetChildSections( SwSections
& rArr
,
855 bool bAllSections
) const
859 if( !HasWriterListeners() )
862 SwIterator
<SwSectionFormat
,SwSectionFormat
> aIter(*this);
863 const SwNodeIndex
* pIdx
;
864 for( SwSectionFormat
* pLast
= aIter
.First(); pLast
; pLast
= aIter
.Next() )
866 ( nullptr != ( pIdx
= pLast
->GetContent(false).
867 GetContentIdx()) && &pIdx
->GetNodes() == &GetDoc()->GetNodes() ))
869 SwSection
* pDummy
= pLast
->GetSection();
870 rArr
.push_back( pDummy
);
873 // Do we need any sorting?
874 if( 1 < rArr
.size() )
877 case SectionSort::Pos
:
878 std::sort( rArr
.begin(), rArr
.end(), lcl_SectionCmpPos
);
880 case SectionSort::Not
: break;
884 // See whether the Section is within the Nodes or the UndoNodes array
885 bool SwSectionFormat::IsInNodesArr() const
887 const SwNodeIndex
* pIdx
= GetContent(false).GetContentIdx();
888 return pIdx
&& &pIdx
->GetNodes() == &GetDoc()->GetNodes();
891 // Parent was changed
892 void SwSectionFormat::UpdateParent()
894 if(!HasWriterListeners())
897 const SwSection
* pSection
= GetSection();
898 const SvxProtectItem
* pProtect
= &GetProtect();
899 // edit in readonly sections
900 const SwFormatEditInReadonly
* pEditInReadonly
= &GetEditInReadonly();
901 bool bIsHidden
= pSection
->IsHidden();
902 if(GetRegisteredIn())
904 const SwSection
* pPS
= GetParentSection();
905 pProtect
= &pPS
->GetFormat()->GetProtect();
906 pEditInReadonly
= &pPS
->GetFormat()->GetEditInReadonly();
907 bIsHidden
= pPS
->IsHiddenFlag();
909 if(!pProtect
->IsContentProtected() != !pSection
->IsProtectFlag())
910 CallSwClientNotify(sw::LegacyModifyHint(pProtect
, pProtect
));
912 // edit in readonly sections
913 if(!pEditInReadonly
->GetValue() != !pSection
->IsEditInReadonlyFlag())
914 CallSwClientNotify(sw::LegacyModifyHint(pEditInReadonly
, pEditInReadonly
));
916 if(bIsHidden
== pSection
->IsHiddenFlag())
918 const sw::SectionHidden
aHint(bIsHidden
);
919 CallSwClientNotify(aHint
);
923 SwSectionNode
* SwSectionFormat::GetSectionNode()
925 const SwNodeIndex
* pIdx
= GetContent(false).GetContentIdx();
926 if( pIdx
&& ( &pIdx
->GetNodes() == &GetDoc()->GetNodes() ))
927 return pIdx
->GetNode().GetSectionNode();
931 // Is this Section valid for the GlobalDocument?
932 const SwSection
* SwSectionFormat::GetGlobalDocSection() const
934 const SwSectionNode
* pNd
= GetSectionNode();
936 ( SectionType::FileLink
== pNd
->GetSection().GetType() ||
937 SectionType::ToxContent
== pNd
->GetSection().GetType() ) &&
938 pNd
->GetIndex() > pNd
->GetNodes().GetEndOfExtras().GetIndex() &&
939 !pNd
->StartOfSectionNode()->IsSectionNode() &&
940 !pNd
->StartOfSectionNode()->FindSectionNode() )
941 return &pNd
->GetSection();
946 ::sfx2::IXmlIdRegistry
& SwSectionFormat::GetRegistry()
948 return GetDoc()->GetXmlIdRegistry();
951 bool SwSectionFormat::IsInClipboard() const
953 return GetDoc()->IsClipBoard();
956 bool SwSectionFormat::IsInUndo() const
958 return !IsInNodesArr();
961 bool SwSectionFormat::IsInContent() const
963 SwNodeIndex
const*const pIdx
= GetContent(false).GetContentIdx();
964 OSL_ENSURE(pIdx
, "SwSectionFormat::IsInContent: no index?");
965 return pIdx
== nullptr || !GetDoc()->IsInHeaderFooter(pIdx
->GetNode());
968 // n.b.: if the section format represents an index, then there is both a
969 // SwXDocumentIndex and a SwXTextSection instance for this single core object.
970 // these two can both implement XMetadatable and forward to the same core
971 // section format. but here only one UNO object can be returned,
972 // so always return the text section.
973 uno::Reference
< rdf::XMetadatable
>
974 SwSectionFormat::MakeUnoObject()
976 uno::Reference
<rdf::XMetadatable
> xMeta
;
977 SwSection
*const pSection( GetSection() );
980 xMeta
= SwXTextSection::CreateXTextSection(this,
981 SectionType::ToxHeader
== pSection
->GetType());
986 bool SwSectionFormat::supportsFullDrawingLayerFillAttributeSet() const
991 void SwSectionFormat::dumpAsXml(xmlTextWriterPtr pWriter
) const
993 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwSectionFormat"));
994 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
995 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("name"), BAD_CAST(GetName().toUtf8().getStr()));
996 GetAttrSet().dumpAsXml(pWriter
);
997 (void)xmlTextWriterEndElement(pWriter
);
1000 void SwSectionFormats::dumpAsXml(xmlTextWriterPtr pWriter
) const
1002 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwSectionFormats"));
1003 for (size_t i
= 0; i
< size(); ++i
)
1004 GetFormat(i
)->dumpAsXml(pWriter
);
1005 (void)xmlTextWriterEndElement(pWriter
);
1008 // Method to break section links inside a linked section
1009 static void lcl_BreakSectionLinksInSect( const SwSectionNode
& rSectNd
)
1011 if ( !rSectNd
.GetSection().IsConnected() )
1013 OSL_FAIL( "method <lcl_RemoveSectionLinksInSect(..)> - no Link at Section of SectionNode" );
1016 const ::sfx2::SvBaseLink
* pOwnLink( &(rSectNd
.GetSection().GetBaseLink() ) );
1017 const ::sfx2::SvBaseLinks
& rLnks
= rSectNd
.GetDoc().getIDocumentLinksAdministration().GetLinkManager().GetLinks();
1018 for ( auto n
= rLnks
.size(); n
> 0; )
1020 SwIntrnlSectRefLink
* pSectLnk
= dynamic_cast<SwIntrnlSectRefLink
*>(&(*rLnks
[ --n
]));
1021 if ( pSectLnk
&& pSectLnk
!= pOwnLink
&&
1022 pSectLnk
->IsInRange( rSectNd
.GetIndex(), rSectNd
.EndOfSectionIndex() ) )
1024 // break the link of the corresponding section.
1025 // the link is also removed from the link manager
1026 SwSectionNode
* pSectNode
= pSectLnk
->GetSectNode();
1028 pSectNode
->GetSection().BreakLink();
1030 // for robustness, because link is removed from the link manager
1031 if ( n
> rLnks
.size() )
1039 static void lcl_UpdateLinksInSect( const SwBaseLink
& rUpdLnk
, SwSectionNode
& rSectNd
)
1041 SwDoc
& rDoc
= rSectNd
.GetDoc();
1042 SwDocShell
* pDShell
= rDoc
.GetDocShell();
1043 if( !pDShell
|| !pDShell
->GetMedium() )
1046 const OUString
sName( pDShell
->GetMedium()->GetName() );
1047 const OUString
sMimeType( SotExchange::GetFormatMimeType( SotClipboardFormatId::SIMPLE_FILE
));
1049 aValue
<<= sName
; // Arbitrary name
1051 const ::sfx2::SvBaseLinks
& rLnks
= rDoc
.getIDocumentLinksAdministration().GetLinkManager().GetLinks();
1052 for( auto n
= rLnks
.size(); n
; )
1054 ::sfx2::SvBaseLink
* pLnk
= &(*rLnks
[ --n
]);
1055 if( pLnk
== &rUpdLnk
)
1057 if( sfx2::SvBaseLinkObjectType::ClientFile
!= pLnk
->GetObjType() )
1059 SwBaseLink
* pBLink
= dynamic_cast<SwBaseLink
*>( pLnk
);
1060 if( pBLink
&& pBLink
->IsInRange( rSectNd
.GetIndex(),
1061 rSectNd
.EndOfSectionIndex() ) )
1063 // It's in the Section, so update. But only if it's not in the same File!
1065 sfx2::LinkManager::GetDisplayNames( pBLink
, nullptr, &sFName
);
1066 if( sFName
!= sName
)
1068 pBLink
->DataChanged( sMimeType
, aValue
);
1070 // If needed find the Link pointer to avoid skipping one or calling one twice
1071 if( n
>= rLnks
.size() && 0 != ( n
= rLnks
.size() ))
1074 if( n
&& pLnk
!= &(*rLnks
[ n
]) )
1076 // Find - it can only precede it!
1078 if( pLnk
== &(*rLnks
[ --n
] ) )
1086 ::sfx2::SvBaseLink::UpdateResult
SwIntrnlSectRefLink::DataChanged(
1087 const OUString
& rMimeType
, const uno::Any
& rValue
)
1089 SwSectionNode
* pSectNd
= m_rSectFormat
.GetSectionNode();
1090 SwDoc
* pDoc
= m_rSectFormat
.GetDoc();
1092 SotClipboardFormatId nDataFormat
= SotExchange::GetFormatIdFromMimeType( rMimeType
);
1094 if( !pSectNd
|| !pDoc
|| pDoc
->IsInDtor() || ChkNoDataFlag() ||
1095 sfx2::LinkManager::RegisterStatusInfoId() == nDataFormat
)
1097 // Should we be in the Undo already?
1101 // #i38810# - Due to possible existing signatures, the
1102 // document has to be modified after updating a link.
1103 pDoc
->getIDocumentState().SetModified();
1104 // set additional flag that links have been updated, in order to check this
1106 pDoc
->getIDocumentLinksAdministration().SetLinksUpdated( true );
1108 // Always switch off Undo
1109 bool const bWasUndo
= pDoc
->GetIDocumentUndoRedo().DoesUndo();
1110 pDoc
->GetIDocumentUndoRedo().DoUndo(false);
1111 bool bWasVisibleLinks
= pDoc
->getIDocumentLinksAdministration().IsVisibleLinks();
1112 pDoc
->getIDocumentLinksAdministration().SetVisibleLinks( false );
1115 SwViewShell
* pVSh
= pDoc
->getIDocumentLayoutAccess().GetCurrentViewShell();
1116 SwEditShell
* pESh
= pDoc
->GetEditShell();
1117 pDoc
->getIDocumentFieldsAccess().LockExpFields();
1119 // Insert an empty TextNode at the Section's start
1120 SwNodeIndex
aIdx( *pSectNd
, +1 );
1121 SwNodeIndex
aEndIdx( *pSectNd
->EndOfSectionNode() );
1122 pDoc
->GetNodes().MakeTextNode( aIdx
.GetNode(),
1123 pDoc
->getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT
) );
1126 pESh
->StartAllAction();
1128 pVSh
->StartAction();
1130 SwPosition
aPos( aIdx
, SwNodeOffset(-1) );
1131 SwDoc::CorrAbs( aIdx
, aEndIdx
, aPos
, true );
1133 pPam
= new SwPaM( aPos
);
1135 // Delete everything succeeding it
1137 DelFlyInRange( aIdx
.GetNode(), aEndIdx
.GetNode() );
1138 DelBookmarks(aIdx
.GetNode(), aEndIdx
.GetNode());
1141 pDoc
->GetNodes().Delete( aIdx
, aEndIdx
.GetIndex() - aIdx
.GetIndex() );
1144 SwSection
& rSection
= pSectNd
->GetSection();
1145 rSection
.SetConnectFlag(false);
1147 Reader
* pRead
= nullptr;
1148 switch( nDataFormat
)
1150 case SotClipboardFormatId::STRING
:
1154 case SotClipboardFormatId::RICHTEXT
:
1155 case SotClipboardFormatId::RTF
:
1156 pRead
= SwReaderWriter::GetRtfReader();
1159 case SotClipboardFormatId::SIMPLE_FILE
:
1160 if ( rValue
.hasValue() )
1163 if ( !(rValue
>>= sFileName
) )
1167 sfx2::LinkManager::GetDisplayNames( this, nullptr, &sFileName
,
1168 &sRange
, &sFilter
);
1170 RedlineFlags eOldRedlineFlags
= RedlineFlags::NONE
;
1171 SfxObjectShellRef xDocSh
;
1172 SfxObjectShellLock xLockRef
;
1174 if( sFileName
.isEmpty() )
1176 xDocSh
= pDoc
->GetDocShell();
1181 nRet
= SwFindDocShell( xDocSh
, xLockRef
, sFileName
,
1182 rSection
.GetLinkFilePassword(),
1183 sFilter
, 0, pDoc
->GetDocShell() );
1186 SwDoc
* pSrcDoc
= static_cast<SwDocShell
*>( xDocSh
.get() )->GetDoc();
1187 eOldRedlineFlags
= pSrcDoc
->getIDocumentRedlineAccess().GetRedlineFlags();
1188 pSrcDoc
->getIDocumentRedlineAccess().SetRedlineFlags( RedlineFlags::ShowInsert
);
1194 rSection
.SetConnectFlag();
1196 SwNodeIndex
aSave( pPam
->GetPoint()->GetNode(), -1 );
1197 std::optional
<SwNodeRange
> oCpyRg
;
1199 if( xDocSh
->GetMedium() &&
1200 rSection
.GetLinkFilePassword().isEmpty() )
1202 if( const SfxStringItem
* pItem
= xDocSh
->GetMedium()->GetItemSet()->
1203 GetItemIfSet( SID_PASSWORD
, false ) )
1204 rSection
.SetLinkFilePassword( pItem
->GetValue() );
1207 SwDoc
* pSrcDoc
= static_cast<SwDocShell
*>( xDocSh
.get() )->GetDoc();
1209 if( !sRange
.isEmpty() )
1212 bool bRecursion
= false;
1213 if( pSrcDoc
== pDoc
)
1215 tools::SvRef
<SwServerObject
> refObj( static_cast<SwServerObject
*>(
1216 pDoc
->getIDocumentLinksAdministration().CreateLinkSource( sRange
)));
1219 bRecursion
= refObj
->IsLinkInServer( this ) ||
1224 SwNode
& rInsPos
= pPam
->GetPoint()->GetNode();
1226 SwPaM
* pCpyPam
= nullptr;
1228 pSrcDoc
->GetDocumentLinksAdministrationManager().SelectServerObj( sRange
, pCpyPam
, oCpyRg
)
1231 if( pSrcDoc
!= pDoc
||
1232 pCpyPam
->Start()->GetNode() > rInsPos
||
1233 rInsPos
>= pCpyPam
->End()->GetNode() )
1235 pSrcDoc
->getIDocumentContentOperations().CopyRange(*pCpyPam
, *pPam
->GetPoint(), SwCopyFlags::CheckPosInFly
);
1239 if( oCpyRg
&& pSrcDoc
== pDoc
&&
1240 oCpyRg
->aStart
< rInsPos
&& rInsPos
< oCpyRg
->aEnd
.GetNode() )
1245 else if( pSrcDoc
!= pDoc
)
1246 oCpyRg
.emplace( pSrcDoc
->GetNodes().GetEndOfExtras(), SwNodeOffset(2),
1247 pSrcDoc
->GetNodes().GetEndOfContent() );
1250 // Update links of extern linked document or extern linked
1251 // document section, if section is protected.
1252 if ( pSrcDoc
!= pDoc
&&
1253 rSection
.IsProtectFlag() )
1255 pSrcDoc
->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks( false, false, nullptr );
1260 SwNode
& rInsPos
= pPam
->GetPoint()->GetNode();
1261 bool bCreateFrame
= rInsPos
<= pDoc
->GetNodes().GetEndOfExtras() ||
1262 rInsPos
.FindTableNode();
1264 SwTableNumFormatMerge
aTNFM( *pSrcDoc
, *pDoc
);
1266 pSrcDoc
->GetDocumentContentOperationsManager().CopyWithFlyInFly(*oCpyRg
, rInsPos
, nullptr, bCreateFrame
);
1270 ::MakeFrames( pDoc
, aSave
.GetNode(), rInsPos
);
1272 // Delete last Node, only if it was copied successfully
1273 // (the Section contains more than one Node)
1274 if( SwNodeOffset(2) < pSectNd
->EndOfSectionIndex() - pSectNd
->GetIndex() )
1277 pPam
->Move( fnMoveBackward
, GoInNode
);
1278 pPam
->SetMark(); // Rewire both SwPositions
1280 pDoc
->CorrAbs( aSave
.GetNode(), *pPam
->GetPoint(), 0, true );
1281 pDoc
->GetNodes().Delete( aSave
);
1286 lcl_BreakSectionLinksInSect( *pSectNd
);
1288 // Update all Links in this Section
1289 lcl_UpdateLinksInSect( *this, *pSectNd
);
1295 else if( static_cast<SwDocShell
*>( xDocSh
.get() )->GetDoc() )
1296 static_cast<SwDocShell
*>( xDocSh
.get() )->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags(
1304 // Only create DDE if Shell is available!
1305 uno::Sequence
< sal_Int8
> aSeq
;
1306 if( pRead
&& rValue
.hasValue() && ( rValue
>>= aSeq
) )
1311 SwPaM
* pCursor
= pESh
->GetCursor();
1312 *pCursor
->GetPoint() = *pPam
->GetPoint();
1317 SvMemoryStream
aStrm( const_cast<sal_Int8
*>(aSeq
.getConstArray()), aSeq
.getLength(),
1321 // TODO/MBA: it's impossible to set a BaseURL here!
1322 SwReader
aTmpReader( aStrm
, OUString(), pDoc
->GetDocShell()->GetMedium()->GetBaseURL(), *pPam
);
1324 if( ! aTmpReader
.Read( *pRead
).IsError() )
1326 rSection
.SetConnectFlag();
1331 pESh
->Pop(SwCursorShell::PopMode::DeleteCurrent
);
1332 pPam
= nullptr; // pam was deleted earlier
1336 // remove all undo actions and turn undo on again
1337 pDoc
->GetIDocumentUndoRedo().DelAllUndoObj();
1338 pDoc
->GetIDocumentUndoRedo().DoUndo(bWasUndo
);
1339 pDoc
->getIDocumentLinksAdministration().SetVisibleLinks( bWasVisibleLinks
);
1341 pDoc
->getIDocumentFieldsAccess().UnlockExpFields();
1342 if( !pDoc
->getIDocumentFieldsAccess().IsExpFieldsLocked() )
1343 pDoc
->getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
1346 pESh
->EndAllAction();
1349 delete pPam
; // Was created at the start
1354 void SwIntrnlSectRefLink::Closed()
1356 SwDoc
* pDoc
= m_rSectFormat
.GetDoc();
1357 if( pDoc
&& !pDoc
->IsInDtor() )
1359 // Advise says goodbye: mark the Section as not protected
1360 // and change the Flag
1361 const SwSectionFormats
& rFormats
= pDoc
->GetSections();
1362 for( auto n
= rFormats
.size(); n
; )
1363 if (rFormats
[--n
] == &m_rSectFormat
)
1365 SwViewShell
* pSh
= pDoc
->getIDocumentLayoutAccess().GetCurrentViewShell();
1366 SwEditShell
* pESh
= pDoc
->GetEditShell();
1369 pESh
->StartAllAction();
1373 SwSectionData
aSectionData(*m_rSectFormat
.GetSection());
1374 aSectionData
.SetType( SectionType::Content
);
1375 aSectionData
.SetLinkFileName( OUString() );
1376 aSectionData
.SetProtectFlag( false );
1377 // edit in readonly sections
1378 aSectionData
.SetEditInReadonlyFlag( false );
1380 aSectionData
.SetConnectFlag( false );
1382 pDoc
->UpdateSection( n
, aSectionData
);
1384 // Make all Links within the Section visible again
1385 SwSectionNode
* pSectNd
= m_rSectFormat
.GetSectionNode();
1387 SwSection::MakeChildLinksVisible( *pSectNd
);
1390 pESh
->EndAllAction();
1396 SvBaseLink::Closed();
1399 void SwSection::CreateLink( LinkCreateType eCreateType
)
1401 SwSectionFormat
* pFormat
= GetFormat();
1402 OSL_ENSURE(pFormat
, "SwSection::CreateLink: no format?");
1403 if (!pFormat
|| (SectionType::Content
== m_Data
.GetType()))
1406 SfxLinkUpdateMode nUpdateType
= SfxLinkUpdateMode::ALWAYS
;
1408 if (!m_RefLink
.is())
1411 m_RefLink
= new SwIntrnlSectRefLink( *pFormat
, nUpdateType
);
1415 pFormat
->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink
.get() );
1418 SwIntrnlSectRefLink
*const pLnk
=
1419 static_cast<SwIntrnlSectRefLink
*>( m_RefLink
.get() );
1421 const OUString
sCmd(m_Data
.GetLinkFileName());
1422 pLnk
->SetUpdateMode( nUpdateType
);
1423 pLnk
->SetVisible( pFormat
->GetDoc()->getIDocumentLinksAdministration().IsVisibleLinks() );
1425 switch (m_Data
.GetType())
1427 case SectionType::DdeLink
:
1428 pLnk
->SetLinkSourceName( sCmd
);
1429 pFormat
->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().InsertDDELink( pLnk
);
1431 case SectionType::FileLink
:
1433 pLnk
->SetContentType( SotClipboardFormatId::SIMPLE_FILE
);
1434 sal_Int32 nIndex
= 0;
1435 const OUString
sFile(sCmd
.getToken( 0, sfx2::cTokenSeparator
, nIndex
));
1436 const OUString
sFltr(sCmd
.getToken( 0, sfx2::cTokenSeparator
, nIndex
));
1437 const OUString
sRange(sCmd
.getToken( 0, sfx2::cTokenSeparator
, nIndex
));
1438 pFormat
->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().InsertFileLink( *pLnk
,
1439 static_cast<sfx2::SvBaseLinkObjectType
>(m_Data
.GetType()),
1441 ( !sFltr
.isEmpty() ? &sFltr
: nullptr ),
1442 ( !sRange
.isEmpty() ? &sRange
: nullptr ) );
1446 OSL_ENSURE( false, "What kind of Link is this?" );
1449 switch( eCreateType
)
1451 case LinkCreateType::Connect
: // Connect Link right away
1455 case LinkCreateType::Update
: // Connect Link and update
1458 case LinkCreateType::NONE
: break;
1462 void SwSection::BreakLink()
1464 const SectionType
eCurrentType( GetType() );
1465 if ( eCurrentType
== SectionType::Content
||
1466 eCurrentType
== SectionType::ToxHeader
||
1467 eCurrentType
== SectionType::ToxContent
)
1473 // Release link, if it exists
1476 SwSectionFormat
*const pFormat( GetFormat() );
1477 OSL_ENSURE(pFormat
, "SwSection::BreakLink: no format?");
1480 pFormat
->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink
.get() );
1485 SetType( SectionType::Content
);
1486 // reset linked file data
1487 SetLinkFileName( OUString() );
1488 SetLinkFilePassword( OUString() );
1491 void SwSection::dumpAsXml(xmlTextWriterPtr pWriter
) const
1493 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwSection"));
1494 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
1495 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("registered-in"), "%p",
1497 m_Data
.dumpAsXml(pWriter
);
1498 (void)xmlTextWriterEndElement(pWriter
);
1501 const SwNode
* SwIntrnlSectRefLink::GetAnchor() const { return m_rSectFormat
.GetSectionNode(); }
1503 bool SwIntrnlSectRefLink::IsInRange( SwNodeOffset nSttNd
, SwNodeOffset nEndNd
) const
1505 SwStartNode
* pSttNd
= m_rSectFormat
.GetSectionNode();
1507 nSttNd
< pSttNd
->GetIndex() &&
1508 pSttNd
->EndOfSectionIndex() < nEndNd
;
1511 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */