/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org 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 version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_toolkit.hxx" #include #include #include #include #include #include //........................................................................ namespace toolkit { //........................................................................ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; // ---------------------------------------------------- // helper // ---------------------------------------------------- static void lcl_throwIllegalArgumentException( ) { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... throw IllegalArgumentException(); } static void lcl_throwIndexOutOfBoundsException( ) { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... throw IndexOutOfBoundsException(); } // =================================================================== // = UnoControlRoadmapModel // =================================================================== // ------------------------------------------------------------------- UnoControlRoadmapModel::UnoControlRoadmapModel() : maContainerListeners( *this ) { ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); ImplRegisterProperty( BASEPROPERTY_BORDER ); ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); ImplRegisterProperty( BASEPROPERTY_IMAGEURL ); ImplRegisterProperty( BASEPROPERTY_GRAPHIC ); ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); ImplRegisterProperty( BASEPROPERTY_COMPLETE ); ImplRegisterProperty( BASEPROPERTY_ACTIVATED ); ImplRegisterProperty( BASEPROPERTY_CURRENTITEMID ); ImplRegisterProperty( BASEPROPERTY_TABSTOP ); ImplRegisterProperty( BASEPROPERTY_TEXT ); } // ------------------------------------------------------------------- ::rtl::OUString UnoControlRoadmapModel::getServiceName() throw(RuntimeException) { return ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmapModel ); } // ------------------------------------------------------------------- Any UnoControlRoadmapModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const { Any aReturn; switch (nPropId) { case BASEPROPERTY_COMPLETE: aReturn <<= (sal_Bool) sal_True; break; case BASEPROPERTY_ACTIVATED: aReturn <<= (sal_Bool) sal_True; break; case BASEPROPERTY_CURRENTITEMID: aReturn <<= (sal_Int16) -1; break; case BASEPROPERTY_TEXT: break; case BASEPROPERTY_BORDER: aReturn <<= (sal_Int16) 2; // No Border break; case BASEPROPERTY_DEFAULTCONTROL: aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmap ) ); break; default : aReturn = UnoControlRoadmapModel_Base::ImplGetDefaultValue( nPropId ); break; } return aReturn; } Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstance( ) throw (Exception, ::com::sun::star::uno::RuntimeException) { ORoadmapEntry* pRoadmapItem = new ORoadmapEntry(); Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem; return xNewRoadmapItem; } Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstanceWithArguments( const Sequence< Any >& /*aArguments*/ ) throw (Exception, RuntimeException) { // Todo: implementation of the arguments handling ORoadmapEntry* pRoadmapItem = new ORoadmapEntry(); Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem; return xNewRoadmapItem; } IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlRoadmapModel, UnoControlRoadmapModel_Base, UnoControlRoadmapModel_IBase ) // ------------------------------------------------------------------- ::com::sun::star::uno::Any SAL_CALL UnoControlRoadmapModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) { Any aRet = UnoControlRoadmapModel_Base::queryAggregation( rType ); if ( !aRet.hasValue() ) aRet = UnoControlRoadmapModel_IBase::queryInterface( rType ); return aRet; } // ------------------------------------------------------------------- ::cppu::IPropertyArrayHelper& UnoControlRoadmapModel::getInfoHelper() { static UnoPropertyArrayHelper* pHelper = NULL; if ( !pHelper ) { Sequence aIDs = ImplGetPropertyIds(); pHelper = new UnoPropertyArrayHelper( aIDs ); } return *pHelper; } // beans::XMultiPropertySet // ------------------------------------------------------------------- Reference< XPropertySetInfo > UnoControlRoadmapModel::getPropertySetInfo( ) throw(RuntimeException) { static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); return xInfo; } sal_Int32 SAL_CALL UnoControlRoadmapModel::getCount() throw(RuntimeException) { return maRoadmapItems.size(); } Any SAL_CALL UnoControlRoadmapModel::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) { if (( Index >= (sal_Int32)maRoadmapItems.size()) || (Index < 0)) lcl_throwIndexOutOfBoundsException( ); Any aAny; aAny = makeAny( maRoadmapItems.at( Index )); return aAny; } void UnoControlRoadmapModel::MakeRMItemValidation( sal_Int32 Index, Reference< XInterface > xRoadmapItem ) { if ((Index > (sal_Int32)maRoadmapItems.size()) || ( Index < 0 ) ) lcl_throwIndexOutOfBoundsException( ); if ( !xRoadmapItem.is() ) lcl_throwIllegalArgumentException(); Reference< XServiceInfo > xServiceInfo( xRoadmapItem, UNO_QUERY ); sal_Bool bIsRoadmapItem = xServiceInfo->supportsService( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.RoadmapItem")) ); if ( !bIsRoadmapItem ) lcl_throwIllegalArgumentException(); } void UnoControlRoadmapModel::SetRMItemDefaultProperties( const sal_Int32 , Reference< XInterface > xRoadmapItem) { Any aAny; Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY ); Reference< XPropertySet > xProps( xRoadmapItem, UNO_QUERY ); if ( xProps.is() ) { sal_Int32 LocID = 0; Any aValue = xPropertySet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ID")) ); aValue >>= LocID; if (LocID < 0) // index may not be smaller than zero { aAny <<= GetUniqueID(); xPropertySet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ID")), aAny ); } } } // The performance of this method could certainly be improved. // As long as only vectors with up to 10 elements are // involved it should be sufficient sal_Int32 UnoControlRoadmapModel::GetUniqueID() { Any aAny; sal_Bool bIncrement = sal_True; sal_Int32 CurID = 0; sal_Int32 n_CurItemID = 0; Reference< XInterface > CurRoadmapItem; while ( bIncrement ) { bIncrement = sal_False; for ( RoadmapItemHolderList::iterator i = maRoadmapItems.begin(); i < maRoadmapItems.end(); ++i ) { CurRoadmapItem = *i; Reference< XPropertySet > xPropertySet( CurRoadmapItem, UNO_QUERY ); aAny = xPropertySet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ID")) ); aAny >>= n_CurItemID; if (n_CurItemID == CurID) { bIncrement = sal_True; CurID++; break; } } } return CurID; } ContainerEvent UnoControlRoadmapModel::GetContainerEvent(sal_Int32 Index, Reference< XInterface > xRoadmapItem) { ContainerEvent aEvent; aEvent.Source = *this; aEvent.Element <<= xRoadmapItem; aEvent.Accessor = makeAny(Index); return aEvent; } sal_Int16 UnoControlRoadmapModel::GetCurrentItemID( Reference< XPropertySet > xPropertySet ) { Any aAny = xPropertySet->getPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ) ); sal_Int16 n_CurrentItemID = 0; aAny >>= n_CurrentItemID; return n_CurrentItemID; } void SAL_CALL UnoControlRoadmapModel::insertByIndex( const sal_Int32 Index, const Any& _Element) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) { if ( ( Index >= ( (sal_Int32)maRoadmapItems.size() + 1 ) ) || (Index < 0)) lcl_throwIndexOutOfBoundsException( ); Reference< XInterface > xRoadmapItem; _Element >>= xRoadmapItem; MakeRMItemValidation( Index, xRoadmapItem); SetRMItemDefaultProperties( Index, xRoadmapItem ); maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); maContainerListeners.elementInserted( aEvent ); Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY ); sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet ); if ( Index <= n_CurrentItemID ) { Any aAny; aAny <<= ( sal_Int16 ) ( n_CurrentItemID + 1 ); xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); } } void SAL_CALL UnoControlRoadmapModel::removeByIndex( sal_Int32 Index) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) { if (( Index > (sal_Int32)maRoadmapItems.size()) || (Index < 0)) lcl_throwIndexOutOfBoundsException( ); Reference< XInterface > xRoadmapItem; maRoadmapItems.erase( maRoadmapItems.begin() + Index ); ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); maContainerListeners.elementRemoved( aEvent ); Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY ); sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet ); Any aAny; if ( Index <= n_CurrentItemID ) { if ( n_CurrentItemID >= (sal_Int32)maRoadmapItems.size() ) { n_CurrentItemID = sal::static_int_cast< sal_Int16 >( maRoadmapItems.size()-1); if ( n_CurrentItemID < 0 ) return; aAny <<= n_CurrentItemID; } else if (Index == n_CurrentItemID) aAny <<= ( sal_Int16 ) -1; else if( Index < n_CurrentItemID) aAny <<= ( sal_Int16 ) ( n_CurrentItemID - 1 ); xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); } } void SAL_CALL UnoControlRoadmapModel::replaceByIndex( const sal_Int32 Index, const Any& _Element) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) { Reference< XInterface > xRoadmapItem; _Element >>= xRoadmapItem; MakeRMItemValidation( Index, xRoadmapItem); SetRMItemDefaultProperties( Index, xRoadmapItem ); maRoadmapItems.erase( maRoadmapItems.begin() + Index ); maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); //push_back( xRoadmapItem ); ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); maContainerListeners.elementReplaced( aEvent ); } Type SAL_CALL UnoControlRoadmapModel::getElementType() throw(RuntimeException) { Type aType = getCppuType( ( Reference< XPropertySet>* ) NULL ); return aType; } sal_Bool SAL_CALL UnoControlRoadmapModel::hasElements() throw(RuntimeException) { return !maRoadmapItems.empty(); } void SAL_CALL UnoControlRoadmapModel::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { maContainerListeners.addInterface( xListener ); } void SAL_CALL UnoControlRoadmapModel::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { maContainerListeners.removeInterface( xListener ); } // =================================================================== // = UnoRoadmapControl // =================================================================== // ------------------------------------------------------------------- UnoRoadmapControl::UnoRoadmapControl(): maItemListeners( *this ) { } IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase ) IMPLEMENT_FORWARD_XINTERFACE2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase ) sal_Bool SAL_CALL UnoRoadmapControl::setModel(const Reference< XControlModel >& _rModel) throw ( RuntimeException ) { Reference< XContainer > xC( getModel(), UNO_QUERY ); if ( xC.is() ) xC->removeContainerListener( this ); sal_Bool bReturn = UnoControlBase::setModel( _rModel ); xC = xC.query( getModel()); if ( xC.is() ) xC->addContainerListener( this ); return bReturn; } // ------------------------------------------------------------------- ::rtl::OUString UnoRoadmapControl::GetComponentServiceName() { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Roadmap")); } void UnoRoadmapControl::dispose() throw(RuntimeException) { EventObject aEvt; aEvt.Source = (::cppu::OWeakObject*)this; maItemListeners.disposeAndClear( aEvt ); UnoControl::dispose(); } void UnoRoadmapControl::elementInserted( const ContainerEvent& rEvent )throw(RuntimeException) { Reference< XInterface > xRoadmapItem; rEvent.Element >>= xRoadmapItem; Reference< XPropertySet > xRoadmapPropertySet( xRoadmapItem, UNO_QUERY ); if ( xRoadmapPropertySet.is() ) xRoadmapPropertySet->addPropertyChangeListener( rtl::OUString(), this ); Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); if ( xPeer.is() ) { xPeer->elementInserted( rEvent ); Reference < XPropertySet > xPropertySet( xPeer, UNO_QUERY ); if ( xPropertySet.is() ) xPropertySet->addPropertyChangeListener( rtl::OUString(), this ); } } void UnoRoadmapControl::elementRemoved( const ContainerEvent& rEvent )throw(RuntimeException) { Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); if ( xPeer.is() ) xPeer->elementRemoved( rEvent ); Reference< XInterface > xRoadmapItem; rEvent.Element >>= xRoadmapItem; Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY ); if ( xPropertySet.is() ) xPropertySet->removePropertyChangeListener( rtl::OUString(), this ); } void UnoRoadmapControl::elementReplaced( const ContainerEvent& rEvent )throw(RuntimeException) { Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); if ( xPeer.is() ) xPeer->elementReplaced( rEvent ); } void SAL_CALL UnoRoadmapControl::itemStateChanged( const ItemEvent& rEvent ) throw (RuntimeException) { sal_Int16 CurItemIndex = sal::static_int_cast< sal_Int16 >(rEvent.ItemId); Any aAny; aAny <<= CurItemIndex; Reference< XControlModel > xModel( getModel( ), UNO_QUERY ); Reference< XPropertySet > xPropertySet( xModel, UNO_QUERY ); xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); if ( maItemListeners.getLength() ) maItemListeners.itemStateChanged( rEvent ); } void SAL_CALL UnoRoadmapControl::addItemListener( const Reference< XItemListener >& l ) throw (RuntimeException) { maItemListeners.addInterface( l ); if( getPeer().is() && maItemListeners.getLength() == 1 ) { Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY ); xRoadmap->addItemListener( this ); } } void SAL_CALL UnoRoadmapControl::removeItemListener( const Reference< XItemListener >& l ) throw (RuntimeException) { if( getPeer().is() && maItemListeners.getLength() == 1 ) { Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY ); xRoadmap->removeItemListener( this ); } maItemListeners.removeInterface( l ); } void SAL_CALL UnoRoadmapControl::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException) { Reference< XPropertyChangeListener > xPeer(getPeer(), UNO_QUERY); if ( xPeer.is() ) xPeer->propertyChange( evt ); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */