/* -*- 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 namespace com::sun::star::container { class XNameContainer; } using namespace ::com::sun::star::uno; using namespace ::com::sun::star::text; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; namespace sd { namespace { class UndoTextAPIChanged : public SdrUndoAction { public: UndoTextAPIChanged( SdrModel& rModel, TextApiObject* pTextObj ); virtual void Undo() override; virtual void Redo() override; protected: std::optional mpOldText; std::optional mpNewText; rtl::Reference< TextApiObject > mxTextObj; }; } UndoTextAPIChanged::UndoTextAPIChanged(SdrModel& rModel, TextApiObject* pTextObj ) : SdrUndoAction( rModel ) , mpOldText( pTextObj->CreateText() ) , mxTextObj( pTextObj ) { } void UndoTextAPIChanged::Undo() { if( !mpNewText ) mpNewText = mxTextObj->CreateText(); mxTextObj->SetText( *mpOldText ); } void UndoTextAPIChanged::Redo() { if( mpNewText ) { mxTextObj->SetText( *mpNewText ); } } namespace { struct TextAPIEditSource_Impl { SdDrawDocument* mpDoc; Outliner* mpOutliner; SvxOutlinerForwarder* mpTextForwarder; }; } class TextAPIEditSource : public SvxEditSource { // refcounted std::shared_ptr m_xImpl; virtual std::unique_ptr Clone() const override; virtual SvxTextForwarder* GetTextForwarder() override; virtual void UpdateData() override; explicit TextAPIEditSource( const TextAPIEditSource& rSource ); public: explicit TextAPIEditSource(SdDrawDocument* pDoc); void Dispose(); void SetText( OutlinerParaObject const & rText ); std::optional CreateText(); OUString GetText() const; SdDrawDocument* GetDoc() { return m_xImpl->mpDoc; } }; static const SvxItemPropertySet* ImplGetSdTextPortionPropertyMap() { static const SfxItemPropertyMapEntry aSdTextPortionPropertyEntries[] = { SVX_UNOEDIT_CHAR_PROPERTIES, SVX_UNOEDIT_FONT_PROPERTIES, SVX_UNOEDIT_OUTLINER_PROPERTIES, SVX_UNOEDIT_PARA_PROPERTIES, {u"TextField", EE_FEATURE_FIELD, cppu::UnoType::get(), PropertyAttribute::READONLY, 0 }, {u"TextPortionType", WID_PORTIONTYPE, ::cppu::UnoType::get(), PropertyAttribute::READONLY, 0 }, {u"TextUserDefinedAttributes", EE_CHAR_XMLATTRIBS, cppu::UnoType::get(), 0, 0}, {u"ParaUserDefinedAttributes", EE_PARA_XMLATTRIBS, cppu::UnoType::get(), 0, 0}, { u"", 0, css::uno::Type(), 0, 0 } }; static SvxItemPropertySet aSdTextPortionPropertyMap( aSdTextPortionPropertyEntries, SdrObject::GetGlobalDrawObjectItemPool() ); return &aSdTextPortionPropertyMap; } TextApiObject::TextApiObject( std::unique_ptr pEditSource ) : SvxUnoText( pEditSource.get(), ImplGetSdTextPortionPropertyMap(), Reference < XText >() ) , mpSource(std::move(pEditSource)) { } TextApiObject::~TextApiObject() noexcept { dispose(); } rtl::Reference< TextApiObject > TextApiObject::create( SdDrawDocument* pDoc ) { rtl::Reference< TextApiObject > xRet( new TextApiObject( std::make_unique( pDoc ) ) ); return xRet; } void TextApiObject::dispose() { if( mpSource ) { mpSource->Dispose(); mpSource.reset(); } } std::optional TextApiObject::CreateText() { return mpSource->CreateText(); } void TextApiObject::SetText( OutlinerParaObject const & rText ) { SdrModel* pModel = mpSource->GetDoc(); if( pModel && pModel->IsUndoEnabled() ) pModel->AddUndo( std::make_unique( *pModel, this ) ); mpSource->SetText( rText ); maSelection.nStartPara = EE_PARA_MAX_COUNT; } OUString TextApiObject::GetText() const { return mpSource->GetText(); } TextApiObject* TextApiObject::getImplementation( const css::uno::Reference< css::text::XText >& xText ) { TextApiObject* pImpl = dynamic_cast< TextApiObject* >( xText.get() ); if( !pImpl ) pImpl = dynamic_cast< TextApiObject* >( comphelper::getFromUnoTunnel( xText ) ); return pImpl; } TextAPIEditSource::TextAPIEditSource(const TextAPIEditSource& rSource) : SvxEditSource(*this) , m_xImpl(rSource.m_xImpl) // shallow copy; uses internal refcounting { } std::unique_ptr TextAPIEditSource::Clone() const { return std::unique_ptr(new TextAPIEditSource( *this )); } void TextAPIEditSource::UpdateData() { // data is kept in outliner all the time } TextAPIEditSource::TextAPIEditSource(SdDrawDocument* pDoc) : m_xImpl(std::make_shared()) { m_xImpl->mpDoc = pDoc; m_xImpl->mpOutliner = nullptr; m_xImpl->mpTextForwarder = nullptr; } void TextAPIEditSource::Dispose() { m_xImpl->mpDoc=nullptr; delete m_xImpl->mpTextForwarder; m_xImpl->mpTextForwarder = nullptr; delete m_xImpl->mpOutliner; m_xImpl->mpOutliner = nullptr; } SvxTextForwarder* TextAPIEditSource::GetTextForwarder() { if(!m_xImpl->mpDoc) return nullptr; // mpDoc == 0 can be used to flag this as disposed if (!m_xImpl->mpOutliner) { //init draw model first m_xImpl->mpOutliner = new SdOutliner(m_xImpl->mpDoc, OutlinerMode::TextObject); SdDrawDocument::SetCalcFieldValueHdl(m_xImpl->mpOutliner); } if (!m_xImpl->mpTextForwarder) m_xImpl->mpTextForwarder = new SvxOutlinerForwarder(*m_xImpl->mpOutliner, false); return m_xImpl->mpTextForwarder; } void TextAPIEditSource::SetText( OutlinerParaObject const & rText ) { if (m_xImpl->mpDoc) { if (!m_xImpl->mpOutliner) { //init draw model first m_xImpl->mpOutliner = new SdOutliner(m_xImpl->mpDoc, OutlinerMode::TextObject); SdDrawDocument::SetCalcFieldValueHdl(m_xImpl->mpOutliner); } m_xImpl->mpOutliner->SetText( rText ); } } std::optional TextAPIEditSource::CreateText() { if (m_xImpl->mpDoc && m_xImpl->mpOutliner) return m_xImpl->mpOutliner->CreateParaObject(); else return std::nullopt; } OUString TextAPIEditSource::GetText() const { if (m_xImpl->mpDoc && m_xImpl->mpOutliner) return m_xImpl->mpOutliner->GetEditEngine().GetText(); else return OUString(); } } // namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */