merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / propctrlr / composeduiupdate.cxx
blobc9659d076de5d0b7645677136375054849c2c1f3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include "composeduiupdate.hxx"
32 /** === begin UNO includes === **/
33 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
34 #include <com/sun/star/lang/DisposedException.hpp>
35 #include <com/sun/star/inspection/PropertyLineElement.hpp>
36 /** === end UNO includes === **/
37 #include <osl/mutex.hxx>
38 #include <rtl/ref.hxx>
40 #include <algorithm>
42 //........................................................................
43 namespace pcr
45 //........................................................................
47 /** === begin UNO using === **/
48 using ::com::sun::star::uno::Exception;
49 using ::com::sun::star::lang::DisposedException;
50 using ::com::sun::star::lang::NullPointerException;
51 using ::com::sun::star::inspection::XPropertyHandler;
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::inspection::XObjectInspectorUI;
54 using ::com::sun::star::inspection::XPropertyControl;
55 using ::com::sun::star::uno::RuntimeException;
56 using ::com::sun::star::lang::NoSupportException;
57 using ::com::sun::star::inspection::XPropertyControlObserver;
58 /** === end UNO using === **/
60 namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement;
62 //====================================================================
63 //= helper
64 //====================================================================
65 namespace
67 struct HandlerLess : public ::std::binary_function < Reference< XPropertyHandler >
68 , Reference< XPropertyHandler >
69 , bool
72 bool operator()( const Reference< XPropertyHandler >& lhs, const Reference< XPropertyHandler >& rhs) const
74 return lhs.get() < rhs.get();
78 //================================================================
79 typedef ::std::set< ::rtl::OUString > StringBag;
80 typedef ::std::map< sal_Int16, StringBag > MapIntToStringBag;
83 //====================================================================
84 //= callbacks for CachedInspectorUI
85 //====================================================================
86 typedef void (ComposedPropertyUIUpdate::*FNotifySingleUIChange)();
88 //====================================================================
89 //= CachedInspectorUI
90 //====================================================================
91 typedef ::cppu::WeakImplHelper1 < ::com::sun::star::inspection::XObjectInspectorUI
92 > CachedInspectorUI_Base;
93 struct CachedInspectorUI : public CachedInspectorUI_Base
95 private:
96 ::osl::Mutex m_aMutex;
97 oslInterlockedCount m_refCount;
98 bool m_bDisposed;
99 ComposedPropertyUIUpdate&
100 m_rMaster;
101 FNotifySingleUIChange m_pUIChangeNotification;
103 // enablePropertyUI cache
104 StringBag aEnabledProperties;
105 StringBag aDisabledProperties;
107 // show/hidePropertyUI cache
108 StringBag aShownProperties;
109 StringBag aHiddenProperties;
111 // rebuildPropertyUI cache
112 StringBag aRebuiltProperties;
114 // showCategory cache
115 StringBag aShownCategories;
116 StringBag aHiddenCategories;
118 // enablePropertyUIElements cache
119 MapIntToStringBag aEnabledElements;
120 MapIntToStringBag aDisabledElements;
122 public:
123 typedef StringBag& (CachedInspectorUI::*FGetStringBag)();
125 // enablePropertyUI cache
126 StringBag& getEnabledProperties() { return aEnabledProperties; }
127 StringBag& getDisabledProperties() { return aDisabledProperties; }
129 // show/hidePropertyUI cache
130 StringBag& getShownProperties() { return aShownProperties; }
131 StringBag& getHiddenProperties() { return aHiddenProperties; }
133 // rebuildPropertyUI cache
134 StringBag& getRebuiltProperties() { return aRebuiltProperties; }
136 // showCategory cache
137 StringBag& getShownCategories() { return aShownCategories; }
138 StringBag& getHiddenCategories() { return aHiddenCategories; }
140 // enablePropertyUIElements
141 StringBag& getEnabledInputControls() { return aEnabledElements[ PropertyLineElement::InputControl ]; }
142 StringBag& getDisabledInputControls() { return aDisabledElements[ PropertyLineElement::InputControl ]; }
143 StringBag& getEnabledPrimaryButtons() { return aEnabledElements[ PropertyLineElement::PrimaryButton ]; }
144 StringBag& getDisabledPrimaryButtons() { return aDisabledElements[ PropertyLineElement::PrimaryButton ]; }
145 StringBag& getEnabledSecondaryButtons() { return aEnabledElements[ PropertyLineElement::SecondaryButton ]; }
146 StringBag& getDisabledSecondaryButtons() { return aDisabledElements[ PropertyLineElement::SecondaryButton ]; }
148 public:
149 CachedInspectorUI( ComposedPropertyUIUpdate& _rMaster, FNotifySingleUIChange _pUIChangeNotification );
151 /// disposes the instance
152 void dispose();
154 // XObjectInspectorUI overridables
155 virtual void SAL_CALL enablePropertyUI( const ::rtl::OUString& _rPropertyName, ::sal_Bool _bEnable ) throw (RuntimeException);
156 virtual void SAL_CALL enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, ::sal_Int16 _nElements, ::sal_Bool _bEnable ) throw (RuntimeException);
157 virtual void SAL_CALL rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
158 virtual void SAL_CALL showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
159 virtual void SAL_CALL hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
160 virtual void SAL_CALL showCategory( const ::rtl::OUString& _rCategory, ::sal_Bool _bShow ) throw (RuntimeException);
161 virtual Reference< XPropertyControl > SAL_CALL getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException);
162 virtual void SAL_CALL registerControlObserver( const Reference< XPropertyControlObserver >& Observer ) throw (RuntimeException);
163 virtual void SAL_CALL revokeControlObserver( const Reference< XPropertyControlObserver >& Observer ) throw (RuntimeException);
164 virtual void SAL_CALL setHelpSectionText( const ::rtl::OUString& _HelpText ) throw (NoSupportException, RuntimeException);
166 // UNOCompatibleNonUNOReference overridables
167 virtual void SAL_CALL acquire() throw();
168 virtual void SAL_CALL release() throw();
170 protected:
171 ~CachedInspectorUI();
173 /// determines whether the instance is already disposed
174 inline bool isDisposed() const { return m_bDisposed; }
176 /// throws an exception if the component is already disposed
177 void checkDisposed() const;
179 private:
180 void impl_markElementEnabledOrDisabled( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElementIdOrZero, sal_Bool _bEnable );
182 /** calls <member>m_pUIChangeNotification</member> at <member>m_rMaster</member>
184 void impl_notifySingleUIChange() const;
186 private:
187 CachedInspectorUI( const CachedInspectorUI& ); // never implemented
188 CachedInspectorUI& operator=( const CachedInspectorUI& ); // never implemented
190 private:
191 class MethodGuard;
192 friend class MethodGuard;
193 class MethodGuard : public ::osl::MutexGuard
195 public:
196 MethodGuard( CachedInspectorUI& rInstance )
197 : ::osl::MutexGuard( rInstance.m_aMutex )
199 rInstance.checkDisposed();
204 //----------------------------------------------------------------
205 CachedInspectorUI::CachedInspectorUI( ComposedPropertyUIUpdate& _rMaster, FNotifySingleUIChange _pUIChangeNotification )
206 :m_refCount( 0 )
207 ,m_bDisposed( false )
208 ,m_rMaster( _rMaster )
209 ,m_pUIChangeNotification( _pUIChangeNotification )
213 //----------------------------------------------------------------
214 CachedInspectorUI::~CachedInspectorUI()
218 //----------------------------------------------------------------
219 void CachedInspectorUI::dispose()
221 ::osl::MutexGuard aGuard( m_aMutex );
222 m_bDisposed = true;
224 clearContainer( aEnabledProperties );
225 clearContainer( aDisabledProperties );
226 clearContainer( aRebuiltProperties );
227 clearContainer( aShownProperties );
228 clearContainer( aHiddenProperties );
229 clearContainer( aShownCategories );
230 clearContainer( aHiddenCategories );
231 clearContainer( aEnabledElements );
232 clearContainer( aDisabledElements );
235 //----------------------------------------------------------------
236 void SAL_CALL CachedInspectorUI::acquire() throw()
238 osl_incrementInterlockedCount( &m_refCount );
241 //----------------------------------------------------------------
242 void SAL_CALL CachedInspectorUI::release() throw()
244 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
245 delete this;
249 //----------------------------------------------------------------
250 void CachedInspectorUI::checkDisposed() const
252 if ( isDisposed() )
253 throw DisposedException();
256 //----------------------------------------------------------------
257 namespace
259 void lcl_markStringKeyPositiveOrNegative( const ::rtl::OUString& _rKeyName, StringBag& _rPositives, StringBag& _rNegatives, sal_Bool _bMarkPositive )
261 if ( _bMarkPositive )
263 _rPositives.insert( _rKeyName );
264 // if the same key has been remember as in the "negative" list before, clear this information, since it's overruled
265 _rNegatives.erase( _rKeyName );
267 else
268 _rNegatives.insert( _rKeyName );
272 //----------------------------------------------------------------
273 void CachedInspectorUI::enablePropertyUI( const ::rtl::OUString& _rPropertyName, sal_Bool _bEnable ) throw (RuntimeException)
275 MethodGuard aGuard( *this );
276 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
277 return;
279 lcl_markStringKeyPositiveOrNegative( _rPropertyName, aEnabledProperties, aDisabledProperties, _bEnable );
280 impl_notifySingleUIChange();
283 //----------------------------------------------------------------
284 void CachedInspectorUI::impl_markElementEnabledOrDisabled( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElementIdOrZero, sal_Bool _bEnable )
286 if ( _nElementIdOrZero == 0 )
287 return;
289 lcl_markStringKeyPositiveOrNegative(
290 _rPropertyName,
291 aEnabledElements[ _nElementIdOrZero ],
292 aDisabledElements[ _nElementIdOrZero ],
293 _bEnable
297 //----------------------------------------------------------------
298 void CachedInspectorUI::impl_notifySingleUIChange() const
300 (m_rMaster.*m_pUIChangeNotification)();
303 //----------------------------------------------------------------
304 void CachedInspectorUI::enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElements, sal_Bool _bEnable ) throw (RuntimeException)
306 MethodGuard aGuard( *this );
307 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
308 return;
310 impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::InputControl, _bEnable );
311 impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::PrimaryButton, _bEnable );
312 impl_markElementEnabledOrDisabled( _rPropertyName, _nElements & PropertyLineElement::SecondaryButton, _bEnable );
314 impl_notifySingleUIChange();
317 //----------------------------------------------------------------
318 void CachedInspectorUI::rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
320 MethodGuard aGuard( *this );
321 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
322 return;
324 aRebuiltProperties.insert( _rPropertyName );
326 impl_notifySingleUIChange();
329 //----------------------------------------------------------------
330 void CachedInspectorUI::showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
332 MethodGuard aGuard( *this );
333 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
334 return;
336 aShownProperties.insert( _rPropertyName );
337 // if the same category has been hidden before, clear this information, since it's overruled
338 aHiddenProperties.erase( _rPropertyName );
340 impl_notifySingleUIChange();
343 //----------------------------------------------------------------
344 void CachedInspectorUI::hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
346 MethodGuard aGuard( *this );
347 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
348 return;
350 aHiddenProperties.insert( _rPropertyName );
351 impl_notifySingleUIChange();
354 //----------------------------------------------------------------
355 void CachedInspectorUI::showCategory( const ::rtl::OUString& _rCategory, sal_Bool _bShow ) throw (RuntimeException)
357 MethodGuard aGuard( *this );
359 lcl_markStringKeyPositiveOrNegative( _rCategory, aShownCategories, aHiddenCategories, _bShow );
360 impl_notifySingleUIChange();
363 //----------------------------------------------------------------
364 Reference< XPropertyControl > SAL_CALL CachedInspectorUI::getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
366 MethodGuard aGuard( *this );
367 if ( !m_rMaster.shouldContinuePropertyHandling( _rPropertyName ) )
368 return Reference< XPropertyControl >();
370 return m_rMaster.getDelegatorUI()->getPropertyControl( _rPropertyName );
373 //--------------------------------------------------------------------
374 void SAL_CALL CachedInspectorUI::registerControlObserver( const Reference< XPropertyControlObserver >& _Observer ) throw (RuntimeException)
376 OSL_ENSURE( false, "CachedInspectorUI::registerControlObserver: not expected to be called!" );
377 // CachedInspectorUI is used as context for the controls, and we don't expect them to
378 // register listeners themself
379 m_rMaster.getDelegatorUI()->registerControlObserver( _Observer );
382 //--------------------------------------------------------------------
383 void SAL_CALL CachedInspectorUI::revokeControlObserver( const Reference< XPropertyControlObserver >& _Observer ) throw (RuntimeException)
385 OSL_ENSURE( false, "CachedInspectorUI::revokeControlObserver: not expected to be called!" );
386 // CachedInspectorUI is used as context for the controls, and we don't expect them to
387 // register listeners themself
388 m_rMaster.getDelegatorUI()->revokeControlObserver( _Observer );
391 //----------------------------------------------------------------
392 void SAL_CALL CachedInspectorUI::setHelpSectionText( const ::rtl::OUString& _HelpText ) throw (NoSupportException, RuntimeException)
394 m_rMaster.getDelegatorUI()->setHelpSectionText( _HelpText );
397 //====================================================================
398 //= HandlerMap
399 //====================================================================
400 typedef ::std::map < Reference< XPropertyHandler >
401 , ::rtl::Reference< CachedInspectorUI >
402 , HandlerLess
403 > ImplMapHandlerToUI;
404 struct MapHandlerToUI
406 ImplMapHandlerToUI aHandlers;
409 //====================================================================
410 //= ComposedPropertyUIUpdate
411 //====================================================================
412 //----------------------------------------------------------------
413 ComposedPropertyUIUpdate::ComposedPropertyUIUpdate( const Reference< XObjectInspectorUI >& _rxDelegatorUI,
414 IPropertyExistenceCheck* _pPropertyCheck )
415 :m_pCollectedUIs( new MapHandlerToUI )
416 ,m_xDelegatorUI( _rxDelegatorUI )
417 ,m_nSuspendCounter( 0 )
418 ,m_pPropertyCheck( _pPropertyCheck )
420 if ( !m_xDelegatorUI.is() )
421 throw NullPointerException();
424 //----------------------------------------------------------------
425 ComposedPropertyUIUpdate::~ComposedPropertyUIUpdate( )
429 //----------------------------------------------------------------
430 Reference< XObjectInspectorUI > ComposedPropertyUIUpdate::getUIForPropertyHandler( const Reference< XPropertyHandler >& _rxHandler )
432 impl_checkDisposed();
434 ::rtl::Reference< CachedInspectorUI >& rUI = m_pCollectedUIs->aHandlers[ _rxHandler ];
435 if ( !rUI.is() )
436 rUI = new CachedInspectorUI( *this, &ComposedPropertyUIUpdate::callback_inspectorUIChanged_throw );
437 return rUI.get();
440 //----------------------------------------------------------------
441 namespace
443 //============================================================
444 //= StringBagCollector
445 //============================================================
446 /** an STL-compatible structure which collects strings from a CachedInspectorUI instances
448 struct StringBagCollector : public ::std::unary_function< ImplMapHandlerToUI::value_type, void >
450 private:
451 StringBag& m_rBag;
452 CachedInspectorUI::FGetStringBag m_pGetter;
454 public:
455 StringBagCollector( StringBag& _rBag, CachedInspectorUI::FGetStringBag _pGetter ) :m_rBag( _rBag ), m_pGetter( _pGetter ) { }
457 void operator()( const ImplMapHandlerToUI::value_type& _rUI )
459 StringBag& rBag( ((_rUI.second.get())->*m_pGetter)() );
460 m_rBag.insert( rBag.begin(), rBag.end() );
463 static void collectAll( StringBag& _rAll, const ImplMapHandlerToUI& _rMap, CachedInspectorUI::FGetStringBag _pGetter )
465 ::std::for_each( _rMap.begin(), _rMap.end(), StringBagCollector( _rAll, _pGetter ) );
469 //============================================================
470 //= StringBagClearer
471 //============================================================
472 /** an STL-compatible structure which cleans a certain string bag in a CachedInspectorUI instances
474 struct StringBagClearer : public ::std::unary_function< ImplMapHandlerToUI::value_type, void >
476 private:
477 CachedInspectorUI::FGetStringBag m_pGetter;
479 public:
480 StringBagClearer( CachedInspectorUI::FGetStringBag _pGetter ) :m_pGetter( _pGetter ) { }
482 void operator()( const ImplMapHandlerToUI::value_type& _rUI )
484 clearContainer( ((_rUI.second.get())->*m_pGetter)() );
487 static void clearAll( const ImplMapHandlerToUI& _rMap, CachedInspectorUI::FGetStringBag _pGetter )
489 ::std::for_each( _rMap.begin(), _rMap.end(), StringBagClearer( _pGetter ) );
493 //============================================================
494 //= FPropertyUISetter
495 //============================================================
496 /** a typedef for a ->XObjectInspectorUI member function taking a string
498 typedef void ( SAL_CALL XObjectInspectorUI::*FPropertyUISetter )( const ::rtl::OUString& );
500 //============================================================
501 //= PropertyUIOperator
502 //============================================================
503 /** an STL-compatible struct which calls a certain member method (taking a string) at a
504 given ->XObjectInspectorUI instance
506 struct PropertyUIOperator : public ::std::unary_function< ::rtl::OUString, void >
508 private:
509 Reference< XObjectInspectorUI > m_xUpdater;
510 FPropertyUISetter m_pSetter;
512 public:
513 PropertyUIOperator( const Reference< XObjectInspectorUI >& _rxInspectorUI, FPropertyUISetter _pSetter )
514 :m_xUpdater( _rxInspectorUI )
515 ,m_pSetter( _pSetter )
519 void operator()( const ::rtl::OUString& _rPropertyName )
521 ((m_xUpdater.get())->*m_pSetter)( _rPropertyName );
524 static void forEach( const StringBag& _rProperties, const Reference< XObjectInspectorUI >& _rxDelegatorUI, FPropertyUISetter _pSetter )
526 ::std::for_each( _rProperties.begin(), _rProperties.end(), PropertyUIOperator( _rxDelegatorUI, _pSetter ) );
530 //============================================================
531 //= IStringKeyBooleanUIUpdate
532 //============================================================
533 /** an interface which encapsulates access to a single aspect of the ->XObjectInspectorUI,
534 where this aspect is given by a string key, and has a boolean value.
536 class IStringKeyBooleanUIUpdate
538 public:
539 virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const = 0;
541 virtual ~IStringKeyBooleanUIUpdate() { }
544 //============================================================
545 //= FPropertyUIFlagSetter
546 //============================================================
547 /** an implementation of the ->IStringKeyBooleanUIUpdate interface which,
548 for a fixed ->XObjectInspectorUI instance and a fixed UI element (->PropertyLineElement),
549 updates this element for a given property with a given boolean flag
550 (->XObjectInspectorUI::enablePropertyUIElements)
552 class EnablePropertyUIElement : public IStringKeyBooleanUIUpdate
554 private:
555 Reference< XObjectInspectorUI > m_xUIUpdate;
556 sal_Int16 m_nElement;
558 public:
559 EnablePropertyUIElement( const Reference< XObjectInspectorUI >& _rxUIUpdate, sal_Int16 _nElement )
560 :m_xUIUpdate( _rxUIUpdate )
561 ,m_nElement( _nElement )
564 // IStringKeyBooleanUIUpdate
565 virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const;
568 //............................................................
569 void EnablePropertyUIElement::updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const
571 m_xUIUpdate->enablePropertyUIElements( _rKey, m_nElement, _bFlag );
574 //============================================================
575 //= FPropertyUIFlagSetter
576 //============================================================
577 /** a ->XObjectInspectorUI method taking a string and a boolean
579 typedef void ( SAL_CALL XObjectInspectorUI::*FPropertyUIFlagSetter )( const ::rtl::OUString&, sal_Bool );
581 //============================================================
582 //= DefaultStringKeyBooleanUIUpdate
583 //============================================================
584 /** an implementaiton of the ->IStringKeyBooleanUIUpdate interface which calls
585 am arbitrary ->XObjectInspectorUI method taking a string and a boolean flag
587 class DefaultStringKeyBooleanUIUpdate : public IStringKeyBooleanUIUpdate
589 private:
590 Reference< XObjectInspectorUI > m_xUIUpdate;
591 FPropertyUIFlagSetter m_pSetter;
593 public:
594 DefaultStringKeyBooleanUIUpdate( const Reference< XObjectInspectorUI >& _rxUIUpdate, FPropertyUIFlagSetter _pSetter );
595 // IStringKeyBooleanUIUpdate
596 virtual void updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const;
599 //............................................................
600 DefaultStringKeyBooleanUIUpdate::DefaultStringKeyBooleanUIUpdate( const Reference< XObjectInspectorUI >& _rxUIUpdate, FPropertyUIFlagSetter _pSetter )
601 :m_xUIUpdate( _rxUIUpdate )
602 ,m_pSetter( _pSetter )
606 //............................................................
607 void DefaultStringKeyBooleanUIUpdate::updateUIForKey( const ::rtl::OUString& _rKey, sal_Bool _bFlag ) const
609 ((m_xUIUpdate.get())->*m_pSetter)( _rKey, _bFlag );
612 //============================================================
613 //= BooleanUIAspectUpdate
614 //============================================================
615 /** an STL-compatible structure which applies a ->IStringKeyBooleanUIUpdate::updateUIForKey
616 operation with a fixed boolean value, for a given string value
618 struct BooleanUIAspectUpdate : public ::std::unary_function< ::rtl::OUString, void >
620 private:
621 const IStringKeyBooleanUIUpdate& m_rUpdater;
622 sal_Bool m_bFlag;
624 public:
625 BooleanUIAspectUpdate( const IStringKeyBooleanUIUpdate& _rUpdater, sal_Bool _bFlag )
626 :m_rUpdater( _rUpdater )
627 ,m_bFlag( _bFlag )
631 void operator()( const ::rtl::OUString& _rPropertyName )
633 m_rUpdater.updateUIForKey( _rPropertyName, m_bFlag );
636 static void forEach( const StringBag& _rProperties, const IStringKeyBooleanUIUpdate& _rUpdater, sal_Bool _bFlag )
638 ::std::for_each( _rProperties.begin(), _rProperties.end(), BooleanUIAspectUpdate( _rUpdater, _bFlag ) );
642 //============================================================
643 //= BooleanUIAspectUpdate
644 //============================================================
645 /** an STL-compatible structure subtracting a given string from a fixed ->StringBag
647 struct StringBagComplement : public ::std::unary_function< ::rtl::OUString, void >
649 private:
650 StringBag& m_rMinuend;
652 public:
653 StringBagComplement( StringBag& _rMinuend ) :m_rMinuend( _rMinuend ) { }
655 void operator()( const ::rtl::OUString& _rPropertyToSubtract )
657 m_rMinuend.erase( _rPropertyToSubtract );
660 static void subtract( StringBag& _rMinuend, const StringBag& _rSubtrahend )
662 ::std::for_each( _rSubtrahend.begin(), _rSubtrahend.end(), StringBagComplement( _rMinuend ) );
666 //============================================================
667 //= BooleanUIAspectUpdate
668 //============================================================
669 void lcl_fireUIStateFlag(
670 const IStringKeyBooleanUIUpdate& _rUIUpdate,
671 const ImplMapHandlerToUI& _rHandlerUIs,
672 CachedInspectorUI::FGetStringBag _pGetPositives,
673 CachedInspectorUI::FGetStringBag _pGetNegatives
676 // all strings which are in the "positive" list of one handler
677 StringBag aAllPositives;
678 StringBagCollector::collectAll( aAllPositives, _rHandlerUIs, _pGetPositives );
680 // all strings which are in the "negative" list of one handler
681 StringBag aAllNegatives;
682 StringBagCollector::collectAll( aAllNegatives, _rHandlerUIs, _pGetNegatives );
684 // propagate the "negative" flags to the delegator UI
685 BooleanUIAspectUpdate::forEach( aAllNegatives, _rUIUpdate, sal_False );
687 // propagate the "positive" flags to the delegator UI, for all elements where _no_
688 // "negative" flag exists
689 StringBagComplement::subtract( aAllPositives, aAllNegatives );
690 BooleanUIAspectUpdate::forEach( aAllPositives, _rUIUpdate, sal_True );
692 // the "positive" request can be cleared no, only negative requests
693 // (such as "disable a property" or "hide a category") need to be preserved for the next round
694 StringBagClearer::clearAll( _rHandlerUIs, _pGetPositives );
698 //----------------------------------------------------------------
699 void ComposedPropertyUIUpdate::impl_fireEnablePropertyUI_throw()
701 lcl_fireUIStateFlag(
702 DefaultStringKeyBooleanUIUpdate( m_xDelegatorUI, &XObjectInspectorUI::enablePropertyUI ),
703 m_pCollectedUIs->aHandlers,
704 &CachedInspectorUI::getEnabledProperties,
705 &CachedInspectorUI::getDisabledProperties
709 //----------------------------------------------------------------
710 void ComposedPropertyUIUpdate::impl_fireRebuildPropertyUI_throw()
712 // collect all properties for which a rebuild request has been made
713 StringBag aAllRebuilt;
714 StringBagCollector::collectAll( aAllRebuilt, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getRebuiltProperties );
716 // rebuild all those properties
717 PropertyUIOperator::forEach( aAllRebuilt, m_xDelegatorUI, &XObjectInspectorUI::rebuildPropertyUI );
719 // clear the "properties to rebuild" at all handlers, since the request has been fulfilled now.
720 StringBagClearer::clearAll( m_pCollectedUIs->aHandlers, &CachedInspectorUI::getRebuiltProperties );
723 //----------------------------------------------------------------
724 void ComposedPropertyUIUpdate::impl_fireShowHidePropertyUI_throw()
726 // all properties which have been shown by at least one handler
727 StringBag aAllShown;
728 StringBagCollector::collectAll( aAllShown, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getShownProperties );
729 // all properties which have been hidden by at least one handler
730 StringBag aAllHidden;
731 StringBagCollector::collectAll( aAllHidden, m_pCollectedUIs->aHandlers, &CachedInspectorUI::getHiddenProperties );
733 // hide properties as necessary
734 PropertyUIOperator::forEach( aAllHidden, m_xDelegatorUI, &XObjectInspectorUI::hidePropertyUI );
736 // for those properties which are hidden, ignore all "show" requests which other handlers might have had
737 StringBagComplement::subtract( aAllShown, aAllHidden );
739 // show properties
740 PropertyUIOperator::forEach( aAllShown, m_xDelegatorUI, &XObjectInspectorUI::showPropertyUI );
743 //----------------------------------------------------------------
744 void ComposedPropertyUIUpdate::impl_fireShowCategory_throw()
746 lcl_fireUIStateFlag(
747 DefaultStringKeyBooleanUIUpdate( m_xDelegatorUI, &XObjectInspectorUI::showCategory ),
748 m_pCollectedUIs->aHandlers,
749 &CachedInspectorUI::getShownCategories,
750 &CachedInspectorUI::getHiddenCategories
754 //----------------------------------------------------------------
755 void ComposedPropertyUIUpdate::impl_fireEnablePropertyUIElements_throw()
757 lcl_fireUIStateFlag(
758 EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::InputControl ),
759 m_pCollectedUIs->aHandlers,
760 &CachedInspectorUI::getEnabledInputControls,
761 &CachedInspectorUI::getDisabledInputControls
764 lcl_fireUIStateFlag(
765 EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::PrimaryButton ),
766 m_pCollectedUIs->aHandlers,
767 &CachedInspectorUI::getEnabledPrimaryButtons,
768 &CachedInspectorUI::getDisabledPrimaryButtons
771 lcl_fireUIStateFlag(
772 EnablePropertyUIElement( m_xDelegatorUI, PropertyLineElement::SecondaryButton ),
773 m_pCollectedUIs->aHandlers,
774 &CachedInspectorUI::getEnabledSecondaryButtons,
775 &CachedInspectorUI::getDisabledSecondaryButtons
779 //--------------------------------------------------------------------
780 void ComposedPropertyUIUpdate::impl_fireAll_throw()
782 OSL_PRECOND( !impl_isDisposed(), "ComposedPropertyUIUpdate::impl_fireAll_throw: already disposed, this will crash!" );
784 impl_fireEnablePropertyUI_throw();
785 impl_fireShowHidePropertyUI_throw();
786 impl_fireRebuildPropertyUI_throw();
787 impl_fireShowCategory_throw();
788 impl_fireEnablePropertyUIElements_throw();
791 //--------------------------------------------------------------------
792 void SAL_CALL ComposedPropertyUIUpdate::suspendAutoFire()
794 impl_checkDisposed();
795 osl_incrementInterlockedCount( &m_nSuspendCounter );
798 //--------------------------------------------------------------------
799 void SAL_CALL ComposedPropertyUIUpdate::resumeAutoFire()
801 impl_checkDisposed();
802 if ( 0 == osl_decrementInterlockedCount( &m_nSuspendCounter ) )
803 impl_fireAll_throw();
806 //----------------------------------------------------------------
807 void ComposedPropertyUIUpdate::impl_checkDisposed() const
809 if ( impl_isDisposed() )
810 throw DisposedException();
813 //----------------------------------------------------------------
814 void ComposedPropertyUIUpdate::callback_inspectorUIChanged_throw()
816 if ( 0 == m_nSuspendCounter )
817 impl_fireAll_throw();
820 //----------------------------------------------------------------
821 Reference< XObjectInspectorUI > ComposedPropertyUIUpdate::getDelegatorUI() const
823 impl_checkDisposed();
824 return m_xDelegatorUI;
827 //----------------------------------------------------------------
828 void SAL_CALL ComposedPropertyUIUpdate::dispose()
830 if ( impl_isDisposed() )
831 return;
833 OSL_ENSURE( m_nSuspendCounter == 0, "ComposedPropertyUIUpdate::dispose: still suspended, the changes will be lost!" );
835 for ( ImplMapHandlerToUI::const_iterator singleUI = m_pCollectedUIs->aHandlers.begin();
836 singleUI != m_pCollectedUIs->aHandlers.end();
837 ++singleUI
840 singleUI->second->dispose();
842 m_pCollectedUIs.reset( NULL );
843 m_xDelegatorUI.set( NULL );
846 //----------------------------------------------------------------
847 bool ComposedPropertyUIUpdate::shouldContinuePropertyHandling( const ::rtl::OUString& _rName ) const
849 if ( !m_pPropertyCheck )
850 return true;
851 if ( m_pPropertyCheck->hasPropertyByName( _rName ) )
852 return true;
853 return false;
856 //........................................................................
857 } // namespace pcr
858 //........................................................................