xref: /AOO41X/main/svx/source/unodraw/shapepropertynotifier.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25 ************************************************************************/
26 
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_svx.hxx"
29 
30 #include "svx/shapepropertynotifier.hxx"
31 
32 /** === begin UNO includes === **/
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 /** === end UNO includes === **/
35 
36 #include <comphelper/stl_types.hxx>
37 #include <cppuhelper/interfacecontainer.hxx>
38 #include <cppuhelper/weak.hxx>
39 #include <tools/diagnose_ex.h>
40 
41 #include <hash_map>
42 
43 namespace
44 {
45 
46     struct ShapePropertyHash
47     {
48         size_t operator()( ::svx::ShapeProperty __x ) const
49         {
50             return size_t( __x );
51         }
52     };
53 }
54 
55 //........................................................................
56 namespace svx
57 {
58 //........................................................................
59 
60 	/** === begin UNO using === **/
61 	using ::com::sun::star::uno::Reference;
62 	using ::com::sun::star::uno::XInterface;
63 	using ::com::sun::star::uno::UNO_QUERY;
64 	using ::com::sun::star::uno::UNO_QUERY_THROW;
65 	using ::com::sun::star::uno::UNO_SET_THROW;
66 	using ::com::sun::star::uno::Exception;
67 	using ::com::sun::star::uno::RuntimeException;
68 	using ::com::sun::star::uno::Any;
69 	using ::com::sun::star::uno::makeAny;
70 	using ::com::sun::star::uno::Sequence;
71 	using ::com::sun::star::uno::Type;
72     using ::com::sun::star::beans::PropertyChangeEvent;
73     using ::com::sun::star::beans::XPropertyChangeListener;
74     using ::com::sun::star::lang::EventObject;
75     using ::com::sun::star::beans::XPropertySet;
76 	/** === end UNO using === **/
77 
78     typedef ::std::hash_map< ShapeProperty, PPropertyValueProvider, ShapePropertyHash  >    PropertyProviders;
79 
80     typedef ::cppu::OMultiTypeInterfaceContainerHelperVar   <   ::rtl::OUString
81                                                             ,   ::comphelper::UStringHash
82                                                             ,   ::comphelper::UStringEqual
83                                                             >   PropertyChangeListenerContainer;
84 
85     //====================================================================
86 	//= IPropertyValueProvider
87 	//====================================================================
88     IPropertyValueProvider::~IPropertyValueProvider()
89     {
90     }
91 
92     //====================================================================
93 	//= PropertyChangeNotifier_Data
94 	//====================================================================
95     struct PropertyChangeNotifier_Data
96     {
97         ::cppu::OWeakObject&            m_rContext;
98         PropertyProviders               m_aProviders;
99         PropertyChangeListenerContainer m_aPropertyChangeListeners;
100 
101         PropertyChangeNotifier_Data( ::cppu::OWeakObject& _rContext, ::osl::Mutex& _rMutex )
102             :m_rContext( _rContext )
103             ,m_aPropertyChangeListeners( _rMutex )
104         {
105         }
106     };
107 	//====================================================================
108 	//= PropertyValueProvider
109 	//====================================================================
110 	//--------------------------------------------------------------------
111     ::rtl::OUString PropertyValueProvider::getPropertyName() const
112     {
113         return m_sPropertyName;
114     }
115 
116 	//--------------------------------------------------------------------
117     void PropertyValueProvider::getCurrentValue( Any& _out_rValue ) const
118     {
119         Reference< XPropertySet > xContextProps( const_cast< PropertyValueProvider* >( this )->m_rContext, UNO_QUERY_THROW );
120         _out_rValue = xContextProps->getPropertyValue( getPropertyName() );
121     }
122 
123 	//====================================================================
124 	//= PropertyChangeNotifier
125 	//====================================================================
126 	//--------------------------------------------------------------------
127     PropertyChangeNotifier::PropertyChangeNotifier( ::cppu::OWeakObject& _rOwner, ::osl::Mutex& _rMutex )
128         :m_pData( new PropertyChangeNotifier_Data( _rOwner, _rMutex ) )
129     {
130     }
131 
132 	//--------------------------------------------------------------------
133     PropertyChangeNotifier::~PropertyChangeNotifier()
134     {
135     }
136 
137 	//--------------------------------------------------------------------
138     void PropertyChangeNotifier::registerProvider( const ShapeProperty _eProperty, const PPropertyValueProvider _pProvider )
139     {
140         ENSURE_OR_THROW( _eProperty != eInvalidShapeProperty, "Illegal ShapeProperty value!" );
141         ENSURE_OR_THROW( !!_pProvider, "NULL factory not allowed." );
142 
143         OSL_ENSURE( m_pData->m_aProviders.find( _eProperty ) == m_pData->m_aProviders.end(),
144             "PropertyChangeNotifier::registerProvider: factory for this ID already present!" );
145 
146         m_pData->m_aProviders[ _eProperty ] = _pProvider;
147     }
148 
149 	//--------------------------------------------------------------------
150     void PropertyChangeNotifier::notifyPropertyChange( const ShapeProperty _eProperty ) const
151     {
152         ENSURE_OR_THROW( _eProperty != eInvalidShapeProperty, "Illegal ShapeProperty value!" );
153 
154         PropertyProviders::const_iterator provPos = m_pData->m_aProviders.find( _eProperty );
155         OSL_ENSURE( provPos != m_pData->m_aProviders.end(), "PropertyChangeNotifier::notifyPropertyChange: no factory!" );
156         if ( provPos == m_pData->m_aProviders.end() )
157             return;
158 
159         ::rtl::OUString sPropertyName( provPos->second->getPropertyName() );
160 
161         ::cppu::OInterfaceContainerHelper* pPropListeners = m_pData->m_aPropertyChangeListeners.getContainer( sPropertyName );
162         ::cppu::OInterfaceContainerHelper* pAllListeners = m_pData->m_aPropertyChangeListeners.getContainer( ::rtl::OUString() );
163 	    if ( !pPropListeners && !pAllListeners )
164             return;
165 
166         try
167         {
168             PropertyChangeEvent aEvent;
169             aEvent.Source = m_pData->m_rContext;
170             // Handle/OldValue not supported
171             aEvent.PropertyName = provPos->second->getPropertyName();
172             provPos->second->getCurrentValue( aEvent.NewValue );
173 
174             if ( pPropListeners )
175                 pPropListeners->notifyEach( &XPropertyChangeListener::propertyChange, aEvent );
176             if ( pAllListeners )
177                 pAllListeners->notifyEach( &XPropertyChangeListener::propertyChange, aEvent );
178         }
179         catch( const Exception& )
180         {
181         	DBG_UNHANDLED_EXCEPTION();
182         }
183     }
184 
185 	//--------------------------------------------------------------------
186     void PropertyChangeNotifier::addPropertyChangeListener( const ::rtl::OUString& _rPropertyName, const Reference< XPropertyChangeListener >& _rxListener )
187     {
188         m_pData->m_aPropertyChangeListeners.addInterface( _rPropertyName, _rxListener );
189     }
190 
191 	//--------------------------------------------------------------------
192     void PropertyChangeNotifier::removePropertyChangeListener( const ::rtl::OUString& _rPropertyName, const Reference< XPropertyChangeListener >& _rxListener )
193     {
194         m_pData->m_aPropertyChangeListeners.removeInterface( _rPropertyName, _rxListener );
195     }
196 
197 	//--------------------------------------------------------------------
198     void PropertyChangeNotifier::disposing()
199     {
200         EventObject aEvent;
201         aEvent.Source = m_pData->m_rContext;
202         m_pData->m_aPropertyChangeListeners.disposeAndClear( aEvent );
203     }
204 
205 //........................................................................
206 } // namespace svx
207 //........................................................................
208