1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: roadmapcontrol.cxx,v $
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_toolkit.hxx"
34 #ifndef _TOOLKIT_ROADMAP_CONTROL_HXX
35 #include <toolkit/controls/roadmapcontrol.hxx>
37 #include <toolkit/helper/unopropertyarrayhelper.hxx>
38 #include <toolkit/helper/property.hxx>
39 #include <com/sun/star/awt/XVclWindowPeer.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <osl/diagnose.h>
43 //........................................................................
46 //........................................................................
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::awt
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star::beans
;
52 using namespace ::com::sun::star::container
;
54 // ----------------------------------------------------
56 // ----------------------------------------------------
58 static void lcl_knitImageComponents( const Reference
< XControlModel
>& _rxModel
,
59 const Reference
< XWindowPeer
>& _rxPeer
,
62 Reference
< XImageProducer
> xProducer( _rxModel
, UNO_QUERY
);
65 Reference
< XImageConsumer
> xConsumer( _rxPeer
, UNO_QUERY
);
70 xProducer
->addConsumer( xConsumer
);
71 xProducer
->startProduction();
74 xProducer
->removeConsumer( xConsumer
);
79 static void lcl_throwIllegalArgumentException( )
80 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
81 throw IllegalArgumentException();
84 static void lcl_throwIndexOutOfBoundsException( )
85 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
86 throw IndexOutOfBoundsException();
89 // ===================================================================
90 // = UnoControlRoadmapModel
91 // ===================================================================
92 // -------------------------------------------------------------------
93 UnoControlRoadmapModel::UnoControlRoadmapModel() : maContainerListeners( *this )
95 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR
);
96 ImplRegisterProperty( BASEPROPERTY_BORDER
);
97 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR
);
98 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL
);
99 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR
);
100 ImplRegisterProperty( BASEPROPERTY_HELPTEXT
);
101 ImplRegisterProperty( BASEPROPERTY_HELPURL
);
102 ImplRegisterProperty( BASEPROPERTY_IMAGEURL
);
103 ImplRegisterProperty( BASEPROPERTY_PRINTABLE
);
104 ImplRegisterProperty( BASEPROPERTY_COMPLETE
);
105 ImplRegisterProperty( BASEPROPERTY_ACTIVATED
);
106 ImplRegisterProperty( BASEPROPERTY_CURRENTITEMID
);
107 ImplRegisterProperty( BASEPROPERTY_TABSTOP
);
108 ImplRegisterProperty( BASEPROPERTY_TEXT
);
111 // -------------------------------------------------------------------
112 ::rtl::OUString
UnoControlRoadmapModel::getServiceName() throw(RuntimeException
)
114 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmapModel
);
118 // -------------------------------------------------------------------
119 Any
UnoControlRoadmapModel::ImplGetDefaultValue( sal_uInt16 nPropId
) const
124 case BASEPROPERTY_COMPLETE
:
125 aReturn
<<= (sal_Bool
) sal_True
;
127 case BASEPROPERTY_ACTIVATED
:
128 aReturn
<<= (sal_Bool
) sal_True
;
130 case BASEPROPERTY_CURRENTITEMID
:
131 aReturn
<<= (sal_Int16
) -1;
133 case BASEPROPERTY_TEXT
:
135 case BASEPROPERTY_BORDER
:
136 aReturn
<<= (sal_Int16
) 2; // No Border
138 case BASEPROPERTY_DEFAULTCONTROL
:
139 aReturn
<<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmap
) );
141 default : aReturn
= UnoControlModel::ImplGetDefaultValue( nPropId
); break;
148 Reference
< XInterface
> SAL_CALL
UnoControlRoadmapModel::createInstance( ) throw (Exception
, ::com::sun::star::uno::RuntimeException
)
150 ORoadmapEntry
* pRoadmapItem
= new ORoadmapEntry();
151 Reference
< XInterface
> xNewRoadmapItem
= (::cppu::OWeakObject
*)pRoadmapItem
;
152 return xNewRoadmapItem
;
156 Reference
< XInterface
> SAL_CALL
UnoControlRoadmapModel::createInstanceWithArguments( const Sequence
< Any
>& /*aArguments*/ ) throw (Exception
, RuntimeException
)
158 // Todo: implementation of the arguments handling
159 ORoadmapEntry
* pRoadmapItem
= new ORoadmapEntry();
160 Reference
< XInterface
> xNewRoadmapItem
= (::cppu::OWeakObject
*)pRoadmapItem
;
161 return xNewRoadmapItem
;
165 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlRoadmapModel
, UnoControlRoadmapModel_Base
, UnoControlRoadmapModel_IBase
)
168 // -------------------------------------------------------------------
169 ::com::sun::star::uno::Any SAL_CALL
UnoControlRoadmapModel::queryAggregation( const ::com::sun::star::uno::Type
& rType
) throw(::com::sun::star::uno::RuntimeException
)
171 Any aRet
= UnoControlRoadmapModel_Base::queryAggregation( rType
);
172 if ( !aRet
.hasValue() )
173 aRet
= UnoControlRoadmapModel_IBase::queryInterface( rType
);
178 // -------------------------------------------------------------------
179 ::cppu::IPropertyArrayHelper
& UnoControlRoadmapModel::getInfoHelper()
181 static UnoPropertyArrayHelper
* pHelper
= NULL
;
184 Sequence
<sal_Int32
> aIDs
= ImplGetPropertyIds();
185 pHelper
= new UnoPropertyArrayHelper( aIDs
);
191 // beans::XMultiPropertySet
192 // -------------------------------------------------------------------
193 Reference
< XPropertySetInfo
> UnoControlRoadmapModel::getPropertySetInfo( ) throw(RuntimeException
)
195 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
200 sal_Int32 SAL_CALL
UnoControlRoadmapModel::getCount() throw(RuntimeException
)
202 return maRoadmapItems
.size();
205 Any SAL_CALL
UnoControlRoadmapModel::getByIndex( sal_Int32 Index
) throw (IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
207 if (( Index
>= (sal_Int32
)maRoadmapItems
.size()) || (Index
< 0))
208 lcl_throwIndexOutOfBoundsException( );
210 aAny
= makeAny( maRoadmapItems
.at( Index
));
216 void UnoControlRoadmapModel::MakeRMItemValidation( sal_Int32 Index
, Reference
< XInterface
> xRoadmapItem
)
218 if ((Index
> (sal_Int32
)maRoadmapItems
.size()) || ( Index
< 0 ) )
219 lcl_throwIndexOutOfBoundsException( );
220 if ( !xRoadmapItem
.is() )
221 lcl_throwIllegalArgumentException();
222 Reference
< XServiceInfo
> xServiceInfo( xRoadmapItem
, UNO_QUERY
);
223 sal_Bool bIsRoadmapItem
= xServiceInfo
->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.RoadmapItem" ) );
224 if ( !bIsRoadmapItem
)
225 lcl_throwIllegalArgumentException();
229 void UnoControlRoadmapModel::SetRMItemDefaultProperties( const sal_Int32
, Reference
< XInterface
> xRoadmapItem
)
232 Reference
< XPropertySet
> xPropertySet( xRoadmapItem
, UNO_QUERY
);
233 Reference
< XPropertySet
> xProps( xRoadmapItem
, UNO_QUERY
);
237 Any aValue
= xPropertySet
->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) );
239 if (LocID
< 0) // index may not be smaller than zero
241 aAny
<<= GetUniqueID();
242 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "ID" ), aAny
);
248 // The performance of this method could certainly be improved.
249 // As long as only vectors with up to 10 elements are
250 // involved it should be sufficient
251 sal_Int32
UnoControlRoadmapModel::GetUniqueID()
254 sal_Bool bIncrement
= sal_True
;
256 sal_Int32 n_CurItemID
= 0;
257 Reference
< XInterface
> CurRoadmapItem
;
260 bIncrement
= sal_False
;
261 for ( RoadmapItemHolderList::iterator i
= maRoadmapItems
.begin(); i
< maRoadmapItems
.end(); i
++ )
264 Reference
< XPropertySet
> xPropertySet( CurRoadmapItem
, UNO_QUERY
);
265 aAny
= xPropertySet
->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) );
266 aAny
>>= n_CurItemID
;
267 if (n_CurItemID
== CurID
)
269 bIncrement
= sal_True
;
279 ContainerEvent
UnoControlRoadmapModel::GetContainerEvent(sal_Int32 Index
, Reference
< XInterface
> xRoadmapItem
)
281 ContainerEvent aEvent
;
282 aEvent
.Source
= *this;
283 aEvent
.Element
<<= xRoadmapItem
;
284 aEvent
.Accessor
= makeAny(Index
);
289 sal_Int16
UnoControlRoadmapModel::GetCurrentItemID( Reference
< XPropertySet
> xPropertySet
)
291 Any aAny
= xPropertySet
->getPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID
) );
292 sal_Int16 n_CurrentItemID
= 0;
293 aAny
>>= n_CurrentItemID
;
294 return n_CurrentItemID
;
298 void SAL_CALL
UnoControlRoadmapModel::insertByIndex( const sal_Int32 Index
, const Any
& _Element
)
299 throw (IllegalArgumentException
, IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
301 if ( ( Index
>= ( (sal_Int32
)maRoadmapItems
.size() + 1 ) ) || (Index
< 0))
302 lcl_throwIndexOutOfBoundsException( );
303 Reference
< XInterface
> xRoadmapItem
;
304 _Element
>>= xRoadmapItem
;
305 MakeRMItemValidation( Index
, xRoadmapItem
);
306 SetRMItemDefaultProperties( Index
, xRoadmapItem
);
307 maRoadmapItems
.insert( maRoadmapItems
.begin() + Index
, xRoadmapItem
);
308 ContainerEvent aEvent
= GetContainerEvent(Index
, xRoadmapItem
);
309 maContainerListeners
.elementInserted( aEvent
);
310 Reference
< XPropertySet
> xPropertySet( (XAggregation
*) (::cppu::OWeakAggObject
*)this, UNO_QUERY
);
311 sal_Int16 n_CurrentItemID
= GetCurrentItemID( xPropertySet
);
312 if ( Index
<= n_CurrentItemID
)
315 aAny
<<= ( sal_Int16
) ( n_CurrentItemID
+ 1 );
316 xPropertySet
->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID
), aAny
);
322 void SAL_CALL
UnoControlRoadmapModel::removeByIndex( sal_Int32 Index
)
323 throw (IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
325 if (( Index
> (sal_Int32
)maRoadmapItems
.size()) || (Index
< 0))
326 lcl_throwIndexOutOfBoundsException( );
327 Reference
< XInterface
> xRoadmapItem
;
328 maRoadmapItems
.erase( maRoadmapItems
.begin() + Index
);
329 ContainerEvent aEvent
= GetContainerEvent(Index
, xRoadmapItem
);
330 maContainerListeners
.elementRemoved( aEvent
);
331 Reference
< XPropertySet
> xPropertySet( (XAggregation
*) (::cppu::OWeakAggObject
*)this, UNO_QUERY
);
332 sal_Int16 n_CurrentItemID
= GetCurrentItemID( xPropertySet
);
334 if ( Index
<= n_CurrentItemID
)
336 if ( n_CurrentItemID
>= (sal_Int32
)maRoadmapItems
.size() )
338 n_CurrentItemID
= sal::static_int_cast
< sal_Int16
>(
339 maRoadmapItems
.size()-1);
340 if ( n_CurrentItemID
< 0 )
342 aAny
<<= n_CurrentItemID
;
344 else if (Index
== n_CurrentItemID
)
345 aAny
<<= ( sal_Int16
) -1;
346 else if( Index
< n_CurrentItemID
)
347 aAny
<<= ( sal_Int16
) ( n_CurrentItemID
- 1 );
348 xPropertySet
->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID
), aAny
);
353 void SAL_CALL
UnoControlRoadmapModel::replaceByIndex( const sal_Int32 Index
, const Any
& _Element
)
354 throw (IllegalArgumentException
, IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
356 Reference
< XInterface
> xRoadmapItem
;
357 _Element
>>= xRoadmapItem
;
358 MakeRMItemValidation( Index
, xRoadmapItem
);
359 SetRMItemDefaultProperties( Index
, xRoadmapItem
);
360 maRoadmapItems
.erase( maRoadmapItems
.begin() + Index
);
361 maRoadmapItems
.insert( maRoadmapItems
.begin() + Index
, xRoadmapItem
); //push_back( xRoadmapItem );
362 ContainerEvent aEvent
= GetContainerEvent(Index
, xRoadmapItem
);
363 maContainerListeners
.elementReplaced( aEvent
);
367 Type SAL_CALL
UnoControlRoadmapModel::getElementType() throw(RuntimeException
)
369 Type aType
= getCppuType( ( Reference
< XPropertySet
>* ) NULL
);
374 sal_Bool SAL_CALL
UnoControlRoadmapModel::hasElements() throw(RuntimeException
)
376 return !maRoadmapItems
.empty();
380 void SAL_CALL
UnoControlRoadmapModel::addContainerListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::container::XContainerListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
382 maContainerListeners
.addInterface( xListener
);
385 void SAL_CALL
UnoControlRoadmapModel::removeContainerListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::container::XContainerListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
387 maContainerListeners
.removeInterface( xListener
);
391 void UnoControlRoadmapModel::addConsumer( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XImageConsumer
>& xConsumer
) throw (::com::sun::star::uno::RuntimeException
)
393 maImageListeners
.push_back( xConsumer
);
397 void UnoControlRoadmapModel::removeConsumer( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XImageConsumer
>& xConsumer
) throw (::com::sun::star::uno::RuntimeException
)
399 maImageListeners
.remove( xConsumer
);
403 void UnoControlRoadmapModel::startProduction( ) throw (::com::sun::star::uno::RuntimeException
)
405 Sequence
<Any
> aArgs(1);
406 aArgs
.getArray()[0] = getPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEURL
) );
407 Reference
< XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
408 Reference
< XImageProducer
> xImageProducer( xMSF
->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "com.sun.star.awt.ImageProducer" ), aArgs
), UNO_QUERY
);
409 if ( xImageProducer
.is() )
411 std::list
< Reference
< XImageConsumer
> >::iterator
aIter( maImageListeners
.begin() );
412 while ( aIter
!= maImageListeners
.end() )
414 xImageProducer
->addConsumer( *aIter
);
417 xImageProducer
->startProduction();
424 // ===================================================================
425 // = UnoRoadmapControl
426 // ===================================================================
427 // -------------------------------------------------------------------
428 UnoRoadmapControl::UnoRoadmapControl(): maItemListeners( *this )
432 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoRoadmapControl
, UnoControlRoadmap_Base
, UnoControlRoadmap_IBase
)
433 IMPLEMENT_FORWARD_XINTERFACE2( UnoRoadmapControl
, UnoControlRoadmap_Base
, UnoControlRoadmap_IBase
)
436 sal_Bool SAL_CALL
UnoRoadmapControl::setModel(const Reference
< XControlModel
>& _rModel
) throw ( RuntimeException
)
440 // remove the peer as image consumer from the model
441 lcl_knitImageComponents( getModel(), getPeer(), false );
443 Reference
< XContainer
> xC( getModel(), UNO_QUERY
);
445 xC
->removeContainerListener( this );
447 sal_Bool bReturn
= UnoControlBase::setModel( _rModel
);
449 xC
= xC
.query( getModel());
451 xC
->addContainerListener( this );
453 // add the peer as image consumer to the model
454 lcl_knitImageComponents( getModel(), getPeer(), true );
460 // -------------------------------------------------------------------
461 ::rtl::OUString
UnoRoadmapControl::GetComponentServiceName()
463 return ::rtl::OUString::createFromAscii( "Roadmap" );
468 void SAL_CALL
UnoRoadmapControl::createPeer( const Reference
<XToolkit
> & rxToolkit
, const Reference
< XWindowPeer
> & rParentPeer
) throw(RuntimeException
)
470 // remove the peer as image consumer from the model
471 lcl_knitImageComponents( getModel(), getPeer(), false );
473 UnoControl::createPeer( rxToolkit
, rParentPeer
);
475 lcl_knitImageComponents( getModel(), getPeer(), true );
480 void UnoRoadmapControl::dispose() throw(RuntimeException
)
483 aEvt
.Source
= (::cppu::OWeakObject
*)this;
484 maItemListeners
.disposeAndClear( aEvt
);
485 UnoControl::dispose();
490 void UnoRoadmapControl::ImplSetPeerProperty( const ::rtl::OUString
& rPropName
, const Any
& rVal
)
492 sal_uInt16 nType
= GetPropertyId( rPropName
);
493 if ( getPeer().is() && ( nType
== BASEPROPERTY_IMAGEURL
) )
495 Reference
< XImageProducer
> xImgProd( getModel(), UNO_QUERY
);
496 Reference
< XImageConsumer
> xImgCons( getPeer(), UNO_QUERY
);
498 if ( xImgProd
.is() && xImgCons
.is() )
500 xImgProd
->startProduction();
504 UnoControlBase::ImplSetPeerProperty( rPropName
, rVal
);
508 void UnoRoadmapControl::elementInserted( const ContainerEvent
& rEvent
)throw(RuntimeException
)
510 Reference
< XInterface
> xRoadmapItem
;
511 rEvent
.Element
>>= xRoadmapItem
;
512 Reference
< XPropertySet
> xRoadmapPropertySet( xRoadmapItem
, UNO_QUERY
);
513 if ( xRoadmapPropertySet
.is() )
514 xRoadmapPropertySet
->addPropertyChangeListener( rtl::OUString(), this );
516 Reference
< XContainerListener
> xPeer(getPeer(), UNO_QUERY
);
519 xPeer
->elementInserted( rEvent
);
520 Reference
< XPropertySet
> xPropertySet( xPeer
, UNO_QUERY
);
521 if ( xPropertySet
.is() )
522 xPropertySet
->addPropertyChangeListener( rtl::OUString(), this );
527 void UnoRoadmapControl::elementRemoved( const ContainerEvent
& rEvent
)throw(RuntimeException
)
529 Reference
< XContainerListener
> xPeer(getPeer(), UNO_QUERY
);
531 xPeer
->elementRemoved( rEvent
);
532 Reference
< XInterface
> xRoadmapItem
;
533 rEvent
.Element
>>= xRoadmapItem
;
534 Reference
< XPropertySet
> xPropertySet( xRoadmapItem
, UNO_QUERY
);
535 if ( xPropertySet
.is() )
536 xPropertySet
->removePropertyChangeListener( rtl::OUString(), this );
540 void UnoRoadmapControl::elementReplaced( const ContainerEvent
& rEvent
)throw(RuntimeException
)
542 Reference
< XContainerListener
> xPeer(getPeer(), UNO_QUERY
);
544 xPeer
->elementReplaced( rEvent
);
548 void SAL_CALL
UnoRoadmapControl::itemStateChanged( const ItemEvent
& rEvent
) throw (RuntimeException
)
550 sal_Int16 CurItemIndex
= sal::static_int_cast
< sal_Int16
>(rEvent
.ItemId
);
552 aAny
<<= CurItemIndex
;
553 Reference
< XControlModel
> xModel( getModel( ), UNO_QUERY
);
554 Reference
< XPropertySet
> xPropertySet( xModel
, UNO_QUERY
);
555 xPropertySet
->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID
), aAny
);
556 if ( maItemListeners
.getLength() )
557 maItemListeners
.itemStateChanged( rEvent
);
561 void SAL_CALL
UnoRoadmapControl::addItemListener( const Reference
< XItemListener
>& l
) throw (RuntimeException
)
563 maItemListeners
.addInterface( l
);
564 if( getPeer().is() && maItemListeners
.getLength() == 1 )
566 Reference
< XItemEventBroadcaster
> xRoadmap( getPeer(), UNO_QUERY
);
567 xRoadmap
->addItemListener( this );
572 void SAL_CALL
UnoRoadmapControl::removeItemListener( const Reference
< XItemListener
>& l
) throw (RuntimeException
)
574 if( getPeer().is() && maItemListeners
.getLength() == 1 )
576 Reference
< XItemEventBroadcaster
> xRoadmap( getPeer(), UNO_QUERY
);
577 xRoadmap
->removeItemListener( this );
580 maItemListeners
.removeInterface( l
);
584 void SAL_CALL
UnoRoadmapControl::propertyChange( const PropertyChangeEvent
& evt
) throw (RuntimeException
)
586 Reference
< XPropertyChangeListener
> xPeer(getPeer(), UNO_QUERY
);
588 xPeer
->propertyChange( evt
);