1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <comphelper/propmultiplex.hxx>
27 #include <osl/diagnose.h>
28 
29 //.........................................................................
30 namespace comphelper
31 {
32 //.........................................................................
33 
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star::lang;
36 using namespace ::com::sun::star::beans;
37 
38 //========================================================================
39 //= OPropertyChangeListener
40 //========================================================================
41 //------------------------------------------------------------------------
~OPropertyChangeListener()42 OPropertyChangeListener::~OPropertyChangeListener()
43 {
44 	if (m_pAdapter)
45 		m_pAdapter->dispose();
46 }
47 
48 //------------------------------------------------------------------
_disposing(const EventObject &)49 void OPropertyChangeListener::_disposing(const EventObject&) throw( RuntimeException)
50 {
51 	// nothing to do here
52 }
53 
54 //------------------------------------------------------------------
disposeAdapter()55 void OPropertyChangeListener::disposeAdapter()
56 {
57 	if ( m_pAdapter )
58 		m_pAdapter->dispose();
59 
60     // will automatically set a new adapter
61     OSL_ENSURE( !m_pAdapter, "OPropertyChangeListener::disposeAdapter: what did dispose do?" );
62 }
63 
64 //------------------------------------------------------------------
setAdapter(OPropertyChangeMultiplexer * pAdapter)65 void OPropertyChangeListener::setAdapter(OPropertyChangeMultiplexer* pAdapter)
66 {
67 	if (m_pAdapter)
68 	{
69 		::osl::MutexGuard aGuard(m_rMutex);
70 		m_pAdapter->release();
71 		m_pAdapter = NULL;
72 	}
73 
74 	if (pAdapter)
75 	{
76 		::osl::MutexGuard aGuard(m_rMutex);
77 		m_pAdapter = pAdapter;
78 		m_pAdapter->acquire();
79 	}
80 }
81 
82 //========================================================================
83 //= OPropertyChangeMultiplexer
84 //========================================================================
85 //------------------------------------------------------------------
OPropertyChangeMultiplexer(OPropertyChangeListener * _pListener,const Reference<XPropertySet> & _rxSet,sal_Bool _bAutoReleaseSet)86 OPropertyChangeMultiplexer::OPropertyChangeMultiplexer(OPropertyChangeListener* _pListener, const  Reference< XPropertySet>& _rxSet, sal_Bool _bAutoReleaseSet)
87 			:m_xSet(_rxSet)
88 			,m_pListener(_pListener)
89 			,m_nLockCount(0)
90 			,m_bListening(sal_False)
91 			,m_bAutoSetRelease(_bAutoReleaseSet)
92 {
93 	m_pListener->setAdapter(this);
94 }
95 
96 //------------------------------------------------------------------
~OPropertyChangeMultiplexer()97 OPropertyChangeMultiplexer::~OPropertyChangeMultiplexer()
98 {
99 }
100 
101 //------------------------------------------------------------------
lock()102 void OPropertyChangeMultiplexer::lock()
103 {
104 	++m_nLockCount;
105 }
106 
107 //------------------------------------------------------------------
unlock()108 void OPropertyChangeMultiplexer::unlock()
109 {
110 	--m_nLockCount;
111 }
112 
113 //------------------------------------------------------------------
dispose()114 void OPropertyChangeMultiplexer::dispose()
115 {
116 	if (m_bListening)
117 	{
118 		Reference< XPropertyChangeListener> xPreventDelete(this);
119 
120 		const ::rtl::OUString* pProperties = m_aProperties.getConstArray();
121 		for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i, ++pProperties)
122 			m_xSet->removePropertyChangeListener(*pProperties, static_cast< XPropertyChangeListener*>(this));
123 
124 		m_pListener->setAdapter(NULL);
125 
126 		m_pListener = NULL;
127 		m_bListening = sal_False;
128 
129 		if (m_bAutoSetRelease)
130 			m_xSet = NULL;
131 	}
132 }
133 
134 // XEventListener
135 //------------------------------------------------------------------
disposing(const EventObject & _rSource)136 void SAL_CALL OPropertyChangeMultiplexer::disposing( const  EventObject& _rSource) throw( RuntimeException)
137 {
138 	if (m_pListener)
139 	{
140 		 // tell the listener
141 		if (!locked())
142 			m_pListener->_disposing(_rSource);
143 		// disconnect the listener
144 		if (m_pListener)	// may have been reset whilest calling into _disposing
145 			m_pListener->setAdapter(NULL);
146 	}
147 
148 	m_pListener = NULL;
149 	m_bListening = sal_False;
150 
151 	if (m_bAutoSetRelease)
152 		m_xSet = NULL;
153 }
154 
155 // XPropertyChangeListener
156 //------------------------------------------------------------------
propertyChange(const PropertyChangeEvent & _rEvent)157 void SAL_CALL OPropertyChangeMultiplexer::propertyChange( const  PropertyChangeEvent& _rEvent ) throw( RuntimeException)
158 {
159 	if (m_pListener && !locked())
160 		m_pListener->_propertyChanged(_rEvent);
161 }
162 
163 //------------------------------------------------------------------
addProperty(const::rtl::OUString & _sPropertyName)164 void OPropertyChangeMultiplexer::addProperty(const ::rtl::OUString& _sPropertyName)
165 {
166 	if (m_xSet.is())
167 	{
168 		m_xSet->addPropertyChangeListener(_sPropertyName, static_cast< XPropertyChangeListener*>(this));
169 		m_aProperties.realloc(m_aProperties.getLength() + 1);
170 		m_aProperties.getArray()[m_aProperties.getLength()-1] = _sPropertyName;
171 		m_bListening = sal_True;
172 	}
173 }
174 
175 //.........................................................................
176 }
177 //.........................................................................
178 
179