/* -*- 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 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; uno::Reference CreateCursor() 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 uno::Reference SAL_CALL createTextCursor() override; uno::Reference SAL_CALL createTextCursorByRange(const uno::Reference& xTextPosition) override; }; } SwXContentControlText::SwXContentControlText(SwDoc& rDoc, SwXContentControl& rContentControl) : SwXText(&rDoc, CursorType::ContentControl) , m_rContentControl(rContentControl) { } const SwStartNode* SwXContentControlText::GetStartNode() const { auto pParent = dynamic_cast(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)); } uno::Reference SwXContentControlText::CreateCursor() { uno::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 = static_cast( new SwXTextCursor(*GetDoc(), &m_rContentControl, CursorType::ContentControl, aPos)); } } return xRet; } uno::Sequence SAL_CALL SwXContentControlText::getImplementationId() { return css::uno::Sequence(); } // XText uno::Reference SAL_CALL SwXContentControlText::createTextCursor() { return CreateCursor(); } uno::Reference SAL_CALL SwXContentControlText::createTextCursorByRange( const uno::Reference& xTextPosition) { const uno::Reference xCursor(CreateCursor()); 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: uno::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; 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; OUString m_aPlaceholderDocPart; OUString m_aDataBindingPrefixMappings; OUString m_aDataBindingXpath; OUString m_aDataBindingStoreItemID; OUString m_aColor; Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* pContentControl, const uno::Reference& xParentText, std::unique_ptr pPortions) : m_pTextPortions(std::move(pPortions)) , m_bIsDisposed(false) , m_bIsDescriptor(pContentControl == nullptr) , m_xParentText(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) { 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 uno::Reference& SwXContentControl::GetParentText() const { return m_pImpl->m_xParentText; } SwXContentControl::SwXContentControl(SwDoc* pDoc, SwContentControl* pContentControl, const 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() {} uno::Reference SwXContentControl::CreateXContentControl(SwDoc& rDoc) { rtl::Reference xContentControl(new SwXContentControl(&rDoc)); uno::Reference xTextContent(xContentControl); xContentControl->m_pImpl->m_wThis = xTextContent; return xContentControl; } uno::Reference SwXContentControl::CreateXContentControl(SwContentControl& rContentControl, const uno::Reference& xParent, std::unique_ptr&& pPortions) { // re-use existing SwXContentControl uno::Reference xContentControl(rContentControl.GetXContentControl()); if (xContentControl.is()) { if (pPortions) { // Set the cache in the XContentControl to the given portions. auto pXContentControl = comphelper::getFromUnoTunnel(xContentControl); assert(pXContentControl); // 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. pXContentControl->m_pImpl->m_pTextPortions = std::move(pPortions); if (pXContentControl->m_pImpl->m_xParentText.get() != xParent.get()) { SAL_WARN("sw.uno", "SwXContentControl with different parent"); pXContentControl->m_pImpl->m_xParentText.set(xParent); } } return xContentControl; } // Create new SwXContentControl. SwTextNode* pTextNode = rContentControl.GetTextNode(); if (!pTextNode) { SAL_WARN("sw.uno", "CreateXContentControl: no text node"); return nullptr; } 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.set(sw::CreateParentXText(pTextNode->GetDoc(), aPos)); } if (!xParentText.is()) { return nullptr; } rtl::Reference pXContentControl = new SwXContentControl( &pTextNode->GetDoc(), &rContentControl, xParentText, std::move(pPortions)); xContentControl.set(pXContentControl); rContentControl.SetXContentControl(xContentControl); pXContentControl->m_pImpl->m_wThis = xContentControl; 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; } const uno::Sequence& SwXContentControl::getUnoTunnelId() { static const comphelper::UnoIdInit theSwXContentControlUnoTunnelId; return theSwXContentControlUnoTunnelId.getSeq(); } // XUnoTunnel sal_Int64 SAL_CALL SwXContentControl::getSomething(const uno::Sequence& rId) { return comphelper::getSomethingImpl(rId, this); } // 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(static_cast<::cppu::OWeakObject&>(*this)); 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", static_cast<::cppu::OWeakObject*>(this)); } uno::Reference xRangeTunnel(xTextRange, uno::UNO_QUERY); if (!xRangeTunnel.is()) { throw lang::IllegalArgumentException( "SwXContentControl::AttachImpl(): argument is no XUnoTunnel", static_cast<::cppu::OWeakObject*>(this), 0); } SwXTextRange* pRange = comphelper::getFromUnoTunnel(xRangeTunnel); OTextCursorHelper* pCursor = pRange ? nullptr : comphelper::getFromUnoTunnel(xRangeTunnel); if (!pRange && !pCursor) { throw lang::IllegalArgumentException( "SwXContentControl::AttachImpl(): argument not supported type", static_cast<::cppu::OWeakObject*>(this), 0); } SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor->GetDoc(); if (!pDoc) { throw lang::IllegalArgumentException( "SwXContentControl::AttachImpl(): argument has no SwDoc", static_cast<::cppu::OWeakObject*>(this), 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->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); 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", static_cast<::cppu::OWeakObject*>(this), 1); } if (!pTextAttr) { SAL_WARN("sw.core", "content control inserted, but has no text attribute?"); throw uno::RuntimeException( "SwXContentControl::AttachImpl(): cannot create content control", static_cast<::cppu::OWeakObject*>(this)); } m_pImpl->EndListeningAll(); m_pImpl->m_pContentControl = pContentControl.get(); m_pImpl->StartListening(pContentControl->GetNotifier()); pContentControl->SetXContentControl(uno::Reference(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", static_cast<::cppu::OWeakObject*>(this)); } 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", static_cast<::cppu::OWeakObject*>(this)); } 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; } else { m_pImpl->m_pContentControl->SetListItems(aItems); } } 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_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 { 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_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 { 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", static_cast<::cppu::OWeakObject*>(this)); } 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)); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */