Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / unocore / unosect.cxx
blob69ec954d063aca0efccdc8f4c72ffde2748fc2d3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
21 #include <unosection.hxx>
23 #include <com/sun/star/beans/PropertyAttribute.hpp>
24 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
25 #include <com/sun/star/text/SectionFileLink.hpp>
27 #include <comphelper/interfacecontainer4.hxx>
28 #include <cppuhelper/exc_hlp.hxx>
29 #include <cppuhelper/supportsservice.hxx>
31 #include <cmdid.h>
32 #include <hintids.hxx>
33 #include <svl/urihelper.hxx>
34 #include <svl/listener.hxx>
35 #include <editeng/brushitem.hxx>
36 #include <editeng/xmlcnitm.hxx>
37 #include <sfx2/linkmgr.hxx>
38 #include <sfx2/lnkbase.hxx>
39 #include <osl/diagnose.h>
40 #include <vcl/svapp.hxx>
41 #include <fmtclds.hxx>
42 #include <unotextrange.hxx>
43 #include <TextCursorHelper.hxx>
44 #include <unoport.hxx>
45 #include <redline.hxx>
46 #include <unomap.hxx>
47 #include <section.hxx>
48 #include <doc.hxx>
49 #include <IDocumentRedlineAccess.hxx>
50 #include <IDocumentUndoRedo.hxx>
51 #include <docsh.hxx>
52 #include <sfx2/docfile.hxx>
53 #include <docary.hxx>
54 #include <swundo.hxx>
55 #include <tox.hxx>
56 #include <unoidx.hxx>
57 #include <doctxm.hxx>
58 #include <fmtftntx.hxx>
59 #include <fmtclbl.hxx>
60 #include <editeng/frmdiritem.hxx>
61 #include <fmtcntnt.hxx>
62 #include <editeng/lrspitem.hxx>
63 #include <comphelper/servicehelper.hxx>
64 #include <comphelper/string.hxx>
65 #include <o3tl/string_view.hxx>
67 using namespace ::com::sun::star;
69 namespace {
71 struct SwTextSectionProperties_Impl
73 uno::Sequence<sal_Int8> m_Password;
74 OUString m_sCondition;
75 OUString m_sLinkFileName;
76 OUString m_sSectionFilter;
77 OUString m_sSectionRegion;
79 std::unique_ptr<SwFormatCol> m_pColItem;
80 std::unique_ptr<SvxBrushItem> m_pBrushItem;
81 std::unique_ptr<SwFormatFootnoteAtTextEnd> m_pFootnoteItem;
82 std::unique_ptr<SwFormatEndAtTextEnd> m_pEndItem;
83 std::unique_ptr<SvXMLAttrContainerItem> m_pXMLAttr;
84 std::unique_ptr<SwFormatNoBalancedColumns> m_pNoBalanceItem;
85 std::unique_ptr<SvxFrameDirectionItem> m_pFrameDirItem;
86 std::unique_ptr<SvxLRSpaceItem> m_pLRSpaceItem;
88 bool m_bDDE;
89 bool m_bHidden;
90 bool m_bCondHidden;
91 bool m_bProtect;
92 bool m_bEditInReadonly;
93 bool m_bUpdateType;
95 SwTextSectionProperties_Impl()
96 : m_bDDE(false)
97 , m_bHidden(false)
98 , m_bCondHidden(false)
99 , m_bProtect(false)
100 , m_bEditInReadonly(false)
101 , m_bUpdateType(true)
109 class SwXTextSection::Impl
110 : public SvtListener
112 public:
113 SwXTextSection & m_rThis;
114 unotools::WeakReference<SwXTextSection> m_wThis;
115 const SfxItemPropertySet & m_rPropSet;
116 std::mutex m_Mutex; // just for OInterfaceContainerHelper4
117 ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
118 const bool m_bIndexHeader;
119 bool m_bIsDescriptor;
120 OUString m_sName;
121 std::unique_ptr<SwTextSectionProperties_Impl> m_pProps;
122 SwSectionFormat* m_pFormat;
124 Impl( SwXTextSection& rThis,
125 SwSectionFormat* const pFormat, const bool bIndexHeader)
126 : m_rThis(rThis)
127 , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_SECTION))
128 , m_bIndexHeader(bIndexHeader)
129 , m_bIsDescriptor(nullptr == pFormat)
130 , m_pProps(pFormat ? nullptr : new SwTextSectionProperties_Impl())
131 , m_pFormat(pFormat)
133 if(m_pFormat)
134 StartListening(m_pFormat->GetNotifier());
137 void Attach(SwSectionFormat* pFormat)
139 EndListeningAll();
140 StartListening(pFormat->GetNotifier());
141 m_pFormat = pFormat;
144 SwSectionFormat* GetSectionFormat() const
145 { return m_pFormat; }
147 SwSectionFormat & GetSectionFormatOrThrow() const {
148 SwSectionFormat *const pFormat( GetSectionFormat() );
149 if (!pFormat) {
150 throw uno::RuntimeException("SwXTextSection: disposed or invalid", nullptr);
152 return *pFormat;
155 /// @throws beans::UnknownPropertyException
156 /// @throws beans::PropertyVetoException,
157 /// @throws lang::IllegalArgumentException
158 /// @throws lang::WrappedTargetException,
159 /// @throws uno::RuntimeException
160 void SetPropertyValues_Impl(
161 const uno::Sequence< OUString >& rPropertyNames,
162 const uno::Sequence< uno::Any >& aValues);
163 /// @throws beans::UnknownPropertyException
164 /// @throws lang::WrappedTargetException,
165 /// @throws uno::RuntimeException
166 uno::Sequence< uno::Any >
167 GetPropertyValues_Impl(
168 const uno::Sequence< OUString >& rPropertyNames);
169 virtual void Notify(const SfxHint& rHint) override;
172 void SwXTextSection::Impl::Notify(const SfxHint& rHint)
174 if(rHint.GetId() == SfxHintId::Dying)
176 m_pFormat = nullptr;
177 uno::Reference<uno::XInterface> const xThis(m_wThis);
178 if (!xThis.is())
179 { // fdo#72695: if UNO object is already dead, don't revive it with event
180 return;
182 lang::EventObject const ev(xThis);
183 std::unique_lock aGuard(m_Mutex);
184 m_EventListeners.disposeAndClear(aGuard, ev);
188 SwSectionFormat * SwXTextSection::GetFormat() const
190 return m_pImpl->GetSectionFormat();
193 rtl::Reference< SwXTextSection >
194 SwXTextSection::CreateXTextSection(
195 SwSectionFormat *const pFormat, const bool bIndexHeader)
197 // re-use existing SwXTextSection
198 // #i105557#: do not iterate over the registered clients: race condition
199 rtl::Reference< SwXTextSection > xSection;
200 if (pFormat)
202 xSection = pFormat->GetXTextSection();
204 if ( !xSection.is() )
206 rtl::Reference<SwXTextSection> pNew = new SwXTextSection(pFormat, bIndexHeader);
207 xSection = pNew;
208 if (pFormat)
210 pFormat->SetXTextSection(xSection);
212 // need a permanent Reference to initialize m_wThis
213 pNew->m_pImpl->m_wThis = xSection.get();
215 return xSection;
218 SwXTextSection::SwXTextSection(
219 SwSectionFormat *const pFormat, const bool bIndexHeader)
220 : m_pImpl( new SwXTextSection::Impl(*this, pFormat, bIndexHeader) )
224 SwXTextSection::~SwXTextSection()
228 uno::Reference< text::XTextSection > SAL_CALL
229 SwXTextSection::getParentSection()
231 SolarMutexGuard aGuard;
233 SwSectionFormat & rSectionFormat( m_pImpl->GetSectionFormatOrThrow() );
235 SwSectionFormat *const pParentFormat = rSectionFormat.GetParent();
236 const uno::Reference< text::XTextSection > xRet =
237 pParentFormat ? CreateXTextSection(pParentFormat) : nullptr;
238 return xRet;
241 uno::Sequence< uno::Reference< text::XTextSection > > SAL_CALL
242 SwXTextSection::getChildSections()
244 SolarMutexGuard aGuard;
246 SwSectionFormat & rSectionFormat( m_pImpl->GetSectionFormatOrThrow() );
248 SwSections aChildren;
249 rSectionFormat.GetChildSections(aChildren, SectionSort::Not, false);
250 uno::Sequence<uno::Reference<text::XTextSection> > aSeq(aChildren.size());
251 uno::Reference< text::XTextSection > * pArray = aSeq.getArray();
252 for (size_t i = 0; i < aChildren.size(); ++i)
254 SwSectionFormat *const pChild = aChildren[i]->GetFormat();
255 pArray[i] = CreateXTextSection(pChild);
257 return aSeq;
260 void SAL_CALL
261 SwXTextSection::attach(const uno::Reference< text::XTextRange > & xTextRange)
263 SolarMutexGuard g;
265 if (!m_pImpl->m_bIsDescriptor)
267 throw uno::RuntimeException();
270 SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
271 OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
273 SwDoc *const pDoc =
274 pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
275 if (!pDoc)
277 throw lang::IllegalArgumentException();
280 SwUnoInternalPaM aPam(*pDoc);
281 // this has to return true now
282 ::sw::XTextRangeToSwPaM(aPam, xTextRange);
283 UnoActionContext aCont(pDoc);
284 pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::INSSECTION, nullptr );
286 if (m_pImpl->m_sName.isEmpty())
288 m_pImpl->m_sName = "TextSection";
290 SectionType eType(SectionType::FileLink);
291 if( m_pImpl->m_pProps->m_bDDE )
292 eType = SectionType::DdeLink;
293 else if( m_pImpl->m_pProps->m_sLinkFileName.isEmpty() && m_pImpl->m_pProps->m_sSectionRegion.isEmpty() )
294 eType = SectionType::Content;
295 // index header section?
296 if (m_pImpl->m_bIndexHeader)
298 // caller wants an index header section, but will only
299 // give him one if a) we are inside an index, and b) said
300 // index doesn't yet have a header section.
301 const SwTOXBase* pBase = SwDoc::GetCurTOX(*aPam.Start());
303 // are we inside an index?
304 if (pBase)
306 // get all child sections
307 SwSections aSectionsArr;
308 static_cast<const SwTOXBaseSection*>(pBase)->GetFormat()->
309 GetChildSections(aSectionsArr);
311 // and search for current header section
312 const size_t nCount = aSectionsArr.size();
313 bool bHeaderPresent = false;
314 for(size_t i = 0; i < nCount; ++i)
316 if (aSectionsArr[i]->GetType() == SectionType::ToxHeader)
317 bHeaderPresent = true;
319 if (! bHeaderPresent)
321 eType = SectionType::ToxHeader;
326 SwSectionData aSect(eType, pDoc->GetUniqueSectionName(&m_pImpl->m_sName));
327 aSect.SetCondition(m_pImpl->m_pProps->m_sCondition);
328 aSect.SetLinkFileName(m_pImpl->m_pProps->m_sLinkFileName +
329 OUStringChar(sfx2::cTokenSeparator) +
330 m_pImpl->m_pProps->m_sSectionFilter +
331 OUStringChar(sfx2::cTokenSeparator) +
332 m_pImpl->m_pProps->m_sSectionRegion);
334 aSect.SetHidden(m_pImpl->m_pProps->m_bHidden);
335 aSect.SetProtectFlag(m_pImpl->m_pProps->m_bProtect);
336 aSect.SetEditInReadonlyFlag(m_pImpl->m_pProps->m_bEditInReadonly);
338 SfxItemSetFixed<
339 RES_LR_SPACE, RES_LR_SPACE,
340 RES_BACKGROUND, RES_BACKGROUND,
341 RES_COL, RES_COL,
342 RES_FTN_AT_TXTEND, RES_FRAMEDIR,
343 RES_UNKNOWNATR_CONTAINER,RES_UNKNOWNATR_CONTAINER>
344 aSet(pDoc->GetAttrPool());
345 if (m_pImpl->m_pProps->m_pBrushItem)
347 aSet.Put(*m_pImpl->m_pProps->m_pBrushItem);
349 if (m_pImpl->m_pProps->m_pColItem)
351 aSet.Put(*m_pImpl->m_pProps->m_pColItem);
353 if (m_pImpl->m_pProps->m_pFootnoteItem)
355 aSet.Put(*m_pImpl->m_pProps->m_pFootnoteItem);
357 if (m_pImpl->m_pProps->m_pEndItem)
359 aSet.Put(*m_pImpl->m_pProps->m_pEndItem);
361 if (m_pImpl->m_pProps->m_pXMLAttr)
363 aSet.Put(*m_pImpl->m_pProps->m_pXMLAttr);
365 if (m_pImpl->m_pProps->m_pNoBalanceItem)
367 aSet.Put(*m_pImpl->m_pProps->m_pNoBalanceItem);
369 if (m_pImpl->m_pProps->m_pFrameDirItem)
371 aSet.Put(*m_pImpl->m_pProps->m_pFrameDirItem);
373 if (m_pImpl->m_pProps->m_pLRSpaceItem)
375 aSet.Put(*m_pImpl->m_pProps->m_pLRSpaceItem);
377 // section password
378 if (m_pImpl->m_pProps->m_Password.hasElements())
380 aSect.SetPassword(m_pImpl->m_pProps->m_Password);
383 SwSection *const pRet =
384 pDoc->InsertSwSection( aPam, aSect, nullptr, aSet.Count() ? &aSet : nullptr );
385 if (!pRet) // fdo#42450 text range could partially overlap existing section
387 // shouldn't have created an undo object yet
388 pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSSECTION, nullptr );
389 throw lang::IllegalArgumentException(
390 "SwXTextSection::attach(): invalid TextRange",
391 static_cast< ::cppu::OWeakObject*>(this), 0);
393 m_pImpl->Attach(pRet->GetFormat());
394 pRet->GetFormat()->SetXObject(static_cast< ::cppu::OWeakObject*>(this));
396 // XML import must hide sections depending on their old
397 // condition status
398 if (!m_pImpl->m_pProps->m_sCondition.isEmpty())
400 pRet->SetCondHidden(m_pImpl->m_pProps->m_bCondHidden);
403 // set update type if DDE link (and connect, if necessary)
404 if (m_pImpl->m_pProps->m_bDDE)
406 if (! pRet->IsConnected())
408 pRet->CreateLink(LinkCreateType::Connect);
410 pRet->SetUpdateType( m_pImpl->m_pProps->m_bUpdateType ?
411 SfxLinkUpdateMode::ALWAYS : SfxLinkUpdateMode::ONCALL );
414 // end the Undo bracketing here
415 pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSSECTION, nullptr );
416 m_pImpl->m_pProps.reset();
417 m_pImpl->m_bIsDescriptor = false;
420 uno::Reference< text::XTextRange > SAL_CALL
421 SwXTextSection::getAnchor()
423 SolarMutexGuard aGuard;
425 rtl::Reference<SwXTextRange> xRet;
426 SwSectionFormat *const pSectFormat = m_pImpl->GetSectionFormat();
427 if(pSectFormat)
429 const SwNodeIndex* pIdx;
430 if( nullptr != ( pSectFormat->GetSection() ) &&
431 nullptr != ( pIdx = pSectFormat->GetContent().GetContentIdx() ) &&
432 pIdx->GetNode().GetNodes().IsDocNodes() )
434 bool isMoveIntoTable(false);
435 SwPaM aPaM(*pIdx);
436 aPaM.Move( fnMoveForward, GoInContent );
437 assert(pIdx->GetNode().IsSectionNode());
438 if (aPaM.GetPoint()->GetNode().FindTableNode() != pIdx->GetNode().FindTableNode()
439 || aPaM.GetPoint()->GetNode().FindSectionNode() != &pIdx->GetNode())
441 isMoveIntoTable = true;
444 const SwEndNode* pEndNode = pIdx->GetNode().EndOfSectionNode();
445 SwPaM aEnd(*pEndNode);
446 aEnd.Move( fnMoveBackward, GoInContent );
447 if (aEnd.GetPoint()->GetNode().FindTableNode() != pIdx->GetNode().FindTableNode()
448 || aEnd.GetPoint()->GetNode().FindSectionNode() != &pIdx->GetNode())
450 isMoveIntoTable = true;
452 if (isMoveIntoTable)
454 uno::Reference<text::XText> const xParentText(
455 ::sw::CreateParentXText(*pSectFormat->GetDoc(), SwPosition(*pIdx)));
456 xRet = new SwXTextRange(*pSectFormat);
458 else // for compatibility, keep the old way in this case
460 xRet = SwXTextRange::CreateXTextRange(*pSectFormat->GetDoc(),
461 *aPaM.Start(), aEnd.Start());
465 return xRet;
468 void SAL_CALL SwXTextSection::dispose()
470 SolarMutexGuard aGuard;
472 SwSectionFormat *const pSectFormat = m_pImpl->GetSectionFormat();
473 if (pSectFormat)
475 pSectFormat->GetDoc()->DelSectionFormat( pSectFormat );
479 void SAL_CALL SwXTextSection::addEventListener(
480 const uno::Reference< lang::XEventListener > & xListener)
482 // no need to lock here as m_pImpl is const and container threadsafe
483 std::unique_lock aGuard(m_pImpl->m_Mutex);
484 m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
487 void SAL_CALL SwXTextSection::removeEventListener(
488 const uno::Reference< lang::XEventListener > & xListener)
490 // no need to lock here as m_pImpl is const and container threadsafe
491 std::unique_lock aGuard(m_pImpl->m_Mutex);
492 m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
495 uno::Reference< beans::XPropertySetInfo > SAL_CALL
496 SwXTextSection::getPropertySetInfo()
498 SolarMutexGuard g;
499 return m_pImpl->m_rPropSet.getPropertySetInfo();
502 static void
503 lcl_UpdateLinkType(SwSection & rSection, bool const bLinkUpdateAlways)
505 if (rSection.GetType() == SectionType::DdeLink)
507 // set update type; needs an established link
508 if (!rSection.IsConnected())
510 rSection.CreateLink(LinkCreateType::Connect);
512 rSection.SetUpdateType( bLinkUpdateAlways
513 ? SfxLinkUpdateMode::ALWAYS : SfxLinkUpdateMode::ONCALL );
517 static void
518 lcl_UpdateSection(SwSectionFormat *const pFormat,
519 std::unique_ptr<SwSectionData> const& pSectionData,
520 std::optional<SfxItemSet> const& oItemSet,
521 bool const bLinkModeChanged, bool const bLinkUpdateAlways = true)
523 if (!pFormat)
524 return;
526 SwSection & rSection = *pFormat->GetSection();
527 SwDoc *const pDoc = pFormat->GetDoc();
528 SwSectionFormats const& rFormats = pDoc->GetSections();
529 UnoActionContext aContext(pDoc);
530 for (size_t i = 0; i < rFormats.size(); ++i)
532 if (rFormats[i]->GetSection()->GetSectionName()
533 == rSection.GetSectionName())
535 pDoc->UpdateSection(i, *pSectionData, oItemSet ? &*oItemSet : nullptr,
536 pDoc->IsInReading());
538 // temporarily remove actions to allow cursor update
539 // TODO: why? no table cursor here!
540 UnoActionRemoveContext aRemoveContext( pDoc );
543 if (bLinkModeChanged)
545 lcl_UpdateLinkType(rSection, bLinkUpdateAlways);
547 // section found and processed: break from loop
548 break;
553 void SwXTextSection::Impl::SetPropertyValues_Impl(
554 const uno::Sequence< OUString >& rPropertyNames,
555 const uno::Sequence< uno::Any >& rValues)
557 if(rPropertyNames.getLength() != rValues.getLength())
559 throw lang::IllegalArgumentException();
561 SwSectionFormat *const pFormat = GetSectionFormat();
562 if (!pFormat && !m_bIsDescriptor)
564 throw uno::RuntimeException();
567 std::unique_ptr<SwSectionData> const pSectionData(
568 pFormat ? new SwSectionData(*pFormat->GetSection()) : nullptr);
570 OUString const*const pPropertyNames = rPropertyNames.getConstArray();
571 uno::Any const*const pValues = rValues.getConstArray();
572 std::optional<SfxItemSet> oItemSet;
573 bool bLinkModeChanged = false;
574 bool bLinkMode = false;
576 for (sal_Int32 nProperty = 0; nProperty < rPropertyNames.getLength();
577 nProperty++)
579 SfxItemPropertyMapEntry const*const pEntry =
580 m_rPropSet.getPropertyMap().getByName(pPropertyNames[nProperty]);
581 if (!pEntry)
583 throw beans::UnknownPropertyException(
584 "Unknown property: " + pPropertyNames[nProperty],
585 static_cast<cppu::OWeakObject *>(& m_rThis));
587 if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
589 throw beans::PropertyVetoException(
590 "Property is read-only: " + pPropertyNames[nProperty],
591 static_cast<cppu::OWeakObject *>(& m_rThis));
593 switch (pEntry->nWID)
595 case WID_SECT_CONDITION:
597 OUString uTmp;
598 pValues[nProperty] >>= uTmp;
599 if (m_bIsDescriptor)
601 m_pProps->m_sCondition = uTmp;
603 else
605 pSectionData->SetCondition(uTmp);
608 break;
609 case WID_SECT_DDE_TYPE:
610 case WID_SECT_DDE_FILE:
611 case WID_SECT_DDE_ELEMENT:
613 OUString sTmp;
614 pValues[nProperty] >>= sTmp;
615 if (m_bIsDescriptor)
617 if (!m_pProps->m_bDDE)
619 m_pProps->m_sLinkFileName =
620 OUStringChar(sfx2::cTokenSeparator) + OUStringChar(sfx2::cTokenSeparator);
621 m_pProps->m_bDDE = true;
623 m_pProps->m_sLinkFileName = comphelper::string::setToken(
624 m_pProps->m_sLinkFileName,
625 pEntry->nWID - WID_SECT_DDE_TYPE, sfx2::cTokenSeparator, sTmp);
627 else
629 OUString sLinkFileName(pSectionData->GetLinkFileName());
630 if (pSectionData->GetType() != SectionType::DdeLink)
632 sLinkFileName = OUStringChar(sfx2::cTokenSeparator) + OUStringChar(sfx2::cTokenSeparator);
633 pSectionData->SetType(SectionType::DdeLink);
635 sLinkFileName = comphelper::string::setToken(sLinkFileName,
636 pEntry->nWID - WID_SECT_DDE_TYPE,
637 sfx2::cTokenSeparator, sTmp);
638 pSectionData->SetLinkFileName(sLinkFileName);
641 break;
642 case WID_SECT_DDE_AUTOUPDATE:
644 bool bVal(false);
645 if (!(pValues[nProperty] >>= bVal))
647 throw lang::IllegalArgumentException();
649 if (m_bIsDescriptor)
651 m_pProps->m_bUpdateType = bVal;
653 else
655 bLinkModeChanged = true;
656 bLinkMode = bVal;
659 break;
660 case WID_SECT_LINK:
662 text::SectionFileLink aLink;
663 if (!(pValues[nProperty] >>= aLink))
665 throw lang::IllegalArgumentException();
667 if (m_bIsDescriptor)
669 m_pProps->m_bDDE = false;
670 m_pProps->m_sLinkFileName = aLink.FileURL;
671 m_pProps->m_sSectionFilter = aLink.FilterName;
673 else
675 if (pSectionData->GetType() != SectionType::FileLink &&
676 !aLink.FileURL.isEmpty())
678 pSectionData->SetType(SectionType::FileLink);
680 const OUString sTmp(!aLink.FileURL.isEmpty()
681 ? URIHelper::SmartRel2Abs(
682 pFormat->GetDoc()->GetDocShell()->GetMedium()->GetURLObject(),
683 aLink.FileURL, URIHelper::GetMaybeFileHdl())
684 : OUString());
685 const OUString sFileName(
686 sTmp + OUStringChar(sfx2::cTokenSeparator) +
687 aLink.FilterName + OUStringChar(sfx2::cTokenSeparator) +
688 o3tl::getToken(pSectionData->GetLinkFileName(), 2, sfx2::cTokenSeparator));
689 pSectionData->SetLinkFileName(sFileName);
690 if (sFileName.getLength() < 3)
692 pSectionData->SetType(SectionType::Content);
696 break;
697 case WID_SECT_REGION:
699 OUString sLink;
700 pValues[nProperty] >>= sLink;
701 if (m_bIsDescriptor)
703 m_pProps->m_bDDE = false;
704 m_pProps->m_sSectionRegion = sLink;
706 else
708 if (pSectionData->GetType() != SectionType::FileLink &&
709 !sLink.isEmpty())
711 pSectionData->SetType(SectionType::FileLink);
713 OUString sSectLink(pSectionData->GetLinkFileName());
714 for (sal_Int32 i = comphelper::string::getTokenCount(sSectLink, sfx2::cTokenSeparator);
715 i < 3; ++i)
717 sSectLink += OUStringChar(sfx2::cTokenSeparator);
719 sSectLink = comphelper::string::setToken(sSectLink, 2, sfx2::cTokenSeparator, sLink);
720 pSectionData->SetLinkFileName(sSectLink);
721 if (sSectLink.getLength() < 3)
723 pSectionData->SetType(SectionType::Content);
727 break;
728 case WID_SECT_VISIBLE:
730 bool bVal(false);
731 if (!(pValues[nProperty] >>= bVal))
733 throw lang::IllegalArgumentException();
735 if (m_bIsDescriptor)
737 m_pProps->m_bHidden = !bVal;
739 else
741 pSectionData->SetHidden(!bVal);
744 break;
745 case WID_SECT_CURRENTLY_VISIBLE:
747 bool bVal(false);
748 if (!(pValues[nProperty] >>= bVal))
750 throw lang::IllegalArgumentException();
752 if (m_bIsDescriptor)
754 m_pProps->m_bCondHidden = !bVal;
756 else
758 if (!pSectionData->GetCondition().isEmpty())
760 pSectionData->SetCondHidden(!bVal);
764 break;
765 case WID_SECT_PROTECTED:
767 bool bVal(false);
768 if (!(pValues[nProperty] >>= bVal))
770 throw lang::IllegalArgumentException();
772 if (m_bIsDescriptor)
774 m_pProps->m_bProtect = bVal;
776 else
778 pSectionData->SetProtectFlag(bVal);
781 break;
782 case WID_SECT_EDIT_IN_READONLY:
784 bool bVal(false);
785 if (!(pValues[nProperty] >>= bVal))
787 throw lang::IllegalArgumentException();
789 if (m_bIsDescriptor)
791 m_pProps->m_bEditInReadonly = bVal;
793 else
795 pSectionData->SetEditInReadonlyFlag(bVal);
798 break;
799 case WID_SECT_PASSWORD:
801 uno::Sequence<sal_Int8> aSeq;
802 pValues[nProperty] >>= aSeq;
803 if (m_bIsDescriptor)
805 m_pProps->m_Password = aSeq;
807 else
809 pSectionData->SetPassword(aSeq);
812 break;
813 default:
815 if (pFormat)
817 const SfxItemSet& rOldAttrSet = pFormat->GetAttrSet();
818 oItemSet.emplace(*rOldAttrSet.GetPool(), pEntry->nWID, pEntry->nWID);
819 oItemSet->Put(rOldAttrSet);
820 m_rPropSet.setPropertyValue(*pEntry,
821 pValues[nProperty], *oItemSet);
823 else
825 SfxPoolItem* pPutItem = nullptr;
826 if (RES_COL == pEntry->nWID)
828 if (!m_pProps->m_pColItem)
830 m_pProps->m_pColItem.reset(new SwFormatCol);
832 pPutItem = m_pProps->m_pColItem.get();
834 else if (RES_BACKGROUND == pEntry->nWID)
836 if (!m_pProps->m_pBrushItem)
838 m_pProps->m_pBrushItem.reset(
839 new SvxBrushItem(RES_BACKGROUND));
841 pPutItem = m_pProps->m_pBrushItem.get();
843 else if (RES_FTN_AT_TXTEND == pEntry->nWID)
845 if (!m_pProps->m_pFootnoteItem)
847 m_pProps->m_pFootnoteItem.reset(new SwFormatFootnoteAtTextEnd);
849 pPutItem = m_pProps->m_pFootnoteItem.get();
851 else if (RES_END_AT_TXTEND == pEntry->nWID)
853 if (!m_pProps->m_pEndItem)
855 m_pProps->m_pEndItem.reset(new SwFormatEndAtTextEnd);
857 pPutItem = m_pProps->m_pEndItem.get();
859 else if (RES_UNKNOWNATR_CONTAINER== pEntry->nWID)
861 if (!m_pProps->m_pXMLAttr)
863 m_pProps->m_pXMLAttr.reset(
864 new SvXMLAttrContainerItem(
865 RES_UNKNOWNATR_CONTAINER));
867 pPutItem = m_pProps->m_pXMLAttr.get();
869 else if (RES_COLUMNBALANCE== pEntry->nWID)
871 if (!m_pProps->m_pNoBalanceItem)
873 m_pProps->m_pNoBalanceItem.reset(
874 new SwFormatNoBalancedColumns(true));
876 pPutItem = m_pProps->m_pNoBalanceItem.get();
878 else if (RES_FRAMEDIR == pEntry->nWID)
880 if (!m_pProps->m_pFrameDirItem)
882 m_pProps->m_pFrameDirItem.reset(
883 new SvxFrameDirectionItem(
884 SvxFrameDirection::Horizontal_LR_TB, RES_FRAMEDIR));
886 pPutItem = m_pProps->m_pFrameDirItem.get();
888 else if (RES_LR_SPACE == pEntry->nWID)
890 if (!m_pProps->m_pLRSpaceItem)
892 m_pProps->m_pLRSpaceItem.reset(
893 new SvxLRSpaceItem( RES_LR_SPACE ));
895 pPutItem = m_pProps->m_pLRSpaceItem.get();
897 if (pPutItem)
899 pPutItem->PutValue(pValues[nProperty],
900 pEntry->nMemberId);
907 lcl_UpdateSection(pFormat, pSectionData, oItemSet, bLinkModeChanged,
908 bLinkMode);
911 void SAL_CALL
912 SwXTextSection::setPropertyValues(
913 const uno::Sequence< OUString >& rPropertyNames,
914 const uno::Sequence< uno::Any >& rValues)
916 SolarMutexGuard aGuard;
918 // workaround for bad designed API
921 m_pImpl->SetPropertyValues_Impl( rPropertyNames, rValues );
923 catch (const beans::UnknownPropertyException &rException)
925 // wrap the original (here not allowed) exception in
926 // a WrappedTargetException that gets thrown instead.
927 lang::WrappedTargetException aWExc;
928 aWExc.TargetException <<= rException;
929 throw aWExc;
933 void SwXTextSection::setPropertyValue(
934 const OUString& rPropertyName, const uno::Any& rValue)
936 SolarMutexGuard aGuard;
938 m_pImpl->SetPropertyValues_Impl( { rPropertyName } , { rValue } );
941 uno::Sequence< uno::Any >
942 SwXTextSection::Impl::GetPropertyValues_Impl(
943 const uno::Sequence< OUString > & rPropertyNames )
945 SwSectionFormat *const pFormat = GetSectionFormat();
946 if (!pFormat && !m_bIsDescriptor)
948 throw uno::RuntimeException( "non-descriptor section without format");
951 uno::Sequence< uno::Any > aRet(rPropertyNames.getLength());
952 uno::Any* pRet = aRet.getArray();
953 SwSection *const pSect = pFormat ? pFormat->GetSection() : nullptr;
954 const OUString* pPropertyNames = rPropertyNames.getConstArray();
956 for (sal_Int32 nProperty = 0; nProperty < rPropertyNames.getLength();
957 nProperty++)
959 SfxItemPropertyMapEntry const*const pEntry =
960 m_rPropSet.getPropertyMap().getByName(pPropertyNames[nProperty]);
961 if (!pEntry)
963 throw beans::UnknownPropertyException(
964 "Unknown property: " + pPropertyNames[nProperty],
965 static_cast<cppu::OWeakObject *>(& m_rThis));
967 switch(pEntry->nWID)
969 case WID_SECT_CONDITION:
971 const OUString uTmp( m_bIsDescriptor
972 ? m_pProps->m_sCondition
973 : pSect->GetCondition());
974 pRet[nProperty] <<= uTmp;
976 break;
977 case WID_SECT_DDE_TYPE:
978 case WID_SECT_DDE_FILE:
979 case WID_SECT_DDE_ELEMENT:
981 OUString sRet;
982 if (m_bIsDescriptor)
984 if (m_pProps->m_bDDE)
986 sRet = m_pProps->m_sLinkFileName;
989 else if (SectionType::DdeLink == pSect->GetType())
991 sRet = pSect->GetLinkFileName();
993 pRet[nProperty] <<= sRet.getToken(pEntry->nWID - WID_SECT_DDE_TYPE,
994 sfx2::cTokenSeparator);
996 break;
997 case WID_SECT_DDE_AUTOUPDATE:
999 // GetUpdateType() returns .._ALWAYS or .._ONCALL
1000 if (pSect && pSect->IsLinkType() && pSect->IsConnected()) // #i73247#
1002 const bool bTemp =
1003 (pSect->GetUpdateType() == SfxLinkUpdateMode::ALWAYS);
1004 pRet[nProperty] <<= bTemp;
1007 break;
1008 case WID_SECT_LINK :
1010 text::SectionFileLink aLink;
1011 if (m_bIsDescriptor)
1013 if (!m_pProps->m_bDDE)
1015 aLink.FileURL = m_pProps->m_sLinkFileName;
1016 aLink.FilterName = m_pProps->m_sSectionFilter;
1019 else if (SectionType::FileLink == pSect->GetType())
1021 const OUString& sRet( pSect->GetLinkFileName() );
1022 sal_Int32 nIndex(0);
1023 aLink.FileURL =
1024 sRet.getToken(0, sfx2::cTokenSeparator, nIndex);
1025 aLink.FilterName =
1026 sRet.getToken(0, sfx2::cTokenSeparator, nIndex);
1028 pRet[nProperty] <<= aLink;
1030 break;
1031 case WID_SECT_REGION :
1033 OUString sRet;
1034 if (m_bIsDescriptor)
1036 sRet = m_pProps->m_sSectionRegion;
1038 else if (SectionType::FileLink == pSect->GetType())
1040 sRet = pSect->GetLinkFileName().getToken(2,
1041 sfx2::cTokenSeparator);
1043 pRet[nProperty] <<= sRet;
1045 break;
1046 case WID_SECT_VISIBLE :
1048 const bool bTemp = m_bIsDescriptor
1049 ? !m_pProps->m_bHidden : !pSect->IsHidden();
1050 pRet[nProperty] <<= bTemp;
1052 break;
1053 case WID_SECT_CURRENTLY_VISIBLE:
1055 const bool bTemp = m_bIsDescriptor
1056 ? !m_pProps->m_bCondHidden : !pSect->IsCondHidden();
1057 pRet[nProperty] <<= bTemp;
1059 break;
1060 case WID_SECT_PROTECTED:
1062 const bool bTemp = m_bIsDescriptor
1063 ? m_pProps->m_bProtect : pSect->IsProtect();
1064 pRet[nProperty] <<= bTemp;
1066 break;
1067 case WID_SECT_EDIT_IN_READONLY:
1069 const bool bTemp = m_bIsDescriptor
1070 ? m_pProps->m_bEditInReadonly : pSect->IsEditInReadonly();
1071 pRet[nProperty] <<= bTemp;
1073 break;
1074 case FN_PARAM_LINK_DISPLAY_NAME:
1076 if (pFormat)
1078 pRet[nProperty] <<= pFormat->GetSection()->GetSectionName();
1081 break;
1082 case WID_SECT_DOCUMENT_INDEX:
1084 // search enclosing index
1085 SwSection* pEnclosingSection = pSect;
1086 while ((pEnclosingSection != nullptr) &&
1087 (SectionType::ToxContent != pEnclosingSection->GetType()))
1089 pEnclosingSection = pEnclosingSection->GetParent();
1091 SwTOXBaseSection* const pTOXBaseSect = pEnclosingSection ?
1092 dynamic_cast<SwTOXBaseSection*>( pEnclosingSection ) : nullptr;
1093 if (pTOXBaseSect)
1095 // convert section to TOXBase and get SwXDocumentIndex
1096 const uno::Reference<text::XDocumentIndex> xIndex =
1097 SwXDocumentIndex::CreateXDocumentIndex(
1098 *pTOXBaseSect->GetFormat()->GetDoc(), pTOXBaseSect);
1099 pRet[nProperty] <<= xIndex;
1101 // else: no enclosing index found -> empty return value
1103 break;
1104 case WID_SECT_IS_GLOBAL_DOC_SECTION:
1106 const bool bRet = pFormat && (nullptr != pFormat->GetGlobalDocSection());
1107 pRet[nProperty] <<= bRet;
1109 break;
1110 case FN_UNO_ANCHOR_TYPES:
1111 case FN_UNO_TEXT_WRAP:
1112 case FN_UNO_ANCHOR_TYPE:
1113 ::sw::GetDefaultTextContentValue(
1114 pRet[nProperty], u"", pEntry->nWID);
1115 break;
1116 case FN_UNO_REDLINE_NODE_START:
1117 case FN_UNO_REDLINE_NODE_END:
1119 if (!pFormat)
1120 break; // #i73247#
1121 SwNode* pSectNode = pFormat->GetSectionNode();
1122 if (FN_UNO_REDLINE_NODE_END == pEntry->nWID)
1124 pSectNode = pSectNode->EndOfSectionNode();
1126 const SwRedlineTable& rRedTable =
1127 pFormat->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
1128 for (SwRangeRedline* pRedline : rRedTable)
1130 const SwNode& rRedPointNode = pRedline->GetPointNode();
1131 const SwNode& rRedMarkNode = pRedline->GetMarkNode();
1132 if ((&rRedPointNode == pSectNode) ||
1133 (&rRedMarkNode == pSectNode))
1135 const SwNode& rStartOfRedline =
1136 (SwNodeIndex(rRedPointNode) <=
1137 SwNodeIndex(rRedMarkNode))
1138 ? rRedPointNode : rRedMarkNode;
1139 const bool bIsStart = (&rStartOfRedline == pSectNode);
1140 pRet[nProperty] <<=
1141 SwXRedlinePortion::CreateRedlineProperties(
1142 *pRedline, bIsStart);
1143 break;
1147 break;
1148 case WID_SECT_PASSWORD:
1150 pRet[nProperty] <<= m_bIsDescriptor
1151 ? m_pProps->m_Password : pSect->GetPassword();
1153 break;
1154 default:
1156 if (pFormat)
1158 m_rPropSet.getPropertyValue(*pEntry,
1159 pFormat->GetAttrSet(), pRet[nProperty]);
1161 else
1163 const SfxPoolItem* pQueryItem = nullptr;
1164 if (RES_COL == pEntry->nWID)
1166 if (!m_pProps->m_pColItem)
1168 m_pProps->m_pColItem.reset(new SwFormatCol);
1170 pQueryItem = m_pProps->m_pColItem.get();
1172 else if (RES_BACKGROUND == pEntry->nWID)
1174 if (!m_pProps->m_pBrushItem)
1176 m_pProps->m_pBrushItem.reset(
1177 new SvxBrushItem(RES_BACKGROUND));
1179 pQueryItem = m_pProps->m_pBrushItem.get();
1181 else if (RES_FTN_AT_TXTEND == pEntry->nWID)
1183 if (!m_pProps->m_pFootnoteItem)
1185 m_pProps->m_pFootnoteItem.reset(new SwFormatFootnoteAtTextEnd);
1187 pQueryItem = m_pProps->m_pFootnoteItem.get();
1189 else if (RES_END_AT_TXTEND == pEntry->nWID)
1191 if (!m_pProps->m_pEndItem)
1193 m_pProps->m_pEndItem.reset(new SwFormatEndAtTextEnd);
1195 pQueryItem = m_pProps->m_pEndItem.get();
1197 else if (RES_UNKNOWNATR_CONTAINER== pEntry->nWID)
1199 if (!m_pProps->m_pXMLAttr)
1201 m_pProps->m_pXMLAttr.reset(
1202 new SvXMLAttrContainerItem);
1204 pQueryItem = m_pProps->m_pXMLAttr.get();
1206 else if (RES_COLUMNBALANCE== pEntry->nWID)
1208 if (!m_pProps->m_pNoBalanceItem)
1210 m_pProps->m_pNoBalanceItem.reset(
1211 new SwFormatNoBalancedColumns);
1213 pQueryItem = m_pProps->m_pNoBalanceItem.get();
1215 else if (RES_FRAMEDIR == pEntry->nWID)
1217 if (!m_pProps->m_pFrameDirItem)
1219 m_pProps->m_pFrameDirItem.reset(
1220 new SvxFrameDirectionItem(
1221 SvxFrameDirection::Environment, RES_FRAMEDIR));
1223 pQueryItem = m_pProps->m_pFrameDirItem.get();
1225 else if (RES_LR_SPACE == pEntry->nWID)
1227 if (!m_pProps->m_pLRSpaceItem)
1229 m_pProps->m_pLRSpaceItem.reset(
1230 new SvxLRSpaceItem( RES_LR_SPACE ));
1232 pQueryItem = m_pProps->m_pLRSpaceItem.get();
1234 if (pQueryItem)
1236 pQueryItem->QueryValue(pRet[nProperty],
1237 pEntry->nMemberId);
1243 return aRet;
1246 uno::Sequence< uno::Any > SAL_CALL
1247 SwXTextSection::getPropertyValues(
1248 const uno::Sequence< OUString >& rPropertyNames)
1250 SolarMutexGuard aGuard;
1251 uno::Sequence< uno::Any > aValues;
1253 // workaround for bad designed API
1256 aValues = m_pImpl->GetPropertyValues_Impl( rPropertyNames );
1258 catch (beans::UnknownPropertyException &)
1260 css::uno::Any anyEx = cppu::getCaughtException();
1261 throw lang::WrappedTargetRuntimeException("Unknown property exception caught",
1262 static_cast < cppu::OWeakObject * > ( this ), anyEx );
1264 catch (lang::WrappedTargetException &)
1266 css::uno::Any anyEx = cppu::getCaughtException();
1267 throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
1268 static_cast < cppu::OWeakObject * > ( this ), anyEx );
1271 return aValues;
1274 uno::Any SAL_CALL
1275 SwXTextSection::getPropertyValue(const OUString& rPropertyName)
1277 SolarMutexGuard aGuard;
1279 uno::Sequence< OUString > aPropertyNames { rPropertyName };
1280 return m_pImpl->GetPropertyValues_Impl(aPropertyNames).getConstArray()[0];
1283 void SAL_CALL SwXTextSection::addPropertiesChangeListener(
1284 const uno::Sequence< OUString >& /*aPropertyNames*/,
1285 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
1287 OSL_FAIL("SwXTextSection::addPropertiesChangeListener(): not implemented");
1290 void SAL_CALL SwXTextSection::removePropertiesChangeListener(
1291 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
1293 OSL_FAIL("SwXTextSection::removePropertiesChangeListener(): not implemented");
1296 void SAL_CALL SwXTextSection::firePropertiesChangeEvent(
1297 const uno::Sequence< OUString >& /*aPropertyNames*/,
1298 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
1300 OSL_FAIL("SwXTextSection::firePropertiesChangeEvent(): not implemented");
1303 void SAL_CALL
1304 SwXTextSection::addPropertyChangeListener(
1305 const OUString& /*rPropertyName*/,
1306 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1308 OSL_FAIL("SwXTextSection::addPropertyChangeListener(): not implemented");
1311 void SAL_CALL
1312 SwXTextSection::removePropertyChangeListener(
1313 const OUString& /*rPropertyName*/,
1314 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1316 OSL_FAIL("SwXTextSection::removePropertyChangeListener(): not implemented");
1319 void SAL_CALL
1320 SwXTextSection::addVetoableChangeListener(
1321 const OUString& /*rPropertyName*/,
1322 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1324 OSL_FAIL("SwXTextSection::addVetoableChangeListener(): not implemented");
1327 void SAL_CALL
1328 SwXTextSection::removeVetoableChangeListener(
1329 const OUString& /*rPropertyName*/,
1330 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1332 OSL_FAIL("SwXTextSection::removeVetoableChangeListener(): not implemented");
1335 beans::PropertyState SAL_CALL
1336 SwXTextSection::getPropertyState(const OUString& rPropertyName)
1338 SolarMutexGuard aGuard;
1340 uno::Sequence< OUString > aNames { rPropertyName };
1341 return getPropertyStates(aNames).getConstArray()[0];
1344 uno::Sequence< beans::PropertyState > SAL_CALL
1345 SwXTextSection::getPropertyStates(
1346 const uno::Sequence< OUString >& rPropertyNames)
1348 SolarMutexGuard aGuard;
1350 SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
1351 if (!pFormat && !m_pImpl->m_bIsDescriptor)
1353 throw uno::RuntimeException();
1356 uno::Sequence< beans::PropertyState > aStates(rPropertyNames.getLength());
1357 beans::PropertyState *const pStates = aStates.getArray();
1358 const OUString* pNames = rPropertyNames.getConstArray();
1359 for (sal_Int32 i = 0; i < rPropertyNames.getLength(); i++)
1361 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
1362 SfxItemPropertyMapEntry const*const pEntry =
1363 m_pImpl->m_rPropSet.getPropertyMap().getByName( pNames[i]);
1364 if (!pEntry)
1366 throw beans::UnknownPropertyException(
1367 "Unknown property: " + pNames[i],
1368 static_cast< cppu::OWeakObject* >(this));
1370 switch (pEntry->nWID)
1372 case WID_SECT_CONDITION:
1373 case WID_SECT_DDE_TYPE:
1374 case WID_SECT_DDE_FILE:
1375 case WID_SECT_DDE_ELEMENT:
1376 case WID_SECT_DDE_AUTOUPDATE:
1377 case WID_SECT_LINK:
1378 case WID_SECT_REGION :
1379 case WID_SECT_VISIBLE:
1380 case WID_SECT_PROTECTED:
1381 case WID_SECT_EDIT_IN_READONLY:
1382 case FN_PARAM_LINK_DISPLAY_NAME:
1383 case FN_UNO_ANCHOR_TYPES:
1384 case FN_UNO_TEXT_WRAP:
1385 case FN_UNO_ANCHOR_TYPE:
1386 pStates[i] = beans::PropertyState_DIRECT_VALUE;
1387 break;
1388 default:
1390 if (pFormat)
1392 pStates[i] = m_pImpl->m_rPropSet.getPropertyState(
1393 pNames[i], pFormat->GetAttrSet());
1395 else
1397 if (RES_COL == pEntry->nWID)
1399 if (!m_pImpl->m_pProps->m_pColItem)
1401 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
1403 else
1405 pStates[i] = beans::PropertyState_DIRECT_VALUE;
1408 else
1410 if (!m_pImpl->m_pProps->m_pBrushItem)
1412 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
1414 else
1416 pStates[i] = beans::PropertyState_DIRECT_VALUE;
1423 return aStates;
1426 void SAL_CALL
1427 SwXTextSection::setPropertyToDefault(const OUString& rPropertyName)
1429 SolarMutexGuard aGuard;
1431 SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
1432 if (!pFormat && !m_pImpl->m_bIsDescriptor)
1434 throw uno::RuntimeException();
1437 SfxItemPropertyMapEntry const*const pEntry =
1438 m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
1439 if (!pEntry)
1441 throw beans::UnknownPropertyException(
1442 "Unknown property: " + rPropertyName,
1443 static_cast< cppu::OWeakObject* >(this));
1445 if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
1447 throw uno::RuntimeException(
1448 "Property is read-only: " + rPropertyName,
1449 static_cast<cppu::OWeakObject *>(this));
1452 std::unique_ptr<SwSectionData> const pSectionData(
1453 pFormat ? new SwSectionData(*pFormat->GetSection()) : nullptr);
1455 std::optional<SfxItemSet> oNewAttrSet;
1456 bool bLinkModeChanged = false;
1458 switch (pEntry->nWID)
1460 case WID_SECT_CONDITION:
1462 if (m_pImpl->m_bIsDescriptor)
1464 m_pImpl->m_pProps->m_sCondition.clear();
1466 else
1468 pSectionData->SetCondition(OUString());
1471 break;
1472 case WID_SECT_DDE_TYPE :
1473 case WID_SECT_DDE_FILE :
1474 case WID_SECT_DDE_ELEMENT :
1475 case WID_SECT_LINK :
1476 case WID_SECT_REGION :
1477 if (m_pImpl->m_bIsDescriptor)
1479 m_pImpl->m_pProps->m_bDDE = false;
1480 m_pImpl->m_pProps->m_sLinkFileName.clear();
1481 m_pImpl->m_pProps->m_sSectionRegion.clear();
1482 m_pImpl->m_pProps->m_sSectionFilter.clear();
1484 else
1486 pSectionData->SetType(SectionType::Content);
1488 break;
1489 case WID_SECT_DDE_AUTOUPDATE:
1490 if (m_pImpl->m_bIsDescriptor)
1492 m_pImpl->m_pProps->m_bUpdateType = true;
1494 else
1496 bLinkModeChanged = true;
1498 break;
1499 case WID_SECT_VISIBLE :
1501 if (m_pImpl->m_bIsDescriptor)
1503 m_pImpl->m_pProps->m_bHidden = false;
1505 else
1507 pSectionData->SetHidden(false);
1510 break;
1511 case WID_SECT_PROTECTED:
1513 if (m_pImpl->m_bIsDescriptor)
1515 m_pImpl->m_pProps->m_bProtect = false;
1517 else
1519 pSectionData->SetProtectFlag(false);
1522 break;
1523 case WID_SECT_EDIT_IN_READONLY:
1525 if (m_pImpl->m_bIsDescriptor)
1527 m_pImpl->m_pProps->m_bEditInReadonly = false;
1529 else
1531 pSectionData->SetEditInReadonlyFlag(false);
1534 break;
1536 case FN_UNO_ANCHOR_TYPES:
1537 case FN_UNO_TEXT_WRAP:
1538 case FN_UNO_ANCHOR_TYPE:
1539 break;
1540 default:
1542 if (SfxItemPool::IsWhich(pEntry->nWID))
1544 if (pFormat)
1546 const SfxItemSet& rOldAttrSet = pFormat->GetAttrSet();
1547 oNewAttrSet.emplace(*rOldAttrSet.GetPool(), pEntry->nWID, pEntry->nWID);
1548 oNewAttrSet->ClearItem(pEntry->nWID);
1550 else
1552 if (RES_COL == pEntry->nWID)
1554 m_pImpl->m_pProps->m_pColItem.reset();
1556 else if (RES_BACKGROUND == pEntry->nWID)
1558 m_pImpl->m_pProps->m_pBrushItem.reset();
1565 lcl_UpdateSection(pFormat, pSectionData, oNewAttrSet, bLinkModeChanged);
1568 uno::Any SAL_CALL
1569 SwXTextSection::getPropertyDefault(const OUString& rPropertyName)
1571 SolarMutexGuard aGuard;
1573 uno::Any aRet;
1574 SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
1575 SfxItemPropertyMapEntry const*const pEntry =
1576 m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
1577 if (!pEntry)
1579 throw beans::UnknownPropertyException(
1580 "Unknown property: " + rPropertyName,
1581 static_cast<cppu::OWeakObject *>(this));
1584 switch(pEntry->nWID)
1586 case WID_SECT_CONDITION:
1587 case WID_SECT_DDE_TYPE :
1588 case WID_SECT_DDE_FILE :
1589 case WID_SECT_DDE_ELEMENT :
1590 case WID_SECT_REGION :
1591 case FN_PARAM_LINK_DISPLAY_NAME:
1592 aRet <<= OUString();
1593 break;
1594 case WID_SECT_LINK :
1595 aRet <<= text::SectionFileLink();
1596 break;
1597 case WID_SECT_DDE_AUTOUPDATE:
1598 case WID_SECT_VISIBLE :
1599 aRet <<= true;
1600 break;
1601 case WID_SECT_PROTECTED:
1602 case WID_SECT_EDIT_IN_READONLY:
1603 aRet <<= false;
1604 break;
1605 case FN_UNO_ANCHOR_TYPES:
1606 case FN_UNO_TEXT_WRAP:
1607 case FN_UNO_ANCHOR_TYPE:
1608 ::sw::GetDefaultTextContentValue(aRet, u"", pEntry->nWID);
1609 break;
1610 default:
1611 if(pFormat && SfxItemPool::IsWhich(pEntry->nWID))
1613 SwDoc *const pDoc = pFormat->GetDoc();
1614 const SfxPoolItem& rDefItem =
1615 pDoc->GetAttrPool().GetDefaultItem(pEntry->nWID);
1616 rDefItem.QueryValue(aRet, pEntry->nMemberId);
1619 return aRet;
1622 OUString SAL_CALL SwXTextSection::getName()
1624 SolarMutexGuard aGuard;
1626 OUString sRet;
1627 SwSectionFormat const*const pFormat = m_pImpl->GetSectionFormat();
1628 if(pFormat)
1630 sRet = pFormat->GetSection()->GetSectionName();
1632 else if (m_pImpl->m_bIsDescriptor)
1634 sRet = m_pImpl->m_sName;
1636 else
1638 throw uno::RuntimeException();
1640 return sRet;
1643 void SAL_CALL SwXTextSection::setName(const OUString& rName)
1645 SolarMutexGuard aGuard;
1647 SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
1648 if(pFormat)
1650 SwSection *const pSect = pFormat->GetSection();
1651 SwSectionData aSection(*pSect);
1652 aSection.SetSectionName(rName);
1654 const SwSectionFormats& rFormats = pFormat->GetDoc()->GetSections();
1655 size_t nApplyPos = SIZE_MAX;
1656 for( size_t i = 0; i < rFormats.size(); ++i )
1658 if(rFormats[i]->GetSection() == pSect)
1660 nApplyPos = i;
1662 else if (rName == rFormats[i]->GetSection()->GetSectionName())
1664 throw uno::RuntimeException();
1667 if (nApplyPos != SIZE_MAX)
1670 UnoActionContext aContext(pFormat->GetDoc());
1671 pFormat->GetDoc()->UpdateSection(nApplyPos, aSection);
1674 // temporarily remove actions to allow cursor update
1675 // TODO: why? no table cursor here!
1676 UnoActionRemoveContext aRemoveContext( pFormat->GetDoc() );
1680 else if (m_pImpl->m_bIsDescriptor)
1682 m_pImpl->m_sName = rName;
1684 else
1686 throw uno::RuntimeException();
1690 OUString SAL_CALL
1691 SwXTextSection::getImplementationName()
1693 return "SwXTextSection";
1696 sal_Bool SAL_CALL SwXTextSection::supportsService(const OUString& rServiceName)
1698 return cppu::supportsService(this, rServiceName);
1701 uno::Sequence< OUString > SAL_CALL
1702 SwXTextSection::getSupportedServiceNames()
1704 return {
1705 "com.sun.star.text.TextContent",
1706 "com.sun.star.text.TextSection",
1707 "com.sun.star.document.LinkTarget"
1711 // MetadatableMixin
1712 ::sfx2::Metadatable* SwXTextSection::GetCoreObject()
1714 SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
1715 return pSectionFormat;
1718 uno::Reference<frame::XModel> SwXTextSection::GetModel()
1720 SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
1721 if (pSectionFormat)
1723 SwDocShell const*const pShell( pSectionFormat->GetDoc()->GetDocShell() );
1724 return pShell ? pShell->GetModel() : nullptr;
1726 return nullptr;
1729 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */