1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/propmultiplex.hxx>
31 #include <osl/diagnose.h>
32 
33 //.........................................................................
34 namespace comphelper
35 {
36 //.........................................................................
37 
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::lang;
40 using namespace ::com::sun::star::beans;
41 
42 //========================================================================
43 //= OPropertyChangeListener
44 //========================================================================
45 //------------------------------------------------------------------------
46 OPropertyChangeListener::~OPropertyChangeListener()
47 {
48 	if (m_pAdapter)
49 		m_pAdapter->dispose();
50 }
51 
52 //------------------------------------------------------------------
53 void OPropertyChangeListener::_disposing(const EventObject&) throw( RuntimeException)
54 {
55 	// nothing to do here
56 }
57 
58 //------------------------------------------------------------------
59 void OPropertyChangeListener::disposeAdapter()
60 {
61 	if ( m_pAdapter )
62 		m_pAdapter->dispose();
63 
64     // will automatically set a new adapter
65     OSL_ENSURE( !m_pAdapter, "OPropertyChangeListener::disposeAdapter: what did dispose do?" );
66 }
67 
68 //------------------------------------------------------------------
69 void OPropertyChangeListener::setAdapter(OPropertyChangeMultiplexer* pAdapter)
70 {
71 	if (m_pAdapter)
72 	{
73 		::osl::MutexGuard aGuard(m_rMutex);
74 		m_pAdapter->release();
75 		m_pAdapter = NULL;
76 	}
77 
78 	if (pAdapter)
79 	{
80 		::osl::MutexGuard aGuard(m_rMutex);
81 		m_pAdapter = pAdapter;
82 		m_pAdapter->acquire();
83 	}
84 }
85 
86 //========================================================================
87 //= OPropertyChangeMultiplexer
88 //========================================================================
89 //------------------------------------------------------------------
90 OPropertyChangeMultiplexer::OPropertyChangeMultiplexer(OPropertyChangeListener* _pListener, const  Reference< XPropertySet>& _rxSet, sal_Bool _bAutoReleaseSet)
91 			:m_xSet(_rxSet)
92 			,m_pListener(_pListener)
93 			,m_nLockCount(0)
94 			,m_bListening(sal_False)
95 			,m_bAutoSetRelease(_bAutoReleaseSet)
96 {
97 	m_pListener->setAdapter(this);
98 }
99 
100 //------------------------------------------------------------------
101 OPropertyChangeMultiplexer::~OPropertyChangeMultiplexer()
102 {
103 }
104 
105 //------------------------------------------------------------------
106 void OPropertyChangeMultiplexer::lock()
107 {
108 	++m_nLockCount;
109 }
110 
111 //------------------------------------------------------------------
112 void OPropertyChangeMultiplexer::unlock()
113 {
114 	--m_nLockCount;
115 }
116 
117 //------------------------------------------------------------------
118 void OPropertyChangeMultiplexer::dispose()
119 {
120 	if (m_bListening)
121 	{
122 		Reference< XPropertyChangeListener> xPreventDelete(this);
123 
124 		const ::rtl::OUString* pProperties = m_aProperties.getConstArray();
125 		for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i, ++pProperties)
126 			m_xSet->removePropertyChangeListener(*pProperties, static_cast< XPropertyChangeListener*>(this));
127 
128 		m_pListener->setAdapter(NULL);
129 
130 		m_pListener = NULL;
131 		m_bListening = sal_False;
132 
133 		if (m_bAutoSetRelease)
134 			m_xSet = NULL;
135 	}
136 }
137 
138 // XEventListener
139 //------------------------------------------------------------------
140 void SAL_CALL OPropertyChangeMultiplexer::disposing( const  EventObject& _rSource) throw( RuntimeException)
141 {
142 	if (m_pListener)
143 	{
144 		 // tell the listener
145 		if (!locked())
146 			m_pListener->_disposing(_rSource);
147 		// disconnect the listener
148 		if (m_pListener)	// may have been reset whilest calling into _disposing
149 			m_pListener->setAdapter(NULL);
150 	}
151 
152 	m_pListener = NULL;
153 	m_bListening = sal_False;
154 
155 	if (m_bAutoSetRelease)
156 		m_xSet = NULL;
157 }
158 
159 // XPropertyChangeListener
160 //------------------------------------------------------------------
161 void SAL_CALL OPropertyChangeMultiplexer::propertyChange( const  PropertyChangeEvent& _rEvent ) throw( RuntimeException)
162 {
163 	if (m_pListener && !locked())
164 		m_pListener->_propertyChanged(_rEvent);
165 }
166 
167 //------------------------------------------------------------------
168 void OPropertyChangeMultiplexer::addProperty(const ::rtl::OUString& _sPropertyName)
169 {
170 	if (m_xSet.is())
171 	{
172 		m_xSet->addPropertyChangeListener(_sPropertyName, static_cast< XPropertyChangeListener*>(this));
173 		m_aProperties.realloc(m_aProperties.getLength() + 1);
174 		m_aProperties.getArray()[m_aProperties.getLength()-1] = _sPropertyName;
175 		m_bListening = sal_True;
176 	}
177 }
178 
179 //.........................................................................
180 }
181 //.........................................................................
182 
183