1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2009 by Sun Microsystems, Inc.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * This file is part of OpenOffice.org.
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.
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).
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 ************************************************************************/
26 // MARKER(update_precomp.py): autogen include statement, do not remove
27 #include "precompiled_svx.hxx"
29 #include "svx/shapepropertynotifier.hxx"
31 /** === begin UNO includes === **/
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 /** === end UNO includes === **/
35 #include <comphelper/stl_types.hxx>
36 #include <cppuhelper/interfacecontainer.hxx>
37 #include <cppuhelper/weak.hxx>
38 #include <tools/diagnose_ex.h>
45 struct ShapePropertyHash
47 size_t operator()( ::svx::ShapeProperty __x
) const
54 //........................................................................
57 //........................................................................
59 /** === begin UNO using === **/
60 using ::com::sun::star::uno::Reference
;
61 using ::com::sun::star::uno::XInterface
;
62 using ::com::sun::star::uno::UNO_QUERY
;
63 using ::com::sun::star::uno::UNO_QUERY_THROW
;
64 using ::com::sun::star::uno::UNO_SET_THROW
;
65 using ::com::sun::star::uno::Exception
;
66 using ::com::sun::star::uno::RuntimeException
;
67 using ::com::sun::star::uno::Any
;
68 using ::com::sun::star::uno::makeAny
;
69 using ::com::sun::star::uno::Sequence
;
70 using ::com::sun::star::uno::Type
;
71 using ::com::sun::star::beans::PropertyChangeEvent
;
72 using ::com::sun::star::beans::XPropertyChangeListener
;
73 using ::com::sun::star::lang::EventObject
;
74 using ::com::sun::star::beans::XPropertySet
;
75 /** === end UNO using === **/
77 typedef ::std::hash_map
< ShapeProperty
, PPropertyValueProvider
, ShapePropertyHash
> PropertyProviders
;
79 typedef ::cppu::OMultiTypeInterfaceContainerHelperVar
< ::rtl::OUString
80 , ::comphelper::UStringHash
81 , ::comphelper::UStringEqual
82 > PropertyChangeListenerContainer
;
84 //====================================================================
85 //= IPropertyValueProvider
86 //====================================================================
87 IPropertyValueProvider::~IPropertyValueProvider()
91 //====================================================================
92 //= PropertyChangeNotifier_Data
93 //====================================================================
94 struct PropertyChangeNotifier_Data
96 ::cppu::OWeakObject
& m_rContext
;
97 PropertyProviders m_aProviders
;
98 PropertyChangeListenerContainer m_aPropertyChangeListeners
;
100 PropertyChangeNotifier_Data( ::cppu::OWeakObject
& _rContext
, ::osl::Mutex
& _rMutex
)
101 :m_rContext( _rContext
)
102 ,m_aPropertyChangeListeners( _rMutex
)
106 //====================================================================
107 //= PropertyValueProvider
108 //====================================================================
109 //--------------------------------------------------------------------
110 ::rtl::OUString
PropertyValueProvider::getPropertyName() const
112 return m_sPropertyName
;
115 //--------------------------------------------------------------------
116 void PropertyValueProvider::getCurrentValue( Any
& _out_rValue
) const
118 Reference
< XPropertySet
> xContextProps( const_cast< PropertyValueProvider
* >( this )->m_rContext
, UNO_QUERY_THROW
);
119 _out_rValue
= xContextProps
->getPropertyValue( getPropertyName() );
122 //====================================================================
123 //= PropertyChangeNotifier
124 //====================================================================
125 //--------------------------------------------------------------------
126 PropertyChangeNotifier::PropertyChangeNotifier( ::cppu::OWeakObject
& _rOwner
, ::osl::Mutex
& _rMutex
)
127 :m_pData( new PropertyChangeNotifier_Data( _rOwner
, _rMutex
) )
131 //--------------------------------------------------------------------
132 PropertyChangeNotifier::~PropertyChangeNotifier()
136 //--------------------------------------------------------------------
137 void PropertyChangeNotifier::registerProvider( const ShapeProperty _eProperty
, const PPropertyValueProvider _pProvider
)
139 ENSURE_OR_THROW( _eProperty
!= eInvalidShapeProperty
, "Illegal ShapeProperty value!" );
140 ENSURE_OR_THROW( !!_pProvider
, "NULL factory not allowed." );
142 OSL_ENSURE( m_pData
->m_aProviders
.find( _eProperty
) == m_pData
->m_aProviders
.end(),
143 "PropertyChangeNotifier::registerProvider: factory for this ID already present!" );
145 m_pData
->m_aProviders
[ _eProperty
] = _pProvider
;
148 //--------------------------------------------------------------------
149 void PropertyChangeNotifier::notifyPropertyChange( const ShapeProperty _eProperty
) const
151 ENSURE_OR_THROW( _eProperty
!= eInvalidShapeProperty
, "Illegal ShapeProperty value!" );
153 PropertyProviders::const_iterator provPos
= m_pData
->m_aProviders
.find( _eProperty
);
154 OSL_ENSURE( provPos
!= m_pData
->m_aProviders
.end(), "PropertyChangeNotifier::notifyPropertyChange: no factory!" );
155 if ( provPos
== m_pData
->m_aProviders
.end() )
158 ::rtl::OUString
sPropertyName( provPos
->second
->getPropertyName() );
160 ::cppu::OInterfaceContainerHelper
* pPropListeners
= m_pData
->m_aPropertyChangeListeners
.getContainer( sPropertyName
);
161 ::cppu::OInterfaceContainerHelper
* pAllListeners
= m_pData
->m_aPropertyChangeListeners
.getContainer( ::rtl::OUString() );
162 if ( !pPropListeners
&& !pAllListeners
)
167 PropertyChangeEvent aEvent
;
168 aEvent
.Source
= m_pData
->m_rContext
;
169 // Handle/OldValue not supported
170 aEvent
.PropertyName
= provPos
->second
->getPropertyName();
171 provPos
->second
->getCurrentValue( aEvent
.NewValue
);
173 if ( pPropListeners
)
174 pPropListeners
->notifyEach( &XPropertyChangeListener::propertyChange
, aEvent
);
176 pAllListeners
->notifyEach( &XPropertyChangeListener::propertyChange
, aEvent
);
178 catch( const Exception
& )
180 DBG_UNHANDLED_EXCEPTION();
184 //--------------------------------------------------------------------
185 void PropertyChangeNotifier::addPropertyChangeListener( const ::rtl::OUString
& _rPropertyName
, const Reference
< XPropertyChangeListener
>& _rxListener
)
187 m_pData
->m_aPropertyChangeListeners
.addInterface( _rPropertyName
, _rxListener
);
190 //--------------------------------------------------------------------
191 void PropertyChangeNotifier::removePropertyChangeListener( const ::rtl::OUString
& _rPropertyName
, const Reference
< XPropertyChangeListener
>& _rxListener
)
193 m_pData
->m_aPropertyChangeListeners
.removeInterface( _rPropertyName
, _rxListener
);
196 //--------------------------------------------------------------------
197 void PropertyChangeNotifier::disposing()
200 aEvent
.Source
= m_pData
->m_rContext
;
201 m_pData
->m_aPropertyChangeListeners
.disposeAndClear( aEvent
);
204 //........................................................................
206 //........................................................................