diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2006-03-14 10:19:44 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2006-03-14 10:19:44 +0000 |
commit | cb749022f3bae63a2764cb85658008ccd220474a (patch) | |
tree | 446720fcf1b57c57dd8596b4f7051a4848077136 /extensions | |
parent | f685bb4194dfe66b6071843375de26e81dc39feb (diff) |
INTEGRATION: CWS pbrwuno (1.1.2); FILE ADDED
2006/03/09 14:14:29 fs 1.1.2.10: #i62967# no UnknownPropertyExceptions at the XObjectInspectorUI anymore
2005/11/02 12:17:15 fs 1.1.2.9: #i10000# exception specifications
2005/10/31 13:45:56 fs 1.1.2.8: some cleanup
2005/10/31 11:13:04 fs 1.1.2.7: teach the ComposedPropertyUIUpdate to handle missing properties
2005/10/17 14:09:12 fs 1.1.2.6: #i53095# some cleanup of remaining TODOs
2005/10/17 08:38:36 fs 1.1.2.5: implement auto-firing for ComposedUIUpdate
2005/10/17 08:17:00 fs 1.1.2.4: #i53095#
2005/10/13 13:00:59 fs 1.1.2.3: #i53095# introduce an XObjectInspector/Model
2005/10/11 13:28:56 fs 1.1.2.2: #i53095# phase 3:
introduced XPropertyHandler and XObjectInspectorUI
same open issues as in previous phase
(plus probably some more, since not everything is tested, yet :-\)
2005/08/12 16:30:09 fs 1.1.2.1: - more fine-grained control in the IPropertyBrowserUI which elements
to enable or disable
- moved designing the SQL command into a dedicated handler
- some more reactions on actuating properties move to dedicated handlers
- *nearly* completed implementation of the "composed browser UI", which
collects and combines UI change requests (IPropertyBrowserUI)
(still missing: proper auto-firing)
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/source/propctrlr/composeduiupdate.cxx | 853 |
1 files changed, 853 insertions, 0 deletions
diff --git a/extensions/source/propctrlr/composeduiupdate.cxx b/extensions/source/propctrlr/composeduiupdate.cxx new file mode 100644 index 000000000000..fa2b62269020 --- /dev/null +++ b/extensions/source/propctrlr/composeduiupdate.cxx @@ -0,0 +1,853 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: composeduiupdate.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: vg $ $Date: 2006-03-14 11:19:44 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef EXTENSIONS_SOURCE_PROPCTRLR_COMPOSEDUIUPDATE_HXX +#include "composeduiupdate.hxx" +#endif + +/** === begin UNO includes === **/ +#ifndef _COM_SUN_STAR_INSPECTION_XOBJECTINSPECTORUI_HPP_ +#include <com/sun/star/inspection/XObjectInspectorUI.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ +#include <com/sun/star/lang/DisposedException.hpp> +#endif +#ifndef _COM_SUN_STAR_INSPECTION_PROPERTYLINEELEMENT_HPP_ +#include <com/sun/star/inspection/PropertyLineElement.hpp> +#endif +/** === end UNO includes === **/ + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_REF_HXX_ +#include <rtl/ref.hxx> +#endif + +#include <algorithm> + +//........................................................................ +namespace pcr +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Exception; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::lang::NullPointerException; + using ::com::sun::star::inspection::XPropertyHandler; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::inspection::XObjectInspectorUI; + using ::com::sun::star::inspection::XPropertyControl; + using ::com::sun::star::uno::RuntimeException; + /** === end UNO using === **/ + + namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement; + + //==================================================================== + //= helper + //==================================================================== + namespace + { + struct HandlerLess : public ::std::binary_function < Reference< XPropertyHandler > + , Reference< XPropertyHandler > + , bool + > + { + bool operator()( const Reference< XPropertyHandler >& lhs, const Reference< XPropertyHandler >& rhs) const + { + return lhs.get() < rhs.get(); + } + }; + + //================================================================ + typedef ::std::set< ::rtl::OUString > StringBag; + typedef ::std::map< sal_Int16, StringBag > MapIntToStringBag; + } + + //==================================================================== + //= callbacks for CachedInspectorUI + //==================================================================== + typedef void (ComposedPropertyUIUpdate::*FNotifySingleUIChange)(); + + //==================================================================== + //= CachedInspectorUI + //==================================================================== + typedef ::cppu::WeakImplHelper1 < ::com::sun::star::inspection::XObjectInspectorUI + > CachedInspectorUI_Base; + struct CachedInspectorUI : public CachedInspectorUI_Base + { + private: + ::osl::Mutex m_aMutex; + oslInterlockedCount m_refCount; + bool m_bDisposed; + ComposedPropertyUIUpdate& + m_rMaster; + FNotifySingleUIChange m_pUIChangeNotification; + + // enablePropertyUI cache + StringBag aEnabledProperties; + StringBag aDisabledProperties; + + // show/hidePropertyUI cache + StringBag aShownProperties; + StringBag aHiddenProperties; + + // rebuildPropertyUI cache + StringBag aRebuiltProperties; + + // showCategory cache + StringBag aShownCategories; + StringBag aHiddenCategories; + + // enablePropertyUIElements cache + MapIntToStringBag aEnabledElements; + MapIntToStringBag aDisabledElements; + + public: + typedef StringBag& (CachedInspectorUI::*FGetStringBag)(); + + // enablePropertyUI cache + StringBag& getEnabledProperties() { return aEnabledProperties; } + StringBag& getDisabledProperties() { return aDisabledProperties; } + + // show/hidePropertyUI cache + StringBag& getShownProperties() { return aShownProperties; } + StringBag& getHiddenProperties() { return aHiddenProperties; } + + // rebuildPropertyUI cache + StringBag& getRebuiltProperties() { return aRebuiltProperties; } + + // showCategory cache + StringBag& getShownCategories() { return aShownCategories; } + StringBag& getHiddenCategories() { return aHiddenCategories; } + + // enablePropertyUIElements + StringBag& getEnabledInputControls() { return aEnabledElements[ PropertyLineElement::InputControl ]; } + StringBag& getDisabledInputControls() { return aDisabledElements[ PropertyLineElement::InputControl ]; } + StringBag& getEnabledPrimaryButtons() { return aEnabledElements[ PropertyLineElement::PrimaryButton ]; } + StringBag& getDisabledPrimaryButtons() { return aDisabledElements[ PropertyLineElement::PrimaryButton ]; } + StringBag& getEnabledSecondaryButtons() { return aEnabledElements[ PropertyLineElement::SecondaryButton ]; } + StringBag& getDisabledSecondaryButtons() { return aDisabledElements[ PropertyLineElement::SecondaryButton ]; } + + public: + CachedInspectorUI( ComposedPropertyUIUpdate& _rMaster, FNotifySingleUIChange _pUIChangeNotification ); + + /// disposes the instance + void dispose(); + + // XObjectInspectorUI overridables + virtual void SAL_CALL enablePropertyUI( const ::rtl::OUString& _rPropertyName, ::sal_Bool _bEnable ) throw (RuntimeException); + virtual void SAL_CALL enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, ::sal_Int16 _nElements, ::sal_Bool _bEnable ) throw (RuntimeException); + virtual void SAL_CALL rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException); + virtual void SAL_CALL showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException); + virtual void SAL_CALL hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException); + virtual void SAL_CALL showCategory( const ::rtl::OUString& _rCategory, ::sal_Bool _bShow ) throw (RuntimeException); + virtual Reference< XPropertyControl > SAL_CALL getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException); + + // UNOCompatibleNonUNOReference overridables + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + protected: + ~CachedInspectorUI(); + + /// determines whether the instance is already disposed + inline bool isDisposed() const { return m_bDisposed; } + + /// throws an exception if the component is already disposed + void checkDisposed() const; + + private: + void impl_markElementEnabledOrDisabled( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElementIdOrZero, sal_Bool _bEnable ); + + /** calls <member>m_pUIChangeNotification</member> at <member>m_rMaster</member> + */ + void impl_notifySingleUIChange() const; + + private: + CachedInspectorUI( const CachedInspectorUI& ); // never implemented + CachedInspectorUI& operator=( const CachedInspectorUI& ); // never implemented + + private: + friend class MethodGuard; + class MethodGuard : public ::osl::MutexGuard + { + public: + MethodGuard( CachedInspectorUI& rInstance ) + : ::osl::MutexGuard( rInstance.m_aMutex ) + { + rInstance.checkDisposed(); + } + }; + }; + + //---------------------------------------------------------------- + CachedInspectorUI::CachedInspectorUI( ComposedPropertyUIUpdate& _rMaster, FNotifySingleUIChange _pUIChangeNotification ) + :m_refCount( 0 ) + ,m_bDisposed( false ) + ,m_rMaster( _rMaster ) + ,m_pUIChangeNotification( _pUIChangeNotification ) + { + } + + //---------------------------------------------------------------- + CachedInspectorUI::~CachedInspectorUI() + { + } + + //---------------------------------------------------------------- + void CachedInspectorUI::dispose() + { + ::osl::MutexGuard aGuard( m_aMutex ); + m_bDisposed = true; + + clearContainer( aEnabledProperties ); + clearContainer( aDisabledProperties ); + clearContainer( aRebuiltProperties ); + clearContainer( aShownProperties ); + clearContainer( aHiddenProperties ); + clearContainer( aShownCategories ); + clearContainer( aHiddenCategories ); + clearContainer( aEnabledElements ); + clearContainer( aDisabledElements ); + } + + //---------------------------------------------------------------- + void SAL_CALL CachedInspectorUI::acquire() throw() + { + osl_incrementInterlockedCount( &m_refCount ); + } + + //---------------------------------------------------------------- + void SAL_CALL CachedInspectorUI::release() throw() + { + if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) + delete this; + } + + + //---------------------------------------------------------------- + void CachedInspectorUI::checkDisposed() const + { + if ( isDisposed() ) + throw DisposedException(); + } + + //---------------------------------------------------------------- + namespace + { + void lcl_markStringKeyPositiveOrNegative( const ::rtl::OUString& _rKeyName, StringBag& _rPositives, StringBag& _rNegatives, sal_Bool _bMarkPositive ) + { + if ( _bMarkPositive ) + { + _rPositives.insert( _rKeyName ); + // if the same key has been remember as in the "negative" list before, clear this information, since it's overruled + _rNegatives.erase( _rKeyName ); + } + else + _rNegatives.insert( _rKeyName ); + } + } + + //---------------------------------------------------------------- + void CachedInspectorUI::enablePropertyUI( const ::rtl::OUString& _rPropertyName, sal_Bool _bEnable ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) ) + return; + + lcl_markStringKeyPositiveOrNegative( _rPropertyName, aEnabledProperties, aDisabledProperties, _bEnable ); + impl_notifySingleUIChange(); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::impl_markElementEnabledOrDisabled( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElementIdOrZero, sal_Bool _bEnable ) + { + if ( _nElementIdOrZero == 0 ) + return; + + lcl_markStringKeyPositiveOrNegative( + _rPropertyName, + aEnabledElements[ _nElementIdOrZero ], + aDisabledElements[ _nElementIdOrZero ], + _bEnable + ); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::impl_notifySingleUIChange() const + { + (m_rMaster.*m_pUIChangeNotification)(); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElements, sal_Bool _bEnable ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) ) + return; + + impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::InputControl, _bEnable ); + impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::PrimaryButton, _bEnable ); + impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::SecondaryButton, _bEnable ); + + impl_notifySingleUIChange(); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) ) + return; + + aRebuiltProperties.insert( _rPropertyName ); + + impl_notifySingleUIChange(); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) ) + return; + + aShownProperties.insert( _rPropertyName ); + // if the same category has been hidden before, clear this information, since it's overruled + aHiddenProperties.erase( _rPropertyName ); + + impl_notifySingleUIChange(); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) ) + return; + + aHiddenProperties.insert( _rPropertyName ); + impl_notifySingleUIChange(); + } + + //---------------------------------------------------------------- + void CachedInspectorUI::showCategory( const ::rtl::OUString& _rCategory, sal_Bool _bShow ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + + lcl_markStringKeyPositiveOrNegative( _rCategory, aShownCategories, aHiddenCategories, _bShow ); + impl_notifySingleUIChange(); + } + + //---------------------------------------------------------------- + Reference< XPropertyControl > SAL_CALL CachedInspectorUI::getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) ) + return Reference< XPropertyControl >(); + + return m_rMaster.getDelegatorUI()->getPropertyControl( _rPropertyName ); + } + + //==================================================================== + //= HandlerMap + //==================================================================== + typedef ::std::map < Reference< XPropertyHandler > + , ::rtl::Reference< CachedInspectorUI > + , HandlerLess + > ImplMapHandlerToUI; + struct MapHandlerToUI + { + ImplMapHandlerToUI aHandlers; + }; + + //==================================================================== + //= ComposedPropertyUIUpdate + //==================================================================== + //---------------------------------------------------------------- + ComposedPropertyUIUpdate::ComposedPropertyUIUpdate( const Reference< XObjectInspectorUI >& _rxDelegatorUI, + IPropertyExistenceCheck* _pPropertyCheck ) + :m_pCollectedUIs( new MapHandlerToUI ) + ,m_xDelegatorUI( _rxDelegatorUI ) + ,m_nSuspendCounter( 0 ) + ,m_pPropertyCheck( _pPropertyCheck ) + { + if ( !m_xDelegatorUI.is() ) + throw NullPointerException(); + } + + //---------------------------------------------------------------- + ComposedPropertyUIUpdate::~ComposedPropertyUIUpdate( ) + { + } + + //---------------------------------------------------------------- + Reference< XObjectInspectorUI > ComposedPropertyUIUpdate::getUIForPropertyHandler( const Reference< XPropertyHandler >& _rxHandler ) + { + impl_checkDisposed(); + + ::rtl::Reference< CachedInspectorUI >& rUI = m_pCollectedUIs->aHandlers[ _rxHandler ]; + if ( !rUI.is() ) + rUI = new CachedInspectorUI( *this, &ComposedPropertyUIUpdate::callback_inspectorUIChanged_throw ); + return rUI.get(); + } + + //---------------------------------------------------------------- + namespace + { + //============================================================ + //= StringBagCollector + //============================================================ + /** an STL-compatible structure which collects strings from a CachedInspectorUI instances + */ + struct StringBagCollector : public ::std::unary_function< ImplMapHandlerToUI::value_type, void > + { + private: + StringBag& m_rBag; + CachedInspectorUI::FGetStringBag m_pGetter; + + public: + StringBagCollector( StringBag& _rBag, CachedInspectorUI::FGetStringBag _pGetter ) :m_rBag( _rBag ), m_pGetter( _pGetter ) { } + + void operator()( const ImplMapHandlerToUI::value_type& _rUI ) + { + StringBag& rBag( ((_rUI.second.get())->*m_pGetter)() ); + m_rBag.insert( rBag.begin(), rBag.end() ); + } + + static void collectAll( StringBag& _rAll, const ImplMapHandlerToUI& _rMap, CachedInspectorUI::FGetStringBag _pGetter ) + { + ::std::for_each( _rMap.begin(), _rMap.end(), StringBagCollector( _rAll, _pGetter ) ); + } + }; + + //============================================================ + //= StringBagClearer + //============================================================ + /** an STL-compatible structure which cleans a certain string bag in a CachedInspectorUI instances + */ + struct StringBagClearer : public ::std::unary_function< ImplMapHandlerToUI::value_type, void > + { + private: + CachedInspectorUI::FGetStringBag m_pGetter; + + public: + StringBagClearer( CachedInspectorUI::FGetStringBag _pGetter ) :m_pGetter( _pGetter ) { } + + void operator()( const ImplMapHandlerToUI::value_type& _rUI ) + { + clearContainer( ((_rUI.second.get())->*m_pGetter)() ); + } + + static void clearAll( const ImplMapHandlerToUI& _rMap, CachedInspectorUI::FGetStringBag _pGetter ) + { + ::std::for_each( _rMap.begin(), _rMap.end(), StringBagClearer( _pGetter ) ); + } + }; + + //============================================================ + //= FPropertyUISetter + //============================================================ + /** a typedef for a ->XObjectInspectorUI member function taking a string + */ + typedef void ( SAL_CALL XObjectInspectorUI::*FPropertyUISetter )( const ::rtl::OUString& ); + + //============================================================ + //= PropertyUIOperator + //============================================================ + /** an STL-compatible struct which calls a certain member method (taking a string) at a + given ->XObjectInspectorUI instance + */ + struct PropertyUIOperator : public ::std::unary_function< ::rtl::OUString, void > + { + private: + Reference< XObjectInspectorUI > m_xUpdater; + FPropertyUISetter m_pSetter; + + public: + PropertyUIOperator( const Reference< XObjectInspectorUI >& _rxInspectorUI, FPropertyUISetter _pSetter ) + :m_xUpdater( _rxInspectorUI ) + ,m_pSetter( _pSetter ) + { + } + + void operator()( const ::rtl::OUString& _rPropertyName ) + { + ((m_xUpdater.get())->*m_pSetter)( _rPropertyName ); + } + + static void forEach( const StringBag& _rProperties, const Reference< XObjectInspectorUI >& _rxDelegatorUI, FPropertyUISetter _pSetter ) + { + ::std::for_each( _rProperties.begin(), _rProperties.end(), PropertyUIOperator( _rxDelegatorUI, _pSetter ) ); + } + }; + + //============================================================ + //= IStringKeyBooleanUIUpdate + //============================================================ + /** an interface which encapsulates access to a single aspect of the ->XObjectInspectorUI, + where this aspect is given by a string key, and has a boolean value. + */ + class IStringKeyBooleanUIUpdate + { + public: + virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const = 0; + }; + + //============================================================ + //= FPropertyUIFlagSetter + //============================================================ + /** an implementation of the ->IStringKeyBooleanUIUpdate interface which, + for a fixed ->XObjectInspectorUI instance and a fixed UI element (->PropertyLineElement), + updates this element for a given property with a given boolean flag + (->XObjectInspectorUI::enablePropertyUIElements) + */ + class EnablePropertyUIElement : public IStringKeyBooleanUIUpdate + { + private: + Reference< XObjectInspectorUI > m_xUIUpdate; + sal_Int16 m_nElement; + + public: + EnablePropertyUIElement( const Reference< XObjectInspectorUI >& _rxUIUpdate, sal_Int16 _nElement ) + :m_xUIUpdate( _rxUIUpdate ) + ,m_nElement( _nElement ) + { + } + // IStringKeyBooleanUIUpdate + virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const; + }; + + //............................................................ + void EnablePropertyUIElement::updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const + { + m_xUIUpdate->enablePropertyUIElements( _rKey, m_nElement, _bFlag ); + } + + //============================================================ + //= FPropertyUIFlagSetter + //============================================================ + /** a ->XObjectInspectorUI method taking a string and a boolean + */ + typedef void ( SAL_CALL XObjectInspectorUI::*FPropertyUIFlagSetter )( const ::rtl::OUString&, sal_Bool ); + + //============================================================ + //= DefaultStringKeyBooleanUIUpdate + //============================================================ + /** an implementaiton of the ->IStringKeyBooleanUIUpdate interface which calls + am arbitrary ->XObjectInspectorUI method taking a string and a boolean flag + */ + class DefaultStringKeyBooleanUIUpdate : public IStringKeyBooleanUIUpdate + { + private: + Reference< XObjectInspectorUI > m_xUIUpdate; + FPropertyUIFlagSetter m_pSetter; + + public: + DefaultStringKeyBooleanUIUpdate( const Reference< XObjectInspectorUI >& _rxUIUpdate, FPropertyUIFlagSetter _pSetter ); + // IStringKeyBooleanUIUpdate + virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const; + }; + + //............................................................ + DefaultStringKeyBooleanUIUpdate::DefaultStringKeyBooleanUIUpdate( const Reference< XObjectInspectorUI >& _rxUIUpdate, FPropertyUIFlagSetter _pSetter ) + :m_xUIUpdate( _rxUIUpdate ) + ,m_pSetter( _pSetter ) + { + } + + //............................................................ + void DefaultStringKeyBooleanUIUpdate::updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const + { + ((m_xUIUpdate.get())->*m_pSetter)( _rKey, _bFlag ); + } + + //============================================================ + //= BooleanUIAspectUpdate + //============================================================ + /** an STL-compatible structure which applies a ->IStringKeyBooleanUIUpdate::updateUIForKey + operation with a fixed boolean value, for a given string value + */ + struct BooleanUIAspectUpdate : public ::std::unary_function< ::rtl::OUString, void > + { + private: + const IStringKeyBooleanUIUpdate& m_rUpdater; + sal_Bool m_bFlag; + + public: + BooleanUIAspectUpdate( const IStringKeyBooleanUIUpdate& _rUpdater, sal_Bool _bFlag ) + :m_rUpdater( _rUpdater ) + ,m_bFlag( _bFlag ) + { + } + + void operator()( const ::rtl::OUString& _rPropertyName ) + { + m_rUpdater.updateUIForKey( _rPropertyName, m_bFlag ); + } + + static void forEach( const StringBag& _rProperties, const IStringKeyBooleanUIUpdate& _rUpdater, sal_Bool _bFlag ) + { + ::std::for_each( _rProperties.begin(), _rProperties.end(), BooleanUIAspectUpdate( _rUpdater, _bFlag ) ); + } + }; + + //============================================================ + //= BooleanUIAspectUpdate + //============================================================ + /** an STL-compatible structure subtracting a given string from a fixed ->StringBag + */ + struct StringBagComplement : public ::std::unary_function< ::rtl::OUString, void > + { + private: + StringBag& m_rMinuend; + + public: + StringBagComplement( StringBag& _rMinuend ) :m_rMinuend( _rMinuend ) { } + + void operator()( const ::rtl::OUString& _rPropertyToSubtract ) + { + m_rMinuend.erase( _rPropertyToSubtract ); + } + + static void subtract( StringBag& _rMinuend, const StringBag& _rSubtrahend ) + { + ::std::for_each( _rSubtrahend.begin(), _rSubtrahend.end(), StringBagComplement( _rMinuend ) ); + } + }; + + //============================================================ + //= BooleanUIAspectUpdate + //============================================================ + void lcl_fireUIStateFlag( + const IStringKeyBooleanUIUpdate& _rUIUpdate, + const ImplMapHandlerToUI& _rHandlerUIs, + CachedInspectorUI::FGetStringBag _pGetPositives, + CachedInspectorUI::FGetStringBag _pGetNegatives + ) + { + // all strings which are in the "positive" list of one handler + StringBag aAllPositives; + StringBagCollector::collectAll( aAllPositives, _rHandlerUIs, _pGetPositives ); + + // all strings which are in the "negative" list of one handler + StringBag aAllNegatives; + StringBagCollector::collectAll( aAllNegatives, _rHandlerUIs, _pGetNegatives ); + + // propagate the "negative" flags to the delegator UI + BooleanUIAspectUpdate::forEach( aAllNegatives, _rUIUpdate, sal_False ); + + // propagate the "positive" flags to the delegator UI, for all elements where _no_ + // "negative" flag exists + StringBagComplement::subtract( aAllPositives, aAllNegatives ); + BooleanUIAspectUpdate::forEach( aAllPositives, _rUIUpdate, sal_True ); + + // the "positive" request can be cleared no, only negative requests + // (such as "disable a property" or "hide a category") need to be preserved for the next round + StringBagClearer::clearAll( _rHandlerUIs, _pGetPositives ); + } + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_fireEnablePropertyUI_throw() + { + lcl_fireUIStateFlag( + DefaultStringKeyBooleanUIUpdate( m_xDelegatorUI, &XObjectInspectorUI::enablePropertyUI ), + m_pCollectedUIs->aHandlers, + &CachedInspectorUI::getEnabledProperties, + &CachedInspectorUI::getDisabledProperties + ); + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_fireRebuildPropertyUI_throw() + { + // collect all properties for which a rebuild request has been made + StringBag aAllRebuilt; + StringBagCollector::collectAll( aAllRebuilt, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getRebuiltProperties ); + + // rebuild all those properties + PropertyUIOperator::forEach( aAllRebuilt, m_xDelegatorUI, &XObjectInspectorUI::rebuildPropertyUI ); + + // clear the "properties to rebuild" at all handlers, since the request has been fulfilled now. + StringBagClearer::clearAll( m_pCollectedUIs->aHandlers, &CachedInspectorUI::getRebuiltProperties ); + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_fireShowHidePropertyUI_throw() + { + // all properties which have been shown by at least one handler + StringBag aAllShown; + StringBagCollector::collectAll( aAllShown, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getShownProperties ); + // all properties which have been hidden by at least one handler + StringBag aAllHidden; + StringBagCollector::collectAll( aAllHidden, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getHiddenProperties ); + + // hide properties as necessary + PropertyUIOperator::forEach( aAllHidden, m_xDelegatorUI, &XObjectInspectorUI::hidePropertyUI ); + + // for those properties which are hidden, ignore all "show" requests which other handlers might have had + StringBagComplement::subtract( aAllShown, aAllHidden ); + + // show properties + PropertyUIOperator::forEach( aAllShown, m_xDelegatorUI, &XObjectInspectorUI::showPropertyUI ); + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_fireShowCategory_throw() + { + lcl_fireUIStateFlag( + DefaultStringKeyBooleanUIUpdate( m_xDelegatorUI, &XObjectInspectorUI::showCategory ), + m_pCollectedUIs->aHandlers, + &CachedInspectorUI::getShownCategories, + &CachedInspectorUI::getHiddenCategories + ); + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_fireEnablePropertyUIElements_throw() + { + lcl_fireUIStateFlag( + EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::InputControl ), + m_pCollectedUIs->aHandlers, + &CachedInspectorUI::getEnabledInputControls, + &CachedInspectorUI::getDisabledInputControls + ); + + lcl_fireUIStateFlag( + EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::PrimaryButton ), + m_pCollectedUIs->aHandlers, + &CachedInspectorUI::getEnabledPrimaryButtons, + &CachedInspectorUI::getDisabledPrimaryButtons + ); + + lcl_fireUIStateFlag( + EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::SecondaryButton ), + m_pCollectedUIs->aHandlers, + &CachedInspectorUI::getEnabledSecondaryButtons, + &CachedInspectorUI::getDisabledSecondaryButtons + ); + } + + //---------------------------------------------------------------- + void SAL_CALL ComposedPropertyUIUpdate::fire() + { + impl_checkDisposed(); + impl_fireAll_throw(); + } + + //-------------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_fireAll_throw() + { + OSL_PRECOND( !impl_isDisposed(), "ComposedPropertyUIUpdate::impl_fireAll_throw: already disposed, this will crash!" ); + + impl_fireEnablePropertyUI_throw(); + impl_fireShowHidePropertyUI_throw(); + impl_fireRebuildPropertyUI_throw(); + impl_fireShowCategory_throw(); + impl_fireEnablePropertyUIElements_throw(); + } + + //-------------------------------------------------------------------- + void SAL_CALL ComposedPropertyUIUpdate::suspendAutoFire() + { + impl_checkDisposed(); + osl_incrementInterlockedCount( &m_nSuspendCounter ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ComposedPropertyUIUpdate::resumeAutoFire() + { + impl_checkDisposed(); + if ( 0 == osl_decrementInterlockedCount( &m_nSuspendCounter ) ) + impl_fireAll_throw(); + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::impl_checkDisposed() const + { + if ( impl_isDisposed() ) + throw DisposedException(); + } + + //---------------------------------------------------------------- + void ComposedPropertyUIUpdate::callback_inspectorUIChanged_throw() + { + if ( 0 == m_nSuspendCounter ) + impl_fireAll_throw(); + } + + //---------------------------------------------------------------- + Reference< XObjectInspectorUI > ComposedPropertyUIUpdate::getDelegatorUI() const + { + impl_checkDisposed(); + return m_xDelegatorUI; + } + + //---------------------------------------------------------------- + void SAL_CALL ComposedPropertyUIUpdate::dispose() + { + if ( impl_isDisposed() ) + return; + + OSL_ENSURE( m_nSuspendCounter == 0, "ComposedPropertyUIUpdate::dispose: still suspended, the changes will be lost!" ); + + for ( ImplMapHandlerToUI::const_iterator singleUI = m_pCollectedUIs->aHandlers.begin(); + singleUI != m_pCollectedUIs->aHandlers.end(); + ++singleUI + ) + { + singleUI->second->dispose(); + } + m_pCollectedUIs.reset( NULL ); + m_xDelegatorUI.set( NULL ); + } + + //---------------------------------------------------------------- + bool ComposedPropertyUIUpdate::shouldContinuePropertyHandling( const ::rtl::OUString& _rName ) const + { + if ( !m_pPropertyCheck ) + return true; + if ( m_pPropertyCheck->hasPropertyByName( _rName ) ) + return true; + return false; + } + +//........................................................................ +} // namespace pcr +//........................................................................ + |