1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <unotools/eventlisteneradapter.hxx>
26 #include <osl/diagnose.h>
27 #include <cppuhelper/implbase.hxx>
28 #include <rtl/ref.hxx>
33 using namespace ::com::sun::star::uno
;
34 using namespace ::com::sun::star::lang
;
36 //= OEventListenerImpl
38 class OEventListenerImpl
: public ::cppu::WeakImplHelper
< XEventListener
>
41 OEventListenerAdapter
* m_pAdapter
;
42 Reference
< XEventListener
> m_xKeepMeAlive
;
43 // imagine an implementation of XComponent which holds it's listeners with a weak reference ...
44 // would be very bad if we don't hold ourself
45 Reference
< XComponent
> m_xComponent
;
48 OEventListenerImpl( OEventListenerAdapter
* _pAdapter
, const Reference
< XComponent
>& _rxComp
);
51 const Reference
< XComponent
>& getComponent() const { return m_xComponent
; }
54 virtual void SAL_CALL
disposing( const EventObject
& _rSource
) override
;
57 OEventListenerImpl::OEventListenerImpl( OEventListenerAdapter
* _pAdapter
, const Reference
< XComponent
>& _rxComp
)
58 :m_pAdapter(_pAdapter
)
60 OSL_ENSURE(m_pAdapter
, "OEventListenerImpl::OEventListenerImpl: invalid adapter!");
61 // no checks of _rxComp !!
62 // (OEventListenerAdapter is responsible for this)
64 // just in case addEventListener throws an exception ... don't initialize m_xKeepMeAlive before this
66 Reference
< XEventListener
> xMeMyselfAndI
= this;
67 _rxComp
->addEventListener(xMeMyselfAndI
);
69 m_xComponent
= _rxComp
;
70 m_xKeepMeAlive
= std::move(xMeMyselfAndI
);
73 void OEventListenerImpl::dispose()
75 if (m_xComponent
.is())
77 if (m_xKeepMeAlive
.is())
78 m_xComponent
->removeEventListener(m_xKeepMeAlive
);
80 m_xKeepMeAlive
.clear();
84 void SAL_CALL
OEventListenerImpl::disposing( const EventObject
& _rSource
)
86 Reference
< XEventListener
> xDeleteUponLeaving
= m_xKeepMeAlive
;
87 m_xKeepMeAlive
.clear();
89 m_pAdapter
->_disposing(_rSource
);
92 //= OEventListenerAdapterImpl
94 struct OEventListenerAdapterImpl
97 std::vector
< rtl::Reference
<OEventListenerImpl
> > aListeners
;
100 //= OEventListenerAdapter
102 OEventListenerAdapter::OEventListenerAdapter()
103 :m_pImpl(new OEventListenerAdapterImpl
)
107 OEventListenerAdapter::~OEventListenerAdapter()
109 stopAllComponentListening( );
112 void OEventListenerAdapter::stopComponentListening( const css::uno::Reference
< css::lang::XComponent
>& _rxComp
)
114 if ( m_pImpl
->aListeners
.empty() )
117 auto it
= m_pImpl
->aListeners
.begin();
120 rtl::Reference
<OEventListenerImpl
>& pListenerImpl
= *it
;
121 if ((pListenerImpl
->getComponent().get() == _rxComp
.get()) || (pListenerImpl
->getComponent() == _rxComp
))
123 pListenerImpl
->dispose();
124 it
= m_pImpl
->aListeners
.erase( it
);
129 while ( it
!= m_pImpl
->aListeners
.end() );
132 void OEventListenerAdapter::stopAllComponentListening( )
134 for ( const auto & i
: m_pImpl
->aListeners
)
138 m_pImpl
->aListeners
.clear();
141 void OEventListenerAdapter::startComponentListening( const Reference
< XComponent
>& _rxComp
)
145 OSL_FAIL("OEventListenerAdapter::startComponentListening: invalid component!");
149 rtl::Reference
<OEventListenerImpl
> pListenerImpl
= new OEventListenerImpl(this, _rxComp
);
150 m_pImpl
->aListeners
.emplace_back(pListenerImpl
);
155 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */