Update ooo320-m1
[ooovba.git] / extensions / source / propctrlr / composeduiupdate.cxx
blob0f18eb4cd43c357b742313ea577a5d20753acde5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: composeduiupdate.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
33 #include "composeduiupdate.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
37 #include <com/sun/star/lang/DisposedException.hpp>
38 #include <com/sun/star/inspection/PropertyLineElement.hpp>
39 /** === end UNO includes === **/
40 #include <osl/mutex.hxx>
41 #include <rtl/ref.hxx>
43 #include <algorithm>
45 //........................................................................
46 namespace pcr
48 //........................................................................
50 /** === begin UNO using === **/
51 using ::com::sun::star::uno::Exception;
52 using ::com::sun::star::lang::DisposedException;
53 using ::com::sun::star::lang::NullPointerException;
54 using ::com::sun::star::inspection::XPropertyHandler;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::inspection::XObjectInspectorUI;
57 using ::com::sun::star::inspection::XPropertyControl;
58 using ::com::sun::star::uno::RuntimeException;
59 using ::com::sun::star::lang::NoSupportException;
60 using ::com::sun::star::inspection::XPropertyControlObserver;
61 /** === end UNO using === **/
63 namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement;
65 //====================================================================
66 //= helper
67 //====================================================================
68 namespace
70 struct HandlerLess : public ::std::binary_function < Reference< XPropertyHandler >
71 , Reference< XPropertyHandler >
72 , bool
75 bool operator()( const Reference< XPropertyHandler >& lhs, const Reference< XPropertyHandler >& rhs) const
77 return lhs.get() < rhs.get();
81 //================================================================
82 typedef ::std::set< ::rtl::OUString > StringBag;
83 typedef ::std::map< sal_Int16, StringBag > MapIntToStringBag;
86 //====================================================================
87 //= callbacks for CachedInspectorUI
88 //====================================================================
89 typedef void (ComposedPropertyUIUpdate::*FNotifySingleUIChange)();
91 //====================================================================
92 //= CachedInspectorUI
93 //====================================================================
94 typedef ::cppu::WeakImplHelper1 < ::com::sun::star::inspection::XObjectInspectorUI
95 > CachedInspectorUI_Base;
96 struct CachedInspectorUI : public CachedInspectorUI_Base
98 private:
99 ::osl::Mutex m_aMutex;
100 oslInterlockedCount m_refCount;
101 bool m_bDisposed;
102 ComposedPropertyUIUpdate&
103 m_rMaster;
104 FNotifySingleUIChange m_pUIChangeNotification;
106 // enablePropertyUI cache
107 StringBag aEnabledProperties;
108 StringBag aDisabledProperties;
110 // show/hidePropertyUI cache
111 StringBag aShownProperties;
112 StringBag aHiddenProperties;
114 // rebuildPropertyUI cache
115 StringBag aRebuiltProperties;
117 // showCategory cache
118 StringBag aShownCategories;
119 StringBag aHiddenCategories;
121 // enablePropertyUIElements cache
122 MapIntToStringBag aEnabledElements;
123 MapIntToStringBag aDisabledElements;
125 public:
126 typedef StringBag& (CachedInspectorUI::*FGetStringBag)();
128 // enablePropertyUI cache
129 StringBag& getEnabledProperties() { return aEnabledProperties; }
130 StringBag& getDisabledProperties() { return aDisabledProperties; }
132 // show/hidePropertyUI cache
133 StringBag& getShownProperties() { return aShownProperties; }
134 StringBag& getHiddenProperties() { return aHiddenProperties; }
136 // rebuildPropertyUI cache
137 StringBag& getRebuiltProperties() { return aRebuiltProperties; }
139 // showCategory cache
140 StringBag& getShownCategories() { return aShownCategories; }
141 StringBag& getHiddenCategories() { return aHiddenCategories; }
143 // enablePropertyUIElements
144 StringBag& getEnabledInputControls() { return aEnabledElements[ PropertyLineElement::InputControl ]; }
145 StringBag& getDisabledInputControls() { return aDisabledElements[ PropertyLineElement::InputControl ]; }
146 StringBag& getEnabledPrimaryButtons() { return aEnabledElements[ PropertyLineElement::PrimaryButton ]; }
147 StringBag& getDisabledPrimaryButtons() { return aDisabledElements[ PropertyLineElement::PrimaryButton ]; }
148 StringBag& getEnabledSecondaryButtons() { return aEnabledElements[ PropertyLineElement::SecondaryButton ]; }
149 StringBag& getDisabledSecondaryButtons() { return aDisabledElements[ PropertyLineElement::SecondaryButton ]; }
151 public:
152 CachedInspectorUI( ComposedPropertyUIUpdate& _rMaster, FNotifySingleUIChange _pUIChangeNotification );
154 /// disposes the instance
155 void dispose();
157 // XObjectInspectorUI overridables
158 virtual void SAL_CALL enablePropertyUI( const ::rtl::OUString& _rPropertyName, ::sal_Bool _bEnable ) throw (RuntimeException);
159 virtual void SAL_CALL enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, ::sal_Int16 _nElements, ::sal_Bool _bEnable ) throw (RuntimeException);
160 virtual void SAL_CALL rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
161 virtual void SAL_CALL showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
162 virtual void SAL_CALL hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
163 virtual void SAL_CALL showCategory( const ::rtl::OUString& _rCategory, ::sal_Bool _bShow ) throw (RuntimeException);
164 virtual Reference< XPropertyControl > SAL_CALL getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
165 virtual void SAL_CALL registerControlObserver( const Reference< XPropertyControlObserver >& Observer ) throw (RuntimeException);
166 virtual void SAL_CALL revokeControlObserver( const Reference< XPropertyControlObserver >& Observer ) throw (RuntimeException);
167 virtual void SAL_CALL setHelpSectionText( const ::rtl::OUString& _HelpText ) throw (NoSupportException, RuntimeException);
169 // UNOCompatibleNonUNOReference overridables
170 virtual void SAL_CALL acquire() throw();
171 virtual void SAL_CALL release() throw();
173 protected:
174 ~CachedInspectorUI();
176 /// determines whether the instance is already disposed
177 inline bool isDisposed() const { return m_bDisposed; }
179 /// throws an exception if the component is already disposed
180 void checkDisposed() const;
182 private:
183 void impl_markElementEnabledOrDisabled( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElementIdOrZero, sal_Bool _bEnable );
185 /** calls <member>m_pUIChangeNotification</member> at <member>m_rMaster</member>
187 void impl_notifySingleUIChange() const;
189 private:
190 CachedInspectorUI( const CachedInspectorUI& ); // never implemented
191 CachedInspectorUI& operator=( const CachedInspectorUI& ); // never implemented
193 private:
194 class MethodGuard;
195 friend class MethodGuard;
196 class MethodGuard : public ::osl::MutexGuard
198 public:
199 MethodGuard( CachedInspectorUI& rInstance )
200 : ::osl::MutexGuard( rInstance.m_aMutex )
202 rInstance.checkDisposed();
207 //----------------------------------------------------------------
208 CachedInspectorUI::CachedInspectorUI( ComposedPropertyUIUpdate& _rMaster, FNotifySingleUIChange _pUIChangeNotification )
209 :m_refCount( 0 )
210 ,m_bDisposed( false )
211 ,m_rMaster( _rMaster )
212 ,m_pUIChangeNotification( _pUIChangeNotification )
216 //----------------------------------------------------------------
217 CachedInspectorUI::~CachedInspectorUI()
221 //----------------------------------------------------------------
222 void CachedInspectorUI::dispose()
224 ::osl::MutexGuard aGuard( m_aMutex );
225 m_bDisposed = true;
227 clearContainer( aEnabledProperties );
228 clearContainer( aDisabledProperties );
229 clearContainer( aRebuiltProperties );
230 clearContainer( aShownProperties );
231 clearContainer( aHiddenProperties );
232 clearContainer( aShownCategories );
233 clearContainer( aHiddenCategories );
234 clearContainer( aEnabledElements );
235 clearContainer( aDisabledElements );
238 //----------------------------------------------------------------
239 void SAL_CALL CachedInspectorUI::acquire() throw()
241 osl_incrementInterlockedCount( &m_refCount );
244 //----------------------------------------------------------------
245 void SAL_CALL CachedInspectorUI::release() throw()
247 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
248 delete this;
252 //----------------------------------------------------------------
253 void CachedInspectorUI::checkDisposed() const
255 if ( isDisposed() )
256 throw DisposedException();
259 //----------------------------------------------------------------
260 namespace
262 void lcl_markStringKeyPositiveOrNegative( const ::rtl::OUString& _rKeyName, StringBag& _rPositives, StringBag& _rNegatives, sal_Bool _bMarkPositive )
264 if ( _bMarkPositive )
266 _rPositives.insert( _rKeyName );
267 // if the same key has been remember as in the "negative" list before, clear this information, since it's overruled
268 _rNegatives.erase( _rKeyName );
270 else
271 _rNegatives.insert( _rKeyName );
275 //----------------------------------------------------------------
276 void CachedInspectorUI::enablePropertyUI( const ::rtl::OUString& _rPropertyName, sal_Bool _bEnable ) throw (RuntimeException)
278 MethodGuard aGuard( *this );
279 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
280 return;
282 lcl_markStringKeyPositiveOrNegative( _rPropertyName, aEnabledProperties, aDisabledProperties, _bEnable );
283 impl_notifySingleUIChange();
286 //----------------------------------------------------------------
287 void CachedInspectorUI::impl_markElementEnabledOrDisabled( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElementIdOrZero, sal_Bool _bEnable )
289 if ( _nElementIdOrZero == 0 )
290 return;
292 lcl_markStringKeyPositiveOrNegative(
293 _rPropertyName,
294 aEnabledElements[ _nElementIdOrZero ],
295 aDisabledElements[ _nElementIdOrZero ],
296 _bEnable
300 //----------------------------------------------------------------
301 void CachedInspectorUI::impl_notifySingleUIChange() const
303 (m_rMaster.*m_pUIChangeNotification)();
306 //----------------------------------------------------------------
307 void CachedInspectorUI::enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElements, sal_Bool _bEnable ) throw (RuntimeException)
309 MethodGuard aGuard( *this );
310 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
311 return;
313 impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::InputControl, _bEnable );
314 impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::PrimaryButton, _bEnable );
315 impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::SecondaryButton, _bEnable );
317 impl_notifySingleUIChange();
320 //----------------------------------------------------------------
321 void CachedInspectorUI::rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
323 MethodGuard aGuard( *this );
324 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
325 return;
327 aRebuiltProperties.insert( _rPropertyName );
329 impl_notifySingleUIChange();
332 //----------------------------------------------------------------
333 void CachedInspectorUI::showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
335 MethodGuard aGuard( *this );
336 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
337 return;
339 aShownProperties.insert( _rPropertyName );
340 // if the same category has been hidden before, clear this information, since it's overruled
341 aHiddenProperties.erase( _rPropertyName );
343 impl_notifySingleUIChange();
346 //----------------------------------------------------------------
347 void CachedInspectorUI::hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
349 MethodGuard aGuard( *this );
350 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
351 return;
353 aHiddenProperties.insert( _rPropertyName );
354 impl_notifySingleUIChange();
357 //----------------------------------------------------------------
358 void CachedInspectorUI::showCategory( const ::rtl::OUString& _rCategory, sal_Bool _bShow ) throw (RuntimeException)
360 MethodGuard aGuard( *this );
362 lcl_markStringKeyPositiveOrNegative( _rCategory, aShownCategories, aHiddenCategories, _bShow );
363 impl_notifySingleUIChange();
366 //----------------------------------------------------------------
367 Reference< XPropertyControl > SAL_CALL CachedInspectorUI::getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
369 MethodGuard aGuard( *this );
370 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
371 return Reference< XPropertyControl >();
373 return m_rMaster.getDelegatorUI()->getPropertyControl( _rPropertyName );
376 //--------------------------------------------------------------------
377 void SAL_CALL CachedInspectorUI::registerControlObserver( const Reference< XPropertyControlObserver >& _Observer ) throw (RuntimeException)
379 OSL_ENSURE( false, "CachedInspectorUI::registerControlObserver: not expected to be called!" );
380 // CachedInspectorUI is used as context for the controls, and we don't expect them to
381 // register listeners themself
382 m_rMaster.getDelegatorUI()->registerControlObserver( _Observer );
385 //--------------------------------------------------------------------
386 void SAL_CALL CachedInspectorUI::revokeControlObserver( const Reference< XPropertyControlObserver >& _Observer ) throw (RuntimeException)
388 OSL_ENSURE( false, "CachedInspectorUI::revokeControlObserver: not expected to be called!" );
389 // CachedInspectorUI is used as context for the controls, and we don't expect them to
390 // register listeners themself
391 m_rMaster.getDelegatorUI()->revokeControlObserver( _Observer );
394 //----------------------------------------------------------------
395 void SAL_CALL CachedInspectorUI::setHelpSectionText( const ::rtl::OUString& _HelpText ) throw (NoSupportException, RuntimeException)
397 m_rMaster.getDelegatorUI()->setHelpSectionText( _HelpText );
400 //====================================================================
401 //= HandlerMap
402 //====================================================================
403 typedef ::std::map < Reference< XPropertyHandler >
404 , ::rtl::Reference< CachedInspectorUI >
405 , HandlerLess
406 > ImplMapHandlerToUI;
407 struct MapHandlerToUI
409 ImplMapHandlerToUI aHandlers;
412 //====================================================================
413 //= ComposedPropertyUIUpdate
414 //====================================================================
415 //----------------------------------------------------------------
416 ComposedPropertyUIUpdate::ComposedPropertyUIUpdate( const Reference< XObjectInspectorUI >& _rxDelegatorUI,
417 IPropertyExistenceCheck* _pPropertyCheck )
418 :m_pCollectedUIs( new MapHandlerToUI )
419 ,m_xDelegatorUI( _rxDelegatorUI )
420 ,m_nSuspendCounter( 0 )
421 ,m_pPropertyCheck( _pPropertyCheck )
423 if ( !m_xDelegatorUI.is() )
424 throw NullPointerException();
427 //----------------------------------------------------------------
428 ComposedPropertyUIUpdate::~ComposedPropertyUIUpdate( )
432 //----------------------------------------------------------------
433 Reference< XObjectInspectorUI > ComposedPropertyUIUpdate::getUIForPropertyHandler( const Reference< XPropertyHandler >& _rxHandler )
435 impl_checkDisposed();
437 ::rtl::Reference< CachedInspectorUI >& rUI = m_pCollectedUIs->aHandlers[ _rxHandler ];
438 if ( !rUI.is() )
439 rUI = new CachedInspectorUI( *this, &ComposedPropertyUIUpdate::callback_inspectorUIChanged_throw );
440 return rUI.get();
443 //----------------------------------------------------------------
444 namespace
446 //============================================================
447 //= StringBagCollector
448 //============================================================
449 /** an STL-compatible structure which collects strings from a CachedInspectorUI instances
451 struct StringBagCollector : public ::std::unary_function< ImplMapHandlerToUI::value_type, void >
453 private:
454 StringBag& m_rBag;
455 CachedInspectorUI::FGetStringBag m_pGetter;
457 public:
458 StringBagCollector( StringBag& _rBag, CachedInspectorUI::FGetStringBag _pGetter ) :m_rBag( _rBag ), m_pGetter( _pGetter ) { }
460 void operator()( const ImplMapHandlerToUI::value_type& _rUI )
462 StringBag& rBag( ((_rUI.second.get())->*m_pGetter)() );
463 m_rBag.insert( rBag.begin(), rBag.end() );
466 static void collectAll( StringBag& _rAll, const ImplMapHandlerToUI& _rMap, CachedInspectorUI::FGetStringBag _pGetter )
468 ::std::for_each( _rMap.begin(), _rMap.end(), StringBagCollector( _rAll, _pGetter ) );
472 //============================================================
473 //= StringBagClearer
474 //============================================================
475 /** an STL-compatible structure which cleans a certain string bag in a CachedInspectorUI instances
477 struct StringBagClearer : public ::std::unary_function< ImplMapHandlerToUI::value_type, void >
479 private:
480 CachedInspectorUI::FGetStringBag m_pGetter;
482 public:
483 StringBagClearer( CachedInspectorUI::FGetStringBag _pGetter ) :m_pGetter( _pGetter ) { }
485 void operator()( const ImplMapHandlerToUI::value_type& _rUI )
487 clearContainer( ((_rUI.second.get())->*m_pGetter)() );
490 static void clearAll( const ImplMapHandlerToUI& _rMap, CachedInspectorUI::FGetStringBag _pGetter )
492 ::std::for_each( _rMap.begin(), _rMap.end(), StringBagClearer( _pGetter ) );
496 //============================================================
497 //= FPropertyUISetter
498 //============================================================
499 /** a typedef for a ->XObjectInspectorUI member function taking a string
501 typedef void ( SAL_CALL XObjectInspectorUI::*FPropertyUISetter )( const ::rtl::OUString& );
503 //============================================================
504 //= PropertyUIOperator
505 //============================================================
506 /** an STL-compatible struct which calls a certain member method (taking a string) at a
507 given ->XObjectInspectorUI instance
509 struct PropertyUIOperator : public ::std::unary_function< ::rtl::OUString, void >
511 private:
512 Reference< XObjectInspectorUI > m_xUpdater;
513 FPropertyUISetter m_pSetter;
515 public:
516 PropertyUIOperator( const Reference< XObjectInspectorUI >& _rxInspectorUI, FPropertyUISetter _pSetter )
517 :m_xUpdater( _rxInspectorUI )
518 ,m_pSetter( _pSetter )
522 void operator()( const ::rtl::OUString& _rPropertyName )
524 ((m_xUpdater.get())->*m_pSetter)( _rPropertyName );
527 static void forEach( const StringBag& _rProperties, const Reference< XObjectInspectorUI >& _rxDelegatorUI, FPropertyUISetter _pSetter )
529 ::std::for_each( _rProperties.begin(), _rProperties.end(), PropertyUIOperator( _rxDelegatorUI, _pSetter ) );
533 //============================================================
534 //= IStringKeyBooleanUIUpdate
535 //============================================================
536 /** an interface which encapsulates access to a single aspect of the ->XObjectInspectorUI,
537 where this aspect is given by a string key, and has a boolean value.
539 class IStringKeyBooleanUIUpdate
541 public:
542 virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const = 0;
544 virtual ~IStringKeyBooleanUIUpdate() { }
547 //============================================================
548 //= FPropertyUIFlagSetter
549 //============================================================
550 /** an implementation of the ->IStringKeyBooleanUIUpdate interface which,
551 for a fixed ->XObjectInspectorUI instance and a fixed UI element (->PropertyLineElement),
552 updates this element for a given property with a given boolean flag
553 (->XObjectInspectorUI::enablePropertyUIElements)
555 class EnablePropertyUIElement : public IStringKeyBooleanUIUpdate
557 private:
558 Reference< XObjectInspectorUI > m_xUIUpdate;
559 sal_Int16 m_nElement;
561 public:
562 EnablePropertyUIElement( const Reference< XObjectInspectorUI >& _rxUIUpdate, sal_Int16 _nElement )
563 :m_xUIUpdate( _rxUIUpdate )
564 ,m_nElement( _nElement )
567 // IStringKeyBooleanUIUpdate
568 virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const;
571 //............................................................
572 void EnablePropertyUIElement::updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const
574 m_xUIUpdate->enablePropertyUIElements( _rKey, m_nElement, _bFlag );
577 //============================================================
578 //= FPropertyUIFlagSetter
579 //============================================================
580 /** a ->XObjectInspectorUI method taking a string and a boolean
582 typedef void ( SAL_CALL XObjectInspectorUI::*FPropertyUIFlagSetter )( const ::rtl::OUString&, sal_Bool );
584 //============================================================
585 //= DefaultStringKeyBooleanUIUpdate
586 //============================================================
587 /** an implementaiton of the ->IStringKeyBooleanUIUpdate interface which calls
588 am arbitrary ->XObjectInspectorUI method taking a string and a boolean flag
590 class DefaultStringKeyBooleanUIUpdate : public IStringKeyBooleanUIUpdate
592 private:
593 Reference< XObjectInspectorUI > m_xUIUpdate;
594 FPropertyUIFlagSetter m_pSetter;
596 public:
597 DefaultStringKeyBooleanUIUpdate( const Reference< XObjectInspectorUI >& _rxUIUpdate, FPropertyUIFlagSetter _pSetter );
598 // IStringKeyBooleanUIUpdate
599 virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const;
602 //............................................................
603 DefaultStringKeyBooleanUIUpdate::DefaultStringKeyBooleanUIUpdate( const Reference< XObjectInspectorUI >& _rxUIUpdate, FPropertyUIFlagSetter _pSetter )
604 :m_xUIUpdate( _rxUIUpdate )
605 ,m_pSetter( _pSetter )
609 //............................................................
610 void DefaultStringKeyBooleanUIUpdate::updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const
612 ((m_xUIUpdate.get())->*m_pSetter)( _rKey, _bFlag );
615 //============================================================
616 //= BooleanUIAspectUpdate
617 //============================================================
618 /** an STL-compatible structure which applies a ->IStringKeyBooleanUIUpdate::updateUIForKey
619 operation with a fixed boolean value, for a given string value
621 struct BooleanUIAspectUpdate : public ::std::unary_function< ::rtl::OUString, void >
623 private:
624 const IStringKeyBooleanUIUpdate& m_rUpdater;
625 sal_Bool m_bFlag;
627 public:
628 BooleanUIAspectUpdate( const IStringKeyBooleanUIUpdate& _rUpdater, sal_Bool _bFlag )
629 :m_rUpdater( _rUpdater )
630 ,m_bFlag( _bFlag )
634 void operator()( const ::rtl::OUString& _rPropertyName )
636 m_rUpdater.updateUIForKey( _rPropertyName, m_bFlag );
639 static void forEach( const StringBag& _rProperties, const IStringKeyBooleanUIUpdate& _rUpdater, sal_Bool _bFlag )
641 ::std::for_each( _rProperties.begin(), _rProperties.end(), BooleanUIAspectUpdate( _rUpdater, _bFlag ) );
645 //============================================================
646 //= BooleanUIAspectUpdate
647 //============================================================
648 /** an STL-compatible structure subtracting a given string from a fixed ->StringBag
650 struct StringBagComplement : public ::std::unary_function< ::rtl::OUString, void >
652 private:
653 StringBag& m_rMinuend;
655 public:
656 StringBagComplement( StringBag& _rMinuend ) :m_rMinuend( _rMinuend ) { }
658 void operator()( const ::rtl::OUString& _rPropertyToSubtract )
660 m_rMinuend.erase( _rPropertyToSubtract );
663 static void subtract( StringBag& _rMinuend, const StringBag& _rSubtrahend )
665 ::std::for_each( _rSubtrahend.begin(), _rSubtrahend.end(), StringBagComplement( _rMinuend ) );
669 //============================================================
670 //= BooleanUIAspectUpdate
671 //============================================================
672 void lcl_fireUIStateFlag(
673 const IStringKeyBooleanUIUpdate& _rUIUpdate,
674 const ImplMapHandlerToUI& _rHandlerUIs,
675 CachedInspectorUI::FGetStringBag _pGetPositives,
676 CachedInspectorUI::FGetStringBag _pGetNegatives
679 // all strings which are in the "positive" list of one handler
680 StringBag aAllPositives;
681 StringBagCollector::collectAll( aAllPositives, _rHandlerUIs, _pGetPositives );
683 // all strings which are in the "negative" list of one handler
684 StringBag aAllNegatives;
685 StringBagCollector::collectAll( aAllNegatives, _rHandlerUIs, _pGetNegatives );
687 // propagate the "negative" flags to the delegator UI
688 BooleanUIAspectUpdate::forEach( aAllNegatives, _rUIUpdate, sal_False );
690 // propagate the "positive" flags to the delegator UI, for all elements where _no_
691 // "negative" flag exists
692 StringBagComplement::subtract( aAllPositives, aAllNegatives );
693 BooleanUIAspectUpdate::forEach( aAllPositives, _rUIUpdate, sal_True );
695 // the "positive" request can be cleared no, only negative requests
696 // (such as "disable a property" or "hide a category") need to be preserved for the next round
697 StringBagClearer::clearAll( _rHandlerUIs, _pGetPositives );
701 //----------------------------------------------------------------
702 void ComposedPropertyUIUpdate::impl_fireEnablePropertyUI_throw()
704 lcl_fireUIStateFlag(
705 DefaultStringKeyBooleanUIUpdate( m_xDelegatorUI, &XObjectInspectorUI::enablePropertyUI ),
706 m_pCollectedUIs->aHandlers,
707 &CachedInspectorUI::getEnabledProperties,
708 &CachedInspectorUI::getDisabledProperties
712 //----------------------------------------------------------------
713 void ComposedPropertyUIUpdate::impl_fireRebuildPropertyUI_throw()
715 // collect all properties for which a rebuild request has been made
716 StringBag aAllRebuilt;
717 StringBagCollector::collectAll( aAllRebuilt, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getRebuiltProperties );
719 // rebuild all those properties
720 PropertyUIOperator::forEach( aAllRebuilt, m_xDelegatorUI, &XObjectInspectorUI::rebuildPropertyUI );
722 // clear the "properties to rebuild" at all handlers, since the request has been fulfilled now.
723 StringBagClearer::clearAll( m_pCollectedUIs->aHandlers, &CachedInspectorUI::getRebuiltProperties );
726 //----------------------------------------------------------------
727 void ComposedPropertyUIUpdate::impl_fireShowHidePropertyUI_throw()
729 // all properties which have been shown by at least one handler
730 StringBag aAllShown;
731 StringBagCollector::collectAll( aAllShown, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getShownProperties );
732 // all properties which have been hidden by at least one handler
733 StringBag aAllHidden;
734 StringBagCollector::collectAll( aAllHidden, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getHiddenProperties );
736 // hide properties as necessary
737 PropertyUIOperator::forEach( aAllHidden, m_xDelegatorUI, &XObjectInspectorUI::hidePropertyUI );
739 // for those properties which are hidden, ignore all "show" requests which other handlers might have had
740 StringBagComplement::subtract( aAllShown, aAllHidden );
742 // show properties
743 PropertyUIOperator::forEach( aAllShown, m_xDelegatorUI, &XObjectInspectorUI::showPropertyUI );
746 //----------------------------------------------------------------
747 void ComposedPropertyUIUpdate::impl_fireShowCategory_throw()
749 lcl_fireUIStateFlag(
750 DefaultStringKeyBooleanUIUpdate( m_xDelegatorUI, &XObjectInspectorUI::showCategory ),
751 m_pCollectedUIs->aHandlers,
752 &CachedInspectorUI::getShownCategories,
753 &CachedInspectorUI::getHiddenCategories
757 //----------------------------------------------------------------
758 void ComposedPropertyUIUpdate::impl_fireEnablePropertyUIElements_throw()
760 lcl_fireUIStateFlag(
761 EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::InputControl ),
762 m_pCollectedUIs->aHandlers,
763 &CachedInspectorUI::getEnabledInputControls,
764 &CachedInspectorUI::getDisabledInputControls
767 lcl_fireUIStateFlag(
768 EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::PrimaryButton ),
769 m_pCollectedUIs->aHandlers,
770 &CachedInspectorUI::getEnabledPrimaryButtons,
771 &CachedInspectorUI::getDisabledPrimaryButtons
774 lcl_fireUIStateFlag(
775 EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::SecondaryButton ),
776 m_pCollectedUIs->aHandlers,
777 &CachedInspectorUI::getEnabledSecondaryButtons,
778 &CachedInspectorUI::getDisabledSecondaryButtons
782 //----------------------------------------------------------------
783 void SAL_CALL ComposedPropertyUIUpdate::fire()
785 impl_checkDisposed();
786 impl_fireAll_throw();
789 //--------------------------------------------------------------------
790 void ComposedPropertyUIUpdate::impl_fireAll_throw()
792 OSL_PRECOND( !impl_isDisposed(), "ComposedPropertyUIUpdate::impl_fireAll_throw: already disposed, this will crash!" );
794 impl_fireEnablePropertyUI_throw();
795 impl_fireShowHidePropertyUI_throw();
796 impl_fireRebuildPropertyUI_throw();
797 impl_fireShowCategory_throw();
798 impl_fireEnablePropertyUIElements_throw();
801 //--------------------------------------------------------------------
802 void SAL_CALL ComposedPropertyUIUpdate::suspendAutoFire()
804 impl_checkDisposed();
805 osl_incrementInterlockedCount( &m_nSuspendCounter );
808 //--------------------------------------------------------------------
809 void SAL_CALL ComposedPropertyUIUpdate::resumeAutoFire()
811 impl_checkDisposed();
812 if ( 0 == osl_decrementInterlockedCount( &m_nSuspendCounter ) )
813 impl_fireAll_throw();
816 //----------------------------------------------------------------
817 void ComposedPropertyUIUpdate::impl_checkDisposed() const
819 if ( impl_isDisposed() )
820 throw DisposedException();
823 //----------------------------------------------------------------
824 void ComposedPropertyUIUpdate::callback_inspectorUIChanged_throw()
826 if ( 0 == m_nSuspendCounter )
827 impl_fireAll_throw();
830 //----------------------------------------------------------------
831 Reference< XObjectInspectorUI > ComposedPropertyUIUpdate::getDelegatorUI() const
833 impl_checkDisposed();
834 return m_xDelegatorUI;
837 //----------------------------------------------------------------
838 void SAL_CALL ComposedPropertyUIUpdate::dispose()
840 if ( impl_isDisposed() )
841 return;
843 OSL_ENSURE( m_nSuspendCounter == 0, "ComposedPropertyUIUpdate::dispose: still suspended, the changes will be lost!" );
845 for ( ImplMapHandlerToUI::const_iterator singleUI = m_pCollectedUIs->aHandlers.begin();
846 singleUI != m_pCollectedUIs->aHandlers.end();
847 ++singleUI
850 singleUI->second->dispose();
852 m_pCollectedUIs.reset( NULL );
853 m_xDelegatorUI.set( NULL );
856 //----------------------------------------------------------------
857 bool ComposedPropertyUIUpdate::shouldContinuePropertyHandling( const ::rtl::OUString& _rName ) const
859 if ( !m_pPropertyCheck )
860 return true;
861 if ( m_pPropertyCheck->hasPropertyByName( _rName ) )
862 return true;
863 return false;
866 //........................................................................
867 } // namespace pcr
868 //........................................................................