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 
31 #include <comphelper/SelectionMultiplex.hxx>
32 #include <osl/diagnose.h>
33 
34 //.........................................................................
35 namespace comphelper
36 {
37 //.........................................................................
38 
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::view;
42 
43 //========================================================================
44 //= OSelectionChangeListener
45 //========================================================================
46 //------------------------------------------------------------------------
47 OSelectionChangeListener::~OSelectionChangeListener()
48 {
49 	if (m_pAdapter)
50 		m_pAdapter->dispose();
51 }
52 
53 //------------------------------------------------------------------
54 void OSelectionChangeListener::_disposing(const EventObject&) throw( RuntimeException)
55 {
56 	// nothing to do here
57 }
58 
59 //------------------------------------------------------------------
60 void OSelectionChangeListener::disposeAdapter()
61 {
62 	if ( m_pAdapter )
63 		m_pAdapter->dispose();
64 
65     // will automatically set a new adapter
66     OSL_ENSURE( !m_pAdapter, "OSelectionChangeListener::disposeAdapter: what did dispose do?" );
67 }
68 
69 //------------------------------------------------------------------
70 void OSelectionChangeListener::setAdapter(OSelectionChangeMultiplexer* pAdapter)
71 {
72 	if (m_pAdapter)
73 	{
74 		::osl::MutexGuard aGuard(m_rMutex);
75 		m_pAdapter->release();
76 		m_pAdapter = NULL;
77 	}
78 
79 	if (pAdapter)
80 	{
81 		::osl::MutexGuard aGuard(m_rMutex);
82 		m_pAdapter = pAdapter;
83 		m_pAdapter->acquire();
84 	}
85 }
86 
87 //========================================================================
88 //= OSelectionChangeMultiplexer
89 //========================================================================
90 //------------------------------------------------------------------
91 OSelectionChangeMultiplexer::OSelectionChangeMultiplexer(OSelectionChangeListener* _pListener, const  Reference< XSelectionSupplier>& _rxSet, sal_Bool _bAutoReleaseSet)
92 			:m_xSet(_rxSet)
93 			,m_pListener(_pListener)
94 			,m_nLockCount(0)
95 			,m_bListening(sal_False)
96 			,m_bAutoSetRelease(_bAutoReleaseSet)
97 {
98 	m_pListener->setAdapter(this);
99     osl_incrementInterlockedCount(&m_refCount);
100     {
101         Reference< XSelectionChangeListener> xPreventDelete(this);
102         m_xSet->addSelectionChangeListener(xPreventDelete);
103     }
104     osl_decrementInterlockedCount(&m_refCount);
105 }
106 
107 //------------------------------------------------------------------
108 OSelectionChangeMultiplexer::~OSelectionChangeMultiplexer()
109 {
110 }
111 
112 //------------------------------------------------------------------
113 void OSelectionChangeMultiplexer::lock()
114 {
115 	++m_nLockCount;
116 }
117 
118 //------------------------------------------------------------------
119 void OSelectionChangeMultiplexer::unlock()
120 {
121 	--m_nLockCount;
122 }
123 
124 //------------------------------------------------------------------
125 void OSelectionChangeMultiplexer::dispose()
126 {
127 	if (m_bListening)
128 	{
129 		Reference< XSelectionChangeListener> xPreventDelete(this);
130 
131 		m_xSet->removeSelectionChangeListener(xPreventDelete);
132 
133 		m_pListener->setAdapter(NULL);
134 
135 		m_pListener = NULL;
136 		m_bListening = sal_False;
137 
138 		if (m_bAutoSetRelease)
139 			m_xSet = NULL;
140 	}
141 }
142 
143 // XEventListener
144 //------------------------------------------------------------------
145 void SAL_CALL OSelectionChangeMultiplexer::disposing( const  EventObject& _rSource) throw( RuntimeException)
146 {
147 	if (m_pListener)
148 	{
149 		 // tell the listener
150 		if (!locked())
151 			m_pListener->_disposing(_rSource);
152 		// disconnect the listener
153 		if (m_pListener)	// may have been reset whilest calling into _disposing
154 			m_pListener->setAdapter(NULL);
155 	}
156 
157 	m_pListener = NULL;
158 	m_bListening = sal_False;
159 
160 	if (m_bAutoSetRelease)
161 		m_xSet = NULL;
162 }
163 
164 // XSelectionChangeListener
165 //------------------------------------------------------------------
166 void SAL_CALL OSelectionChangeMultiplexer::selectionChanged( const  EventObject& _rEvent ) throw( RuntimeException)
167 {
168 	if (m_pListener && !locked())
169 		m_pListener->_selectionChanged(_rEvent);
170 }
171 //.........................................................................
172 }
173 //.........................................................................
174 
175