diff options
-rw-r--r-- | offapi/UnoApi_offapi.mk | 2 | ||||
-rw-r--r-- | offapi/com/sun/star/text/XPasteBroadcaster.idl | 42 | ||||
-rw-r--r-- | offapi/com/sun/star/text/XPasteListener.idl | 42 | ||||
-rw-r--r-- | sw/inc/fesh.hxx | 4 | ||||
-rw-r--r-- | sw/inc/unotxdoc.hxx | 10 | ||||
-rw-r--r-- | sw/qa/extras/unowriter/unowriter.cxx | 77 | ||||
-rw-r--r-- | sw/source/core/frmedt/fecopy.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/frmedt/fews.cxx | 14 | ||||
-rw-r--r-- | sw/source/uibase/dochdl/swdtflvr.cxx | 121 | ||||
-rw-r--r-- | sw/source/uibase/inc/swdtflvr.hxx | 6 | ||||
-rw-r--r-- | sw/source/uibase/uno/unotxdoc.cxx | 17 |
11 files changed, 327 insertions, 10 deletions
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 9934fff83b8c..f120c550e8e2 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -3784,6 +3784,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/text,\ XPagePrintable \ XParagraphAppend \ XParagraphCursor \ + XPasteBroadcaster \ + XPasteListener \ XRedline \ XReferenceMarksSupplier \ XRelativeTextContentInsert \ diff --git a/offapi/com/sun/star/text/XPasteBroadcaster.idl b/offapi/com/sun/star/text/XPasteBroadcaster.idl new file mode 100644 index 000000000000..faddd99b6c34 --- /dev/null +++ b/offapi/com/sun/star/text/XPasteBroadcaster.idl @@ -0,0 +1,42 @@ +/* -*- 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/. + */ +#ifndef __com_sun_star_text_XPasteBroadcaster_idl__ +#define __com_sun_star_text_XPasteBroadcaster_idl__ + +#include <com/sun/star/uno/XInterface.idl> +#include <com/sun/star/text/XPasteListener.idl> + +module com { module sun { module star { module text { + +/** allows for adding/removing of paste event listeners. + + @since LibreOffice 6.3 +*/ +interface XPasteBroadcaster : com::sun::star::uno::XInterface +{ + /** Adds an entry to the list of paste listeners. + + @param xListener + The listener to be added. + */ + void addPasteEventListener([in] com::sun::star::text::XPasteListener xListener); + + /** Removes an entry to the list of paste listeners. + + @param xListener + The listener to be removed. + */ + void removePasteEventListener( [in] com::sun::star::text::XPasteListener xListener ); +}; + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/offapi/com/sun/star/text/XPasteListener.idl b/offapi/com/sun/star/text/XPasteListener.idl new file mode 100644 index 000000000000..ce5d663f4ccd --- /dev/null +++ b/offapi/com/sun/star/text/XPasteListener.idl @@ -0,0 +1,42 @@ +/* -*- 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/. + * + */ +#ifndef __com_sun_star_text_XPasteListener_idl__ +#define __com_sun_star_text_XPasteListener_idl__ + +#include <com/sun/star/beans/PropertyValue.idl> +#include <com/sun/star/uno/XInterface.idl> + +module com { module sun { module star { module text { + +/** used to notify listeners about paste events. + + @since LibreOffice 6.3 +*/ +interface XPasteListener : com::sun::star::uno::XInterface +{ + /** Notifies the listener about paste events. + + @param aEvent + The event containing details about the paste. + + <p>The following keys may be used: + <ul> + <li>TextRange</li> + </ul></p> + */ + void notifyPasteEvent([in] sequence< ::com::sun::star::beans::PropertyValue > aEvent); +}; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index 97feecbeeeab..886cb2d7bf39 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -30,6 +30,7 @@ #include <sot/formats.hxx> #include <rtl/ustring.hxx> #include <o3tl/typed_flags_set.hxx> +#include <comphelper/interfacecontainer2.hxx> #include <vector> #include <memory> @@ -204,6 +205,7 @@ private: std::unique_ptr<SdrDropMarkerOverlay> m_pChainTo; std::unique_ptr<SdrDropMarkerOverlay> m_pChainFrom; bool m_bCheckForOLEInCaption; + comphelper::OInterfaceContainerHelper2 m_aPasteListeners; SAL_DLLPRIVATE SwFlyFrame *FindFlyFrame( const css::uno::Reference < css::embed::XEmbeddedObject >& ) const; @@ -561,6 +563,8 @@ public: void Paste( SvStream& rStm, SwPasteSdr nAction, const Point* pPt ); bool Paste( const Graphic &rGrf, const OUString& rURL ); + comphelper::OInterfaceContainerHelper2& GetPasteListeners(); + bool IsAlignPossible() const; void SetCalcFieldValueHdl(Outliner* pOutliner); diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx index bc4d7176fd8a..ae3fb79aa936 100644 --- a/sw/inc/unotxdoc.hxx +++ b/sw/inc/unotxdoc.hxx @@ -62,6 +62,7 @@ #include <cppuhelper/implbase.hxx> #include <vcl/ITiledRenderable.hxx> #include <com/sun/star/tiledrendering/XTiledRenderable.hpp> +#include <com/sun/star/text/XPasteBroadcaster.hpp> #include "unobaseclass.hxx" #include "viewopt.hxx" @@ -122,7 +123,8 @@ typedef cppu::WeakImplHelper css::xforms::XFormsSupplier, css::text::XFlatParagraphIteratorProvider, css::document::XDocumentLanguages, - css::util::XCloneable + css::util::XCloneable, + css::text::XPasteBroadcaster > SwXTextDocumentBaseClass; @@ -379,6 +381,12 @@ public: // css::util::XCloneable virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override; + // css::text::XPasteBroadcaster + void SAL_CALL addPasteEventListener( + const ::css::uno::Reference<::css::text::XPasteListener>& xListener) override; + void SAL_CALL removePasteEventListener( + const ::css::uno::Reference<::css::text::XPasteListener>& xListener) override; + /// @see vcl::ITiledRenderable::paintTile(). virtual void paintTile( VirtualDevice &rDevice, int nOutputWidth, diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx index a0e093dc35d5..77186c1d9350 100644 --- a/sw/qa/extras/unowriter/unowriter.cxx +++ b/sw/qa/extras/unowriter/unowriter.cxx @@ -20,6 +20,7 @@ #include <toolkit/helper/vclunohelper.hxx> #include <wrtsh.hxx> #include <ndtxt.hxx> +#include <swdtflvr.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -28,6 +29,31 @@ using namespace ::com::sun::star::text; namespace { char const DATA_DIRECTORY[] = "/sw/qa/extras/unowriter/data/"; + +/// Listener implementation for testPasteListener. +class PasteListener : public cppu::WeakImplHelper<text::XPasteListener> +{ + OUString m_aString; + +public: + void SAL_CALL notifyPasteEvent(const uno::Sequence<beans::PropertyValue>& rEvent) override; + + OUString& GetString(); +}; + +void PasteListener::notifyPasteEvent(const uno::Sequence<beans::PropertyValue>& rEvent) +{ + comphelper::SequenceAsHashMap aMap(rEvent); + auto it = aMap.find("TextRange"); + if (it != aMap.end()) + { + auto xTextRange = it->second.get<uno::Reference<text::XTextRange>>(); + if (xTextRange.is()) + m_aString = xTextRange->getString(); + } +} + +OUString& PasteListener::GetString() { return m_aString; } } /// Test to assert UNO API call results of Writer. @@ -463,6 +489,57 @@ DECLARE_UNOAPI_TEST_FILE(testRenderablePagePosition, "renderable-page-position.o CPPUNIT_ASSERT_GREATER(aPosition1.Y, aPosition2.Y); } +DECLARE_UNOAPI_TEST(testPasteListener) +{ + loadURL("private:factory/swriter", nullptr); + + // Insert initial string. + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xBodyText(xTextDocument->getText(), uno::UNO_QUERY); + xBodyText->insertString(xBodyText->getStart(), "ABCDEF", false); + + // Add paste listener. + uno::Reference<text::XPasteBroadcaster> xBroadcaster(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XPasteListener> xListener(new PasteListener); + auto pListener = static_cast<PasteListener*>(xListener.get()); + xBroadcaster->addPasteEventListener(xListener); + + // Cut "DE" and then paste it. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false); + rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell); + pTransfer->Cut(); + TransferableDataHelper aHelper(pTransfer.get()); + SwTransferable::Paste(*pWrtShell, aHelper); + // Without working listener registration in place, this test would have + // failed with 'Expected: DE; Actual:', i.e. the paste listener was not + // invoked. + CPPUNIT_ASSERT_EQUAL(OUString("DE"), pListener->GetString()); + + // Make sure that paste did not overwrite anything. + CPPUNIT_ASSERT_EQUAL(OUString("ABCDEF"), xBodyText->getString()); + + // Paste again, this time overwriting "BC". + pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 4, /*bBasicCall=*/false); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false); + pListener->GetString().clear(); + SwTransferable::Paste(*pWrtShell, aHelper); + CPPUNIT_ASSERT_EQUAL(OUString("DE"), pListener->GetString()); + + // Make sure that paste overwrote "BC". + CPPUNIT_ASSERT_EQUAL(OUString("ADEDEF"), xBodyText->getString()); + + // Deregister paste listener, make sure it's not invoked. + xBroadcaster->removePasteEventListener(xListener); + pListener->GetString().clear(); + SwTransferable::Paste(*pWrtShell, aHelper); + CPPUNIT_ASSERT(pListener->GetString().isEmpty()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index 430871b0657b..209c93e50c38 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -1178,6 +1178,8 @@ void SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt1 EndAllAction(); } +comphelper::OInterfaceContainerHelper2& SwFEShell::GetPasteListeners() { return m_aPasteListeners; } + bool SwFEShell::GetDrawObjGraphic( SotClipboardFormatId nFormat, Graphic& rGrf ) const { OSL_ENSURE( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" ); diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx index 00b5a0a12512..d6108875560c 100644 --- a/sw/source/core/frmedt/fews.cxx +++ b/sw/source/core/frmedt/fews.cxx @@ -55,6 +55,18 @@ using namespace com::sun::star; +namespace +{ +/** + * This mutex is only used for the paste listeners, where the solar mutex can't + * be used. + */ +osl::Mutex& GetPasteMutex() +{ + static osl::Mutex aMutex; + return aMutex; +} +} void SwFEShell::EndAllActionAndCall() { @@ -694,12 +706,14 @@ sal_uInt16 SwFEShell::GetCurOutColNum() const SwFEShell::SwFEShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption *pOptions ) : SwEditShell( rDoc, pWindow, pOptions ) , m_bCheckForOLEInCaption(false) + , m_aPasteListeners(GetPasteMutex()) { } SwFEShell::SwFEShell( SwEditShell& rShell, vcl::Window *pWindow ) : SwEditShell( rShell, pWindow ) , m_bCheckForOLEInCaption(false) + , m_aPasteListeners(GetPasteMutex()) { } diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index 67c7d3f30866..c7aa43238729 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp> #include <com/sun/star/embed/NoVisualAreaSizeException.hpp> #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp> +#include <com/sun/star/text/XPasteListener.hpp> #include <svtools/embedtransfer.hxx> #include <svtools/insdlg.hxx> @@ -124,6 +125,7 @@ #include <fmtmeta.hxx> #include <itabenum.hxx> #include <iodetect.hxx> +#include <unotextrange.hxx> #include <vcl/GraphicNativeTransform.hxx> #include <vcl/GraphicNativeMetadata.hxx> @@ -178,17 +180,39 @@ public: void Disconnect( bool bRemoveDataAdvise ); }; +/// Tracks the boundaries of pasted content and notifies listeners. +class SwPasteContext +{ +public: + SwPasteContext(SwWrtShell& rWrtShell); + ~SwPasteContext(); + + void remember(); + void forget(); + +private: + SwWrtShell& m_rWrtShell; + std::unique_ptr<SwPaM> m_pPaM; + sal_Int32 m_nStartContent = 0; +}; + // helper class for Action and Undo enclosing class SwTrnsfrActionAndUndo { SwWrtShell *pSh; public: - SwTrnsfrActionAndUndo( SwWrtShell *pS, bool bDelSel = false) + SwTrnsfrActionAndUndo( SwWrtShell *pS, bool bDelSel = false, SwPasteContext* pContext = nullptr) : pSh( pS ) { pSh->StartUndo( SwUndoId::PASTE_CLIPBOARD ); if( bDelSel ) + { + if (pContext) + pContext->forget(); pSh->DelRight(); + if (pContext) + pContext->remember(); + } pSh->StartAllAction(); } ~SwTrnsfrActionAndUndo() COVERITY_NOEXCEPT_FALSE @@ -1071,6 +1095,82 @@ static uno::Reference < XTransferable > * lcl_getTransferPointer ( uno::Referenc return &xRef; } +SwPasteContext::SwPasteContext(SwWrtShell& rWrtShell) + : m_rWrtShell(rWrtShell) +{ + remember(); +} + +void SwPasteContext::remember() +{ + if (m_rWrtShell.GetPasteListeners().getLength() == 0) + return; + + SwPaM* pCursor = m_rWrtShell.GetCursor(); + if (!pCursor) + return; + + // Set point to the previous node, so it is not moved. + const SwNodeIndex& rNodeIndex = pCursor->GetPoint()->nNode; + m_pPaM.reset(new SwPaM(rNodeIndex, rNodeIndex, 0, -1)); + m_nStartContent = pCursor->GetPoint()->nContent.GetIndex(); +} + +void SwPasteContext::forget() { m_pPaM.reset(nullptr); } + +SwPasteContext::~SwPasteContext() +{ + try + { + if (m_rWrtShell.GetPasteListeners().getLength() == 0) + return; + + if (!m_pPaM) + return; + + SwPaM* pCursor = m_rWrtShell.GetCursor(); + if (!pCursor) + return; + + if (!pCursor->GetPoint()->nNode.GetNode().IsTextNode()) + // Non-text was pasted. + return; + + // Update mark after paste. + *m_pPaM->GetMark() = *pCursor->GetPoint(); + + // Restore point. + ++m_pPaM->GetPoint()->nNode; + SwNode& rNode = m_pPaM->GetNode(); + if (!rNode.IsTextNode()) + // Starting point is no longer text. + return; + + m_pPaM->GetPoint()->nContent.Assign(static_cast<SwContentNode*>(&rNode), m_nStartContent); + + // Invoke the listeners. + beans::PropertyValue aPropertyValue; + aPropertyValue.Name = "TextRange"; + const uno::Reference<text::XTextRange> xTextRange = SwXTextRange::CreateXTextRange( + *m_pPaM->GetDoc(), *m_pPaM->GetPoint(), m_pPaM->GetMark()); + aPropertyValue.Value <<= xTextRange; + uno::Sequence<beans::PropertyValue> aEvent{ aPropertyValue }; + + comphelper::OInterfaceIteratorHelper2 it(m_rWrtShell.GetPasteListeners()); + while (it.hasMoreElements()) + { + uno::Reference<text::XPasteListener> xListener(it.next(), UNO_QUERY); + if (xListener.is()) + xListener->notifyPasteEvent(aEvent); + } + } + catch (const uno::Exception& rException) + { + SAL_WARN("sw", + "SwPasteContext::~SwPasteContext: uncaught exception: " << rException.Message); + } +} + bool SwTransferable::IsPaste( const SwWrtShell& rSh, const TransferableDataHelper& rData ) { @@ -1114,6 +1214,8 @@ bool SwTransferable::IsPaste( const SwWrtShell& rSh, bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType) { + SwPasteContext aPasteContext(rSh); + sal_uInt8 nEventAction, nAction=0; SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh ); SotClipboardFormatId nFormat = SotClipboardFormatId::NONE; @@ -1189,7 +1291,7 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt if (bInsertOleTableInTable && EXCHG_OUT_ACTION_INSERT_STRING == nAction) { bool bPasted = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat, - nDestination, false, false, nullptr, 0, false, nAnchorType ); + nDestination, false, false, nullptr, 0, false, nAnchorType, &aPasteContext ); if (bPasted && rSh.DoesUndo()) { SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher(); @@ -1204,7 +1306,7 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt return EXCHG_INOUT_ACTION_NONE != nAction && SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat, - nDestination, false, false, nullptr, 0, false, nAnchorType ); + nDestination, false, false, nullptr, 0, false, nAnchorType, &aPasteContext ); } bool SwTransferable::PasteData( TransferableDataHelper& rData, @@ -1213,7 +1315,8 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, SotExchangeDest nDestination, bool bIsPasteFormat, bool bIsDefault, const Point* pPt, sal_Int8 nDropAction, - bool bPasteSelection, RndStdIds nAnchorType ) + bool bPasteSelection, RndStdIds nAnchorType, + SwPasteContext* pContext ) { SwWait aWait( *rSh.GetView().GetDocShell(), false ); std::unique_ptr<SwTrnsfrActionAndUndo, o3tl::default_delete<SwTrnsfrActionAndUndo>> pAction; @@ -1272,7 +1375,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, if( bDelSel ) // #i34830# - pAction.reset(new SwTrnsfrActionAndUndo( &rSh, true )); + pAction.reset(new SwTrnsfrActionAndUndo(&rSh, true, pContext)); } SwTransferable *pTrans=nullptr, *pTunneledTrans=GetSwTransferable( rData ); @@ -1319,7 +1422,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, EXCHG_OUT_ACTION_INSERT_PRIVATE == nAction ) { // then internal paste - bRet = pTunneledTrans->PrivatePaste( rSh ); + bRet = pTunneledTrans->PrivatePaste(rSh, pContext); } else if( EXCHG_INOUT_ACTION_NONE != nAction ) { @@ -3276,7 +3379,7 @@ bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc) } -bool SwTransferable::PrivatePaste( SwWrtShell& rShell ) +bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext) { // first, ask for the SelectionType, then action-bracketing !!!! // (otherwise it's not pasted into a TableSelection!!!) @@ -3295,7 +3398,11 @@ bool SwTransferable::PrivatePaste( SwWrtShell& rShell ) { bKillPaMs = true; rShell.SetRetainSelection( true ); + if (pContext) + pContext->forget(); rShell.DelRight(); + if (pContext) + pContext->remember(); // when a Fly was selected, a valid cursor position has to be found now // (parked Cursor!) if( ( SelectionType::Frame | SelectionType::Graphic | diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx index f9dc71623477..c8015d1955c8 100644 --- a/sw/source/uibase/inc/swdtflvr.hxx +++ b/sw/source/uibase/inc/swdtflvr.hxx @@ -41,6 +41,7 @@ class SwWrtShell; class SvxClipboardFormatItem; class SwFrameShell; class SwView_Impl; +class SwPasteContext; enum class SwPasteSdr; enum class TransferBufferType : sal_uInt16 @@ -133,7 +134,7 @@ class SW_DLLPUBLIC SwTransferable : public TransferableHelper bool PrivateDrop( SwWrtShell& rSh, const Point& rDragPt, bool bMove, bool bIsXSelection ); - bool PrivatePaste( SwWrtShell& rShell ); + bool PrivatePaste( SwWrtShell& rShell, SwPasteContext* pContext = nullptr ); void SetDataForDragAndDrop( const Point& rSttPos ); @@ -181,7 +182,8 @@ public: SotExchangeDest nDestination, bool bIsPasteFormat, bool bIsDefault, const Point* pDDPos = nullptr, sal_Int8 nDropAction = 0, - bool bPasteSelection = false, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA ); + bool bPasteSelection = false, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA, + SwPasteContext* pContext = nullptr ); static bool IsPasteSpecial( const SwWrtShell& rWrtShell, const TransferableDataHelper& ); diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx index a1324b36422d..9f2e45c766f8 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -3183,6 +3183,23 @@ uno::Reference< util::XCloneable > SwXTextDocument::createClone( ) return uno::Reference< util::XCloneable >( xNewModel, UNO_QUERY ); } +void SwXTextDocument::addPasteEventListener(const uno::Reference<text::XPasteListener>& xListener) +{ + SolarMutexGuard aGuard; + + if (IsValid() && xListener.is()) + pDocShell->GetWrtShell()->GetPasteListeners().addInterface(xListener); +} + +void SwXTextDocument::removePasteEventListener( + const uno::Reference<text::XPasteListener>& xListener) +{ + SolarMutexGuard aGuard; + + if (IsValid() && xListener.is()) + pDocShell->GetWrtShell()->GetPasteListeners().removeInterface(xListener); +} + void SwXTextDocument::paintTile( VirtualDevice &rDevice, int nOutputWidth, int nOutputHeight, int nTilePosX, int nTilePosY, |