/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; namespace { /// UNO API wrapper around the text inside an SwXContentControl. class SwXContentControlText : public cppu::OWeakObject, public SwXText { private: SwXContentControl& m_rContentControl; void PrepareForAttach(uno::Reference& xRange, const SwPaM& rPam) override; protected: const SwStartNode* GetStartNode() const override; public: SwXContentControlText(SwDoc& rDoc, SwXContentControl& rContentControl); /// SwXText::Invalidate() is protected. using SwXText::Invalidate; // XInterface void SAL_CALL acquire() noexcept override { cppu::OWeakObject::acquire(); } void SAL_CALL release() noexcept override { cppu::OWeakObject::release(); } // XTypeProvider uno::Sequence SAL_CALL getImplementationId() override; // XText virtual rtl::Reference createXTextCursor() override; virtual rtl::Reference createXTextCursorByRange( const ::css::uno::Reference<::css::text::XTextRange>& aTextPosition) override; }; } SwXContentControlText::SwXContentControlText(SwDoc& rDoc, SwXContentControl& rContentControl) : SwXText(&rDoc, CursorType::ContentControl) , m_rContentControl(rContentControl) { } const SwStartNode* SwXContentControlText::GetStartNode() const { SwXText* pParent = m_rContentControl.GetParentText().get(); return pParent ? pParent->GetStartNode() : nullptr; } void SwXContentControlText::PrepareForAttach(uno::Reference& xRange, const SwPaM& rPam) { // Create a new cursor to prevent modifying SwXTextRange. xRange = static_cast( new SwXTextCursor(*GetDoc(), &m_rContentControl, CursorType::ContentControl, *rPam.GetPoint(), (rPam.HasMark()) ? rPam.GetMark() : nullptr)); } rtl::Reference SwXContentControlText::createXTextCursor() { rtl::Reference xRet; if (IsValid()) { SwTextNode* pTextNode; sal_Int32 nContentControlStart; sal_Int32 nContentControlEnd; bool bSuccess = m_rContentControl.SetContentRange(pTextNode, nContentControlStart, nContentControlEnd); if (bSuccess) { SwPosition aPos(*pTextNode, nContentControlStart); xRet = new SwXTextCursor(*GetDoc(), &m_rContentControl, CursorType::ContentControl, aPos); } } return xRet; } uno::Sequence SAL_CALL SwXContentControlText::getImplementationId() { return css::uno::Sequence(); } // XText rtl::Reference SwXContentControlText::createXTextCursorByRange( const uno::Reference& xTextPosition) { const rtl::Reference xCursor(createXTextCursor()); xCursor->gotoRange(xTextPosition, false); return xCursor; } /** * The inner part SwXContentControl, which is deleted with a locked SolarMutex. * * The content control has a cached list of text portions for its contents. This list is created by * SwXTextPortionEnumeration. The content control listens at the SwTextNode and throws away the * cache when the text node changes. */ class SwXContentControl::Impl : public SvtListener { public: unotools::WeakReference m_wThis; // Just for OInterfaceContainerHelper4. std::mutex m_Mutex; ::comphelper::OInterfaceContainerHelper4 m_EventListeners; std::unique_ptr m_pTextPortions; // 3 possible states: not attached, attached, disposed bool m_bIsDisposed; bool m_bIsDescriptor; css::uno::Reference m_xParentText; rtl::Reference m_xText; SwContentControl* m_pContentControl; bool m_bShowingPlaceHolder; bool m_bCheckbox; bool m_bChecked; OUString m_aCheckedState; OUString m_aUncheckedState; std::vector m_aListItems; bool m_bPicture; bool m_bDate; OUString m_aDateFormat; OUString m_aDateLanguage; OUString m_aCurrentDate; bool m_bPlainText; bool m_bComboBox; bool m_bDropDown; OUString m_aPlaceholderDocPart; OUString m_aDataBindingPrefixMappings; OUString m_aDataBindingXpath; OUString m_aDataBindingStoreItemID; OUString m_aColor; OUString m_aAppearance; OUString m_aAlias; OUString m_aTag; sal_Int32 m_nId; sal_uInt32 m_nTabIndex; OUString m_aLock; OUString m_aMultiLine; Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* pContentControl, css::uno::Reference xParentText, std::unique_ptr pPortions) : m_pTextPortions(std::move(pPortions)) , m_bIsDisposed(false) , m_bIsDescriptor(pContentControl == nullptr) , m_xParentText(std::move(xParentText)) , m_xText(new SwXContentControlText(rDoc, rThis)) , m_pContentControl(pContentControl) , m_bShowingPlaceHolder(false) , m_bCheckbox(false) , m_bChecked(false) , m_bPicture(false) , m_bDate(false) , m_bPlainText(false) , m_bComboBox(false) , m_bDropDown(false) , m_nId(0) , m_nTabIndex(0) { if (m_pContentControl) { StartListening(m_pContentControl->GetNotifier()); } } const SwContentControl* GetContentControl() const; protected: void Notify(const SfxHint& rHint) override; }; const SwContentControl* SwXContentControl::Impl::GetContentControl() const { return m_pContentControl; } // sw::BroadcastingModify void SwXContentControl::Impl::Notify(const SfxHint& rHint) { // throw away cache (SwTextNode changed) m_pTextPortions.reset(); if (rHint.GetId() != SfxHintId::Dying && rHint.GetId() != SfxHintId::Deinitializing) return; m_bIsDisposed = true; m_pContentControl = nullptr; m_xText->Invalidate(); uno::Reference xThis(m_wThis); if (!xThis.is()) { // If UNO object is already dead, don't refer to it in an event. return; } lang::EventObject aEvent(xThis); std::unique_lock aGuard(m_Mutex); m_EventListeners.disposeAndClear(aGuard, aEvent); } const css::uno::Reference& SwXContentControl::GetParentText() const { return m_pImpl->m_xParentText; } SwXContentControl::SwXContentControl(SwDoc* pDoc, SwContentControl* pContentControl, const css::uno::Reference& xParentText, std::unique_ptr pPortions) : m_pImpl(new SwXContentControl::Impl(*this, *pDoc, pContentControl, xParentText, std::move(pPortions))) { } SwXContentControl::SwXContentControl(SwDoc* pDoc) : m_pImpl(new SwXContentControl::Impl(*this, *pDoc, nullptr, nullptr, nullptr)) { } SwXContentControl::~SwXContentControl() {} rtl::Reference SwXContentControl::CreateXContentControl(SwDoc& rDoc) { rtl::Reference xContentControl(new SwXContentControl(&rDoc)); xContentControl->m_pImpl->m_wThis = xContentControl.get(); return xContentControl; } rtl::Reference SwXContentControl::CreateXContentControl(SwContentControl& rContentControl, const css::uno::Reference& xParent, std::unique_ptr&& pPortions) { // re-use existing SwXContentControl rtl::Reference xContentControl(rContentControl.GetXContentControl()); if (xContentControl.is()) { if (pPortions) { // The content control must always be created with the complete content. If // SwXTextPortionEnumeration is created for a selection, it must be checked that the // content control is contained in the selection. xContentControl->m_pImpl->m_pTextPortions = std::move(pPortions); if (xContentControl->m_pImpl->m_xParentText.get() != xParent.get()) { SAL_WARN("sw.uno", "SwXContentControl with different parent"); xContentControl->m_pImpl->m_xParentText = xParent; } } return xContentControl; } // Create new SwXContentControl. SwTextNode* pTextNode = rContentControl.GetTextNode(); if (!pTextNode) { SAL_WARN("sw.uno", "CreateXContentControl: no text node"); return nullptr; } css::uno::Reference xParentText(xParent); if (!xParentText.is()) { SwTextContentControl* pTextAttr = rContentControl.GetTextAttr(); if (!pTextAttr) { SAL_WARN("sw.uno", "CreateXContentControl: no text attr"); return nullptr; } SwPosition aPos(*pTextNode, pTextAttr->GetStart()); xParentText = sw::CreateParentXText(pTextNode->GetDoc(), aPos); } if (!xParentText.is()) { return nullptr; } xContentControl = new SwXContentControl(&pTextNode->GetDoc(), &rContentControl, xParentText, std::move(pPortions)); rContentControl.SetXContentControl(xContentControl); xContentControl->m_pImpl->m_wThis = xContentControl.get(); return xContentControl; } bool SwXContentControl::SetContentRange(SwTextNode*& rpNode, sal_Int32& rStart, sal_Int32& rEnd) const { const SwContentControl* pContentControl = m_pImpl->GetContentControl(); if (pContentControl) { const SwTextContentControl* pTextAttr = pContentControl->GetTextAttr(); if (pTextAttr) { rpNode = pContentControl->GetTextNode(); if (rpNode) { // rStart points at the first position within the content control. rStart = pTextAttr->GetStart() + 1; // rEnd points at the last position within the content control. rEnd = *pTextAttr->End() - 1; return true; } } } return false; } // XServiceInfo OUString SAL_CALL SwXContentControl::getImplementationName() { return "SwXContentControl"; } sal_Bool SAL_CALL SwXContentControl::supportsService(const OUString& rServiceName) { return cppu::supportsService(this, rServiceName); } uno::Sequence SAL_CALL SwXContentControl::getSupportedServiceNames() { return { "com.sun.star.text.TextContent", "com.sun.star.text.ContentControl" }; } // XComponent void SAL_CALL SwXContentControl::addEventListener(const uno::Reference& xListener) { std::unique_lock aGuard(m_pImpl->m_Mutex); m_pImpl->m_EventListeners.addInterface(aGuard, xListener); } void SAL_CALL SwXContentControl::removeEventListener(const uno::Reference& xListener) { std::unique_lock aGuard(m_pImpl->m_Mutex); m_pImpl->m_EventListeners.removeInterface(aGuard, xListener); } void SAL_CALL SwXContentControl::dispose() { SolarMutexGuard g; if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_pTextPortions.reset(); lang::EventObject aEvent(getXWeak()); std::unique_lock aGuard(m_pImpl->m_Mutex); m_pImpl->m_EventListeners.disposeAndClear(aGuard, aEvent); m_pImpl->m_bIsDisposed = true; m_pImpl->m_xText->Invalidate(); } else if (!m_pImpl->m_bIsDisposed) { SwTextNode* pTextNode; sal_Int32 nContentControlStart; sal_Int32 nContentControlEnd; bool bSuccess = SetContentRange(pTextNode, nContentControlStart, nContentControlEnd); if (!bSuccess) { SAL_WARN("sw.core", "SwXContentControl::dispose: no pam"); } else { // -1 because of CH_TXTATR SwPaM aPam(*pTextNode, nContentControlStart - 1, *pTextNode, nContentControlEnd); SwDoc& rDoc(pTextNode->GetDoc()); rDoc.getIDocumentContentOperations().DeleteAndJoin(aPam); // removal should call Modify and do the dispose assert(m_pImpl->m_bIsDisposed); } } } void SwXContentControl::AttachImpl(const uno::Reference& xTextRange, sal_uInt16 nWhich) { SolarMutexGuard aGuard; if (m_pImpl->m_bIsDisposed) { throw lang::DisposedException(); } if (!m_pImpl->m_bIsDescriptor) { throw uno::RuntimeException("SwXContentControl::AttachImpl(): already attached", getXWeak()); } SwXTextRange* pRange = dynamic_cast(xTextRange.get()); OTextCursorHelper* pCursor = pRange ? nullptr : dynamic_cast(xTextRange.get()); if (!pRange && !pCursor) { throw lang::IllegalArgumentException( "SwXContentControl::AttachImpl(): argument not supported type", getXWeak(), 0); } SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor->GetDoc(); if (!pDoc) { throw lang::IllegalArgumentException( "SwXContentControl::AttachImpl(): argument has no SwDoc", getXWeak(), 0); } SwUnoInternalPaM aPam(*pDoc); ::sw::XTextRangeToSwPaM(aPam, xTextRange); UnoActionContext aContext(pDoc); auto pTextCursor = dynamic_cast(pCursor); bool bForceExpandHints = pTextCursor && pTextCursor->IsAtEndOfContentControl(); SetAttrMode nInsertFlags = bForceExpandHints ? (SetAttrMode::FORCEHINTEXPAND | SetAttrMode::DONTEXPAND) : SetAttrMode::DONTEXPAND; auto pContentControl = std::make_shared(nullptr); pContentControl->SetShowingPlaceHolder(m_pImpl->m_bShowingPlaceHolder); pContentControl->SetCheckbox(m_pImpl->m_bCheckbox); pContentControl->SetChecked(m_pImpl->m_bChecked); pContentControl->SetCheckedState(m_pImpl->m_aCheckedState); pContentControl->SetUncheckedState(m_pImpl->m_aUncheckedState); pContentControl->SetListItems(m_pImpl->m_aListItems); pContentControl->SetPicture(m_pImpl->m_bPicture); pContentControl->SetDate(m_pImpl->m_bDate); pContentControl->SetDateFormat(m_pImpl->m_aDateFormat); pContentControl->SetDateLanguage(m_pImpl->m_aDateLanguage); pContentControl->SetCurrentDate(m_pImpl->m_aCurrentDate); pContentControl->SetPlainText(m_pImpl->m_bPlainText); pContentControl->SetComboBox(m_pImpl->m_bComboBox); pContentControl->SetDropDown(m_pImpl->m_bDropDown); pContentControl->SetPlaceholderDocPart(m_pImpl->m_aPlaceholderDocPart); pContentControl->SetDataBindingPrefixMappings(m_pImpl->m_aDataBindingPrefixMappings); pContentControl->SetDataBindingXpath(m_pImpl->m_aDataBindingXpath); pContentControl->SetDataBindingStoreItemID(m_pImpl->m_aDataBindingStoreItemID); pContentControl->SetColor(m_pImpl->m_aColor); pContentControl->SetAppearance(m_pImpl->m_aAppearance); pContentControl->SetAlias(m_pImpl->m_aAlias); pContentControl->SetTag(m_pImpl->m_aTag); pContentControl->SetId(m_pImpl->m_nId); pContentControl->SetTabIndex(m_pImpl->m_nTabIndex); pContentControl->SetLock(m_pImpl->m_aLock); pContentControl->SetMultiLine(m_pImpl->m_aMultiLine); SwFormatContentControl aContentControl(pContentControl, nWhich); bool bSuccess = pDoc->getIDocumentContentOperations().InsertPoolItem(aPam, aContentControl, nInsertFlags); SwTextAttr* pTextAttr = pContentControl->GetTextAttr(); if (!bSuccess) { throw lang::IllegalArgumentException( "SwXContentControl::AttachImpl(): cannot create content control: invalid range", getXWeak(), 1); } if (!pTextAttr) { SAL_WARN("sw.core", "content control inserted, but has no text attribute?"); throw uno::RuntimeException( "SwXContentControl::AttachImpl(): cannot create content control", getXWeak()); } m_pImpl->EndListeningAll(); m_pImpl->m_pContentControl = pContentControl.get(); m_pImpl->StartListening(pContentControl->GetNotifier()); pContentControl->SetXContentControl(this); m_pImpl->m_xParentText = sw::CreateParentXText(*pDoc, *aPam.GetPoint()); m_pImpl->m_bIsDescriptor = false; } // XTextContent void SAL_CALL SwXContentControl::attach(const uno::Reference& xTextRange) { return SwXContentControl::AttachImpl(xTextRange, RES_TXTATR_CONTENTCONTROL); } uno::Reference SAL_CALL SwXContentControl::getAnchor() { SolarMutexGuard g; if (m_pImpl->m_bIsDisposed) { throw lang::DisposedException(); } if (m_pImpl->m_bIsDescriptor) { throw uno::RuntimeException("SwXContentControl::getAnchor(): not inserted", getXWeak()); } SwTextNode* pTextNode; sal_Int32 nContentControlStart; sal_Int32 nContentControlEnd; bool bSuccess = SetContentRange(pTextNode, nContentControlStart, nContentControlEnd); if (!bSuccess) { SAL_WARN("sw.core", "no pam"); throw lang::DisposedException("SwXContentControl::getAnchor(): not attached", getXWeak()); } SwPosition aStart(*pTextNode, nContentControlStart - 1); // -1 due to CH_TXTATR SwPosition aEnd(*pTextNode, nContentControlEnd); return SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), aStart, &aEnd); } // XTextRange uno::Reference SAL_CALL SwXContentControl::getText() { return this; } uno::Reference SAL_CALL SwXContentControl::getStart() { SolarMutexGuard g; return m_pImpl->m_xText->getStart(); } uno::Reference SAL_CALL SwXContentControl::getEnd() { SolarMutexGuard g; return m_pImpl->m_xText->getEnd(); } OUString SAL_CALL SwXContentControl::getString() { SolarMutexGuard g; return m_pImpl->m_xText->getString(); } void SAL_CALL SwXContentControl::setString(const OUString& rString) { SolarMutexGuard g; return m_pImpl->m_xText->setString(rString); } // XSimpleText uno::Reference SAL_CALL SwXContentControl::createTextCursor() { SolarMutexGuard g; return m_pImpl->m_xText->createTextCursor(); } uno::Reference SAL_CALL SwXContentControl::createTextCursorByRange(const uno::Reference& xTextPosition) { SolarMutexGuard g; return m_pImpl->m_xText->createTextCursorByRange(xTextPosition); } void SAL_CALL SwXContentControl::insertString(const uno::Reference& xRange, const OUString& rString, sal_Bool bAbsorb) { SolarMutexGuard g; return m_pImpl->m_xText->insertString(xRange, rString, bAbsorb); } void SAL_CALL SwXContentControl::insertControlCharacter( const uno::Reference& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb) { SolarMutexGuard g; return m_pImpl->m_xText->insertControlCharacter(xRange, nControlCharacter, bAbsorb); } // XText void SAL_CALL SwXContentControl::insertTextContent( const uno::Reference& xRange, const uno::Reference& xContent, sal_Bool bAbsorb) { SolarMutexGuard g; return m_pImpl->m_xText->insertTextContent(xRange, xContent, bAbsorb); } void SAL_CALL SwXContentControl::removeTextContent(const uno::Reference& xContent) { SolarMutexGuard g; return m_pImpl->m_xText->removeTextContent(xContent); } // XPropertySet uno::Reference SAL_CALL SwXContentControl::getPropertySetInfo() { SolarMutexGuard aGuard; static uno::Reference xRet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONTENTCONTROL)->getPropertySetInfo(); return xRet; } void SAL_CALL SwXContentControl::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& rValue) { SolarMutexGuard aGuard; if (rPropertyName == UNO_NAME_SHOWING_PLACE_HOLDER) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bShowingPlaceHolder = bValue; } else { m_pImpl->m_pContentControl->SetShowingPlaceHolder(bValue); } } } else if (rPropertyName == UNO_NAME_CHECKBOX) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bCheckbox = bValue; } else { m_pImpl->m_pContentControl->SetCheckbox(bValue); } } } else if (rPropertyName == UNO_NAME_CHECKED) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bChecked = bValue; } else { m_pImpl->m_pContentControl->SetChecked(bValue); } } } else if (rPropertyName == UNO_NAME_CHECKED_STATE) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aCheckedState = aValue; } else { m_pImpl->m_pContentControl->SetCheckedState(aValue); } } } else if (rPropertyName == UNO_NAME_UNCHECKED_STATE) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aUncheckedState = aValue; } else { m_pImpl->m_pContentControl->SetUncheckedState(aValue); } } } else if (rPropertyName == UNO_NAME_LIST_ITEMS) { std::vector aItems = SwContentControlListItem::ItemsFromAny(rValue); if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aListItems = aItems; if (!m_pImpl->m_bComboBox && !m_pImpl->m_bDropDown) { m_pImpl->m_bDropDown = true; } } else { m_pImpl->m_pContentControl->SetListItems(aItems); if (!m_pImpl->m_pContentControl->GetComboBox() && !m_pImpl->m_pContentControl->GetDropDown()) { m_pImpl->m_pContentControl->SetDropDown(true); } } } else if (rPropertyName == UNO_NAME_PICTURE) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bPicture = bValue; } else { m_pImpl->m_pContentControl->SetPicture(bValue); } } } else if (rPropertyName == UNO_NAME_DATE) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bDate = bValue; } else { m_pImpl->m_pContentControl->SetDate(bValue); } } } else if (rPropertyName == UNO_NAME_DATE_FORMAT) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aDateFormat = aValue; } else { m_pImpl->m_pContentControl->SetDateFormat(aValue); } } } else if (rPropertyName == UNO_NAME_DATE_LANGUAGE) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aDateLanguage = aValue; } else { m_pImpl->m_pContentControl->SetDateLanguage(aValue); } } } else if (rPropertyName == UNO_NAME_CURRENT_DATE) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aCurrentDate = aValue; } else { m_pImpl->m_pContentControl->SetCurrentDate(aValue); } } } else if (rPropertyName == UNO_NAME_PLAIN_TEXT) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bPlainText = bValue; } else { m_pImpl->m_pContentControl->SetPlainText(bValue); } } } else if (rPropertyName == UNO_NAME_COMBO_BOX) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bComboBox = bValue; } else { m_pImpl->m_pContentControl->SetComboBox(bValue); } } } else if (rPropertyName == UNO_NAME_DROP_DOWN) { bool bValue; if (rValue >>= bValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_bDropDown = bValue; } else { m_pImpl->m_pContentControl->SetDropDown(bValue); } } } else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aPlaceholderDocPart = aValue; } else { m_pImpl->m_pContentControl->SetPlaceholderDocPart(aValue); } } } else if (rPropertyName == UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aDataBindingPrefixMappings = aValue; } else { m_pImpl->m_pContentControl->SetDataBindingPrefixMappings(aValue); } } } else if (rPropertyName == UNO_NAME_DATA_BINDING_XPATH) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aDataBindingXpath = aValue; } else { m_pImpl->m_pContentControl->SetDataBindingXpath(aValue); } } } else if (rPropertyName == UNO_NAME_DATA_BINDING_STORE_ITEM_ID) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aDataBindingStoreItemID = aValue; } else { m_pImpl->m_pContentControl->SetDataBindingStoreItemID(aValue); } } } else if (rPropertyName == UNO_NAME_COLOR) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aColor = aValue; } else { m_pImpl->m_pContentControl->SetColor(aValue); } } } else if (rPropertyName == UNO_NAME_APPEARANCE) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aAppearance = aValue; } else { m_pImpl->m_pContentControl->SetAppearance(aValue); } } } else if (rPropertyName == UNO_NAME_ALIAS) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aAlias = aValue; } else { m_pImpl->m_pContentControl->SetAlias(aValue); } } } else if (rPropertyName == UNO_NAME_TAG) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aTag = aValue; } else { m_pImpl->m_pContentControl->SetTag(aValue); } } } else if (rPropertyName == UNO_NAME_ID) { sal_Int32 nValue = 0; if (rValue >>= nValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_nId = nValue; } else { m_pImpl->m_pContentControl->SetId(nValue); } } } else if (rPropertyName == UNO_NAME_TAB_INDEX) { sal_uInt32 nValue = 0; if (rValue >>= nValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_nTabIndex = nValue; } else { m_pImpl->m_pContentControl->SetTabIndex(nValue); } } } else if (rPropertyName == UNO_NAME_LOCK) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aLock = aValue; } else { m_pImpl->m_pContentControl->SetLock(aValue); } } } else if (rPropertyName == UNO_NAME_MULTILINE) { OUString aValue; if (rValue >>= aValue) { if (m_pImpl->m_bIsDescriptor) { m_pImpl->m_aMultiLine = aValue; } else { m_pImpl->m_pContentControl->SetMultiLine(aValue); } } } else { throw beans::UnknownPropertyException(); } } uno::Any SAL_CALL SwXContentControl::getPropertyValue(const OUString& rPropertyName) { SolarMutexGuard aGuard; uno::Any aRet; if (rPropertyName == UNO_NAME_SHOWING_PLACE_HOLDER) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bShowingPlaceHolder; } else { aRet <<= m_pImpl->m_pContentControl->GetShowingPlaceHolder(); } } else if (rPropertyName == UNO_NAME_CHECKBOX) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bCheckbox; } else { aRet <<= m_pImpl->m_pContentControl->GetCheckbox(); } } else if (rPropertyName == UNO_NAME_CHECKED) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bChecked; } else { aRet <<= m_pImpl->m_pContentControl->GetChecked(); } } else if (rPropertyName == UNO_NAME_CHECKED_STATE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aCheckedState; } else { aRet <<= m_pImpl->m_pContentControl->GetCheckedState(); } } else if (rPropertyName == UNO_NAME_UNCHECKED_STATE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aUncheckedState; } else { aRet <<= m_pImpl->m_pContentControl->GetUncheckedState(); } } else if (rPropertyName == UNO_NAME_LIST_ITEMS) { std::vector aItems; if (m_pImpl->m_bIsDescriptor) { aItems = m_pImpl->m_aListItems; } else { aItems = m_pImpl->m_pContentControl->GetListItems(); } SwContentControlListItem::ItemsToAny(aItems, aRet); } else if (rPropertyName == UNO_NAME_PICTURE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bPicture; } else { aRet <<= m_pImpl->m_pContentControl->GetPicture(); } } else if (rPropertyName == UNO_NAME_DATE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bDate; } else { aRet <<= m_pImpl->m_pContentControl->GetDate(); } } else if (rPropertyName == UNO_NAME_DATE_FORMAT) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aDateFormat; } else { aRet <<= m_pImpl->m_pContentControl->GetDateFormat(); } } else if (rPropertyName == UNO_NAME_DATE_LANGUAGE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aDateLanguage; } else { aRet <<= m_pImpl->m_pContentControl->GetDateLanguage(); } } else if (rPropertyName == UNO_NAME_CURRENT_DATE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aCurrentDate; } else { aRet <<= m_pImpl->m_pContentControl->GetCurrentDate(); } } else if (rPropertyName == UNO_NAME_PLAIN_TEXT) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bPlainText; } else { aRet <<= m_pImpl->m_pContentControl->GetPlainText(); } } else if (rPropertyName == UNO_NAME_COMBO_BOX) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bComboBox; } else { aRet <<= m_pImpl->m_pContentControl->GetComboBox(); } } else if (rPropertyName == UNO_NAME_DROP_DOWN) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_bDropDown; } else { aRet <<= m_pImpl->m_pContentControl->GetDropDown(); } } else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aPlaceholderDocPart; } else { aRet <<= m_pImpl->m_pContentControl->GetCurrentDate(); } } else if (rPropertyName == UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aDataBindingPrefixMappings; } else { aRet <<= m_pImpl->m_pContentControl->GetDataBindingPrefixMappings(); } } else if (rPropertyName == UNO_NAME_DATA_BINDING_XPATH) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aDataBindingXpath; } else { aRet <<= m_pImpl->m_pContentControl->GetDataBindingXpath(); } } else if (rPropertyName == UNO_NAME_DATA_BINDING_STORE_ITEM_ID) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aDataBindingStoreItemID; } else { aRet <<= m_pImpl->m_pContentControl->GetDataBindingStoreItemID(); } } else if (rPropertyName == UNO_NAME_COLOR) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aColor; } else { aRet <<= m_pImpl->m_pContentControl->GetColor(); } } else if (rPropertyName == UNO_NAME_APPEARANCE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aAppearance; } else { aRet <<= m_pImpl->m_pContentControl->GetAppearance(); } } else if (rPropertyName == UNO_NAME_ALIAS) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aAlias; } else { aRet <<= m_pImpl->m_pContentControl->GetAlias(); } } else if (rPropertyName == UNO_NAME_TAG) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aTag; } else { aRet <<= m_pImpl->m_pContentControl->GetTag(); } } else if (rPropertyName == UNO_NAME_DATE_STRING) { if (!m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_pContentControl->GetDateString(); } } else if (rPropertyName == UNO_NAME_ID) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_nId; } else { aRet <<= m_pImpl->m_pContentControl->GetId(); } } else if (rPropertyName == UNO_NAME_TAB_INDEX) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_nTabIndex; } else { aRet <<= m_pImpl->m_pContentControl->GetTabIndex(); } } else if (rPropertyName == UNO_NAME_LOCK) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aLock; } else { aRet <<= m_pImpl->m_pContentControl->GetLock(); } } else if (rPropertyName == UNO_NAME_MULTILINE) { if (m_pImpl->m_bIsDescriptor) { aRet <<= m_pImpl->m_aMultiLine; } else { aRet <<= m_pImpl->m_pContentControl->GetMultiLine(); } } else { throw beans::UnknownPropertyException(); } return aRet; } void SAL_CALL SwXContentControl::addPropertyChangeListener( const OUString& /*rPropertyName*/, const uno::Reference& /*xListener*/) { SAL_WARN("sw.uno", "SwXContentControl::addPropertyChangeListener: not implemented"); } void SAL_CALL SwXContentControl::removePropertyChangeListener( const OUString& /*rPropertyName*/, const uno::Reference& /*xListener*/) { SAL_WARN("sw.uno", "SwXContentControl::removePropertyChangeListener: not implemented"); } void SAL_CALL SwXContentControl::addVetoableChangeListener( const OUString& /*rPropertyName*/, const uno::Reference& /*xListener*/) { SAL_WARN("sw.uno", "SwXContentControl::addVetoableChangeListener: not implemented"); } void SAL_CALL SwXContentControl::removeVetoableChangeListener( const OUString& /*rPropertyName*/, const uno::Reference& /*xListener*/) { SAL_WARN("sw.uno", "SwXContentControl::removeVetoableChangeListener: not implemented"); } // XElementAccess uno::Type SAL_CALL SwXContentControl::getElementType() { return cppu::UnoType::get(); } sal_Bool SAL_CALL SwXContentControl::hasElements() { SolarMutexGuard g; return m_pImpl->m_pContentControl != nullptr; } // XEnumerationAccess uno::Reference SAL_CALL SwXContentControl::createEnumeration() { SolarMutexGuard g; if (m_pImpl->m_bIsDisposed) { throw lang::DisposedException(); } if (m_pImpl->m_bIsDescriptor) { throw uno::RuntimeException("createEnumeration(): not inserted", getXWeak()); } SwTextNode* pTextNode; sal_Int32 nContentControlStart; sal_Int32 nContentControlEnd; bool bSuccess = SetContentRange(pTextNode, nContentControlStart, nContentControlEnd); if (!bSuccess) { SAL_WARN("sw.core", "no pam"); throw lang::DisposedException(); } SwPaM aPam(*pTextNode, nContentControlStart); if (!m_pImpl->m_pTextPortions) { return new SwXTextPortionEnumeration(aPam, GetParentText(), nContentControlStart, nContentControlEnd); } else { return new SwXTextPortionEnumeration(aPam, std::deque(*m_pImpl->m_pTextPortions)); } } SwXContentControls::SwXContentControls(SwDoc* pDoc) : SwUnoCollection(pDoc) { } SwXContentControls::~SwXContentControls() {} sal_Int32 SwXContentControls::getCount() { SolarMutexGuard aGuard; return GetDoc().GetContentControlManager().GetCount(); } uno::Any SwXContentControls::getByIndex(sal_Int32 nIndex) { SolarMutexGuard aGuard; SwContentControlManager& rManager = GetDoc().GetContentControlManager(); if (nIndex < 0 || o3tl::make_unsigned(nIndex) >= rManager.GetCount()) { throw lang::IndexOutOfBoundsException(); } SwTextContentControl* pTextContentControl = rManager.Get(nIndex); const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl(); rtl::Reference xContentControl = SwXContentControl::CreateXContentControl(*rFormatContentControl.GetContentControl()); uno::Any aRet; aRet <<= uno::Reference(xContentControl); return aRet; } uno::Type SwXContentControls::getElementType() { return cppu::UnoType::get(); } sal_Bool SwXContentControls::hasElements() { SolarMutexGuard aGuard; return !GetDoc().GetContentControlManager().IsEmpty(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */