1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_toolkit.hxx" 30 31 #ifndef _TOOLKIT_ROADMAP_CONTROL_HXX 32 #include <toolkit/controls/roadmapcontrol.hxx> 33 #endif 34 #include <toolkit/helper/unopropertyarrayhelper.hxx> 35 #include <toolkit/helper/property.hxx> 36 #include <com/sun/star/awt/XVclWindowPeer.hpp> 37 #include <comphelper/processfactory.hxx> 38 #include <osl/diagnose.h> 39 40 //........................................................................ 41 namespace toolkit 42 { 43 //........................................................................ 44 45 using namespace ::com::sun::star::uno; 46 using namespace ::com::sun::star::awt; 47 using namespace ::com::sun::star::lang; 48 using namespace ::com::sun::star::beans; 49 using namespace ::com::sun::star::container; 50 51 // ---------------------------------------------------- 52 // helper 53 // ---------------------------------------------------- 54 55 static void lcl_throwIllegalArgumentException( ) 56 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... 57 throw IllegalArgumentException(); 58 } 59 60 static void lcl_throwIndexOutOfBoundsException( ) 61 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... 62 throw IndexOutOfBoundsException(); 63 } 64 65 // =================================================================== 66 // = UnoControlRoadmapModel 67 // =================================================================== 68 // ------------------------------------------------------------------- 69 UnoControlRoadmapModel::UnoControlRoadmapModel( const Reference< XMultiServiceFactory >& i_factory ) 70 :UnoControlRoadmapModel_Base( i_factory ) 71 ,maContainerListeners( *this ) 72 { 73 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); 74 ImplRegisterProperty( BASEPROPERTY_BORDER ); 75 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); 76 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); 77 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); 78 ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); 79 ImplRegisterProperty( BASEPROPERTY_HELPURL ); 80 ImplRegisterProperty( BASEPROPERTY_IMAGEURL ); 81 ImplRegisterProperty( BASEPROPERTY_GRAPHIC ); 82 ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); 83 ImplRegisterProperty( BASEPROPERTY_COMPLETE ); 84 ImplRegisterProperty( BASEPROPERTY_ACTIVATED ); 85 ImplRegisterProperty( BASEPROPERTY_CURRENTITEMID ); 86 ImplRegisterProperty( BASEPROPERTY_TABSTOP ); 87 ImplRegisterProperty( BASEPROPERTY_TEXT ); 88 } 89 90 // ------------------------------------------------------------------- 91 ::rtl::OUString UnoControlRoadmapModel::getServiceName() throw(RuntimeException) 92 { 93 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmapModel ); 94 } 95 96 97 // ------------------------------------------------------------------- 98 Any UnoControlRoadmapModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const 99 { 100 Any aReturn; 101 switch (nPropId) 102 { 103 case BASEPROPERTY_COMPLETE: 104 aReturn <<= (sal_Bool) sal_True; 105 break; 106 case BASEPROPERTY_ACTIVATED: 107 aReturn <<= (sal_Bool) sal_True; 108 break; 109 case BASEPROPERTY_CURRENTITEMID: 110 aReturn <<= (sal_Int16) -1; 111 break; 112 case BASEPROPERTY_TEXT: 113 break; 114 case BASEPROPERTY_BORDER: 115 aReturn <<= (sal_Int16) 2; // No Border 116 break; 117 case BASEPROPERTY_DEFAULTCONTROL: 118 aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmap ) ); 119 break; 120 default : aReturn = UnoControlRoadmapModel_Base::ImplGetDefaultValue( nPropId ); break; 121 } 122 123 return aReturn; 124 } 125 126 127 Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstance( ) throw (Exception, ::com::sun::star::uno::RuntimeException) 128 { 129 ORoadmapEntry* pRoadmapItem = new ORoadmapEntry(); 130 Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem; 131 return xNewRoadmapItem; 132 } 133 134 135 Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstanceWithArguments( const Sequence< Any >& /*aArguments*/ ) throw (Exception, RuntimeException) 136 { 137 // Todo: implementation of the arguments handling 138 ORoadmapEntry* pRoadmapItem = new ORoadmapEntry(); 139 Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem; 140 return xNewRoadmapItem; 141 } 142 143 144 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlRoadmapModel, UnoControlRoadmapModel_Base, UnoControlRoadmapModel_IBase ) 145 146 147 // ------------------------------------------------------------------- 148 ::com::sun::star::uno::Any SAL_CALL UnoControlRoadmapModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) 149 { 150 Any aRet = UnoControlRoadmapModel_Base::queryAggregation( rType ); 151 if ( !aRet.hasValue() ) 152 aRet = UnoControlRoadmapModel_IBase::queryInterface( rType ); 153 return aRet; 154 } 155 156 157 // ------------------------------------------------------------------- 158 ::cppu::IPropertyArrayHelper& UnoControlRoadmapModel::getInfoHelper() 159 { 160 static UnoPropertyArrayHelper* pHelper = NULL; 161 if ( !pHelper ) 162 { 163 Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); 164 pHelper = new UnoPropertyArrayHelper( aIDs ); 165 } 166 return *pHelper; 167 } 168 169 170 // beans::XMultiPropertySet 171 // ------------------------------------------------------------------- 172 Reference< XPropertySetInfo > UnoControlRoadmapModel::getPropertySetInfo( ) throw(RuntimeException) 173 { 174 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 175 return xInfo; 176 } 177 178 179 sal_Int32 SAL_CALL UnoControlRoadmapModel::getCount() throw(RuntimeException) 180 { 181 return maRoadmapItems.size(); 182 } 183 184 Any SAL_CALL UnoControlRoadmapModel::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 185 { 186 if (( Index >= (sal_Int32)maRoadmapItems.size()) || (Index < 0)) 187 lcl_throwIndexOutOfBoundsException( ); 188 Any aAny; 189 aAny = makeAny( maRoadmapItems.at( Index )); 190 return aAny; 191 } 192 193 194 195 void UnoControlRoadmapModel::MakeRMItemValidation( sal_Int32 Index, Reference< XInterface > xRoadmapItem ) 196 { 197 if ((Index > (sal_Int32)maRoadmapItems.size()) || ( Index < 0 ) ) 198 lcl_throwIndexOutOfBoundsException( ); 199 if ( !xRoadmapItem.is() ) 200 lcl_throwIllegalArgumentException(); 201 Reference< XServiceInfo > xServiceInfo( xRoadmapItem, UNO_QUERY ); 202 sal_Bool bIsRoadmapItem = xServiceInfo->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.RoadmapItem" ) ); 203 if ( !bIsRoadmapItem ) 204 lcl_throwIllegalArgumentException(); 205 } 206 207 208 void UnoControlRoadmapModel::SetRMItemDefaultProperties( const sal_Int32 , Reference< XInterface > xRoadmapItem) 209 { 210 Any aAny; 211 Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY ); 212 Reference< XPropertySet > xProps( xRoadmapItem, UNO_QUERY ); 213 if ( xProps.is() ) 214 { 215 sal_Int32 LocID = 0; 216 Any aValue = xPropertySet->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) ); 217 aValue >>= LocID; 218 if (LocID < 0) // index may not be smaller than zero 219 { 220 aAny <<= GetUniqueID(); 221 xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "ID" ), aAny ); 222 } 223 } 224 } 225 226 227 // The performance of this method could certainly be improved. 228 // As long as only vectors with up to 10 elements are 229 // involved it should be sufficient 230 sal_Int32 UnoControlRoadmapModel::GetUniqueID() 231 { 232 Any aAny; 233 sal_Bool bIncrement = sal_True; 234 sal_Int32 CurID = 0; 235 sal_Int32 n_CurItemID = 0; 236 Reference< XInterface > CurRoadmapItem; 237 while ( bIncrement ) 238 { 239 bIncrement = sal_False; 240 for ( RoadmapItemHolderList::iterator i = maRoadmapItems.begin(); i < maRoadmapItems.end(); i++ ) 241 { 242 CurRoadmapItem = *i; 243 Reference< XPropertySet > xPropertySet( CurRoadmapItem, UNO_QUERY ); 244 aAny = xPropertySet->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) ); 245 aAny >>= n_CurItemID; 246 if (n_CurItemID == CurID) 247 { 248 bIncrement = sal_True; 249 CurID++; 250 break; 251 } 252 } 253 } 254 return CurID; 255 } 256 257 258 ContainerEvent UnoControlRoadmapModel::GetContainerEvent(sal_Int32 Index, Reference< XInterface > xRoadmapItem) 259 { 260 ContainerEvent aEvent; 261 aEvent.Source = *this; 262 aEvent.Element <<= xRoadmapItem; 263 aEvent.Accessor = makeAny(Index); 264 return aEvent; 265 } 266 267 268 sal_Int16 UnoControlRoadmapModel::GetCurrentItemID( Reference< XPropertySet > xPropertySet ) 269 { 270 Any aAny = xPropertySet->getPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ) ); 271 sal_Int16 n_CurrentItemID = 0; 272 aAny >>= n_CurrentItemID; 273 return n_CurrentItemID; 274 } 275 276 277 void SAL_CALL UnoControlRoadmapModel::insertByIndex( const sal_Int32 Index, const Any& _Element) 278 throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 279 { 280 if ( ( Index >= ( (sal_Int32)maRoadmapItems.size() + 1 ) ) || (Index < 0)) 281 lcl_throwIndexOutOfBoundsException( ); 282 Reference< XInterface > xRoadmapItem; 283 _Element >>= xRoadmapItem; 284 MakeRMItemValidation( Index, xRoadmapItem); 285 SetRMItemDefaultProperties( Index, xRoadmapItem ); 286 maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); 287 ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); 288 maContainerListeners.elementInserted( aEvent ); 289 Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY ); 290 sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet ); 291 if ( Index <= n_CurrentItemID ) 292 { 293 Any aAny; 294 aAny <<= ( sal_Int16 ) ( n_CurrentItemID + 1 ); 295 xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); 296 } 297 } 298 299 300 301 void SAL_CALL UnoControlRoadmapModel::removeByIndex( sal_Int32 Index) 302 throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 303 { 304 if (( Index > (sal_Int32)maRoadmapItems.size()) || (Index < 0)) 305 lcl_throwIndexOutOfBoundsException( ); 306 Reference< XInterface > xRoadmapItem; 307 maRoadmapItems.erase( maRoadmapItems.begin() + Index ); 308 ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); 309 maContainerListeners.elementRemoved( aEvent ); 310 Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY ); 311 sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet ); 312 Any aAny; 313 if ( Index <= n_CurrentItemID ) 314 { 315 if ( n_CurrentItemID >= (sal_Int32)maRoadmapItems.size() ) 316 { 317 n_CurrentItemID = sal::static_int_cast< sal_Int16 >( 318 maRoadmapItems.size()-1); 319 if ( n_CurrentItemID < 0 ) 320 return; 321 aAny <<= n_CurrentItemID; 322 } 323 else if (Index == n_CurrentItemID) 324 aAny <<= ( sal_Int16 ) -1; 325 else if( Index < n_CurrentItemID) 326 aAny <<= ( sal_Int16 ) ( n_CurrentItemID - 1 ); 327 xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); 328 } 329 } 330 331 332 void SAL_CALL UnoControlRoadmapModel::replaceByIndex( const sal_Int32 Index, const Any& _Element) 333 throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 334 { 335 Reference< XInterface > xRoadmapItem; 336 _Element >>= xRoadmapItem; 337 MakeRMItemValidation( Index, xRoadmapItem); 338 SetRMItemDefaultProperties( Index, xRoadmapItem ); 339 maRoadmapItems.erase( maRoadmapItems.begin() + Index ); 340 maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); //push_back( xRoadmapItem ); 341 ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); 342 maContainerListeners.elementReplaced( aEvent ); 343 } 344 345 346 Type SAL_CALL UnoControlRoadmapModel::getElementType() throw(RuntimeException) 347 { 348 Type aType = getCppuType( ( Reference< XPropertySet>* ) NULL ); 349 return aType; 350 } 351 352 353 sal_Bool SAL_CALL UnoControlRoadmapModel::hasElements() throw(RuntimeException) 354 { 355 return !maRoadmapItems.empty(); 356 } 357 358 359 void SAL_CALL UnoControlRoadmapModel::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) 360 { 361 maContainerListeners.addInterface( xListener ); 362 } 363 364 void SAL_CALL UnoControlRoadmapModel::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) 365 { 366 maContainerListeners.removeInterface( xListener ); 367 } 368 369 // =================================================================== 370 // = UnoRoadmapControl 371 // =================================================================== 372 // ------------------------------------------------------------------- 373 UnoRoadmapControl::UnoRoadmapControl( const Reference< XMultiServiceFactory >& i_factory ) 374 :UnoControlRoadmap_Base( i_factory ) 375 ,maItemListeners( *this ) 376 { 377 } 378 379 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase ) 380 IMPLEMENT_FORWARD_XINTERFACE2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase ) 381 382 383 sal_Bool SAL_CALL UnoRoadmapControl::setModel(const Reference< XControlModel >& _rModel) throw ( RuntimeException ) 384 { 385 386 387 Reference< XContainer > xC( getModel(), UNO_QUERY ); 388 if ( xC.is() ) 389 xC->removeContainerListener( this ); 390 391 sal_Bool bReturn = UnoControlBase::setModel( _rModel ); 392 393 xC = xC.query( getModel()); 394 if ( xC.is() ) 395 xC->addContainerListener( this ); 396 397 return bReturn; 398 } 399 400 401 // ------------------------------------------------------------------- 402 ::rtl::OUString UnoRoadmapControl::GetComponentServiceName() 403 { 404 return ::rtl::OUString::createFromAscii( "Roadmap" ); 405 } 406 407 408 409 void UnoRoadmapControl::dispose() throw(RuntimeException) 410 { 411 EventObject aEvt; 412 aEvt.Source = (::cppu::OWeakObject*)this; 413 maItemListeners.disposeAndClear( aEvt ); 414 UnoControl::dispose(); 415 } 416 417 418 419 void UnoRoadmapControl::elementInserted( const ContainerEvent& rEvent )throw(RuntimeException) 420 { 421 Reference< XInterface > xRoadmapItem; 422 rEvent.Element >>= xRoadmapItem; 423 Reference< XPropertySet > xRoadmapPropertySet( xRoadmapItem, UNO_QUERY ); 424 if ( xRoadmapPropertySet.is() ) 425 xRoadmapPropertySet->addPropertyChangeListener( rtl::OUString(), this ); 426 427 Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); 428 if ( xPeer.is() ) 429 { 430 xPeer->elementInserted( rEvent ); 431 Reference < XPropertySet > xPropertySet( xPeer, UNO_QUERY ); 432 if ( xPropertySet.is() ) 433 xPropertySet->addPropertyChangeListener( rtl::OUString(), this ); 434 } 435 } 436 437 438 void UnoRoadmapControl::elementRemoved( const ContainerEvent& rEvent )throw(RuntimeException) 439 { 440 Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); 441 if ( xPeer.is() ) 442 xPeer->elementRemoved( rEvent ); 443 Reference< XInterface > xRoadmapItem; 444 rEvent.Element >>= xRoadmapItem; 445 Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY ); 446 if ( xPropertySet.is() ) 447 xPropertySet->removePropertyChangeListener( rtl::OUString(), this ); 448 } 449 450 451 void UnoRoadmapControl::elementReplaced( const ContainerEvent& rEvent )throw(RuntimeException) 452 { 453 Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); 454 if ( xPeer.is() ) 455 xPeer->elementReplaced( rEvent ); 456 } 457 458 459 void SAL_CALL UnoRoadmapControl::itemStateChanged( const ItemEvent& rEvent ) throw (RuntimeException) 460 { 461 sal_Int16 CurItemIndex = sal::static_int_cast< sal_Int16 >(rEvent.ItemId); 462 Any aAny; 463 aAny <<= CurItemIndex; 464 Reference< XControlModel > xModel( getModel( ), UNO_QUERY ); 465 Reference< XPropertySet > xPropertySet( xModel, UNO_QUERY ); 466 xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); 467 if ( maItemListeners.getLength() ) 468 maItemListeners.itemStateChanged( rEvent ); 469 } 470 471 472 void SAL_CALL UnoRoadmapControl::addItemListener( const Reference< XItemListener >& l ) throw (RuntimeException) 473 { 474 maItemListeners.addInterface( l ); 475 if( getPeer().is() && maItemListeners.getLength() == 1 ) 476 { 477 Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY ); 478 xRoadmap->addItemListener( this ); 479 } 480 } 481 482 483 void SAL_CALL UnoRoadmapControl::removeItemListener( const Reference< XItemListener >& l ) throw (RuntimeException) 484 { 485 if( getPeer().is() && maItemListeners.getLength() == 1 ) 486 { 487 Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY ); 488 xRoadmap->removeItemListener( this ); 489 } 490 491 maItemListeners.removeInterface( l ); 492 } 493 494 495 void SAL_CALL UnoRoadmapControl::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException) 496 { 497 Reference< XPropertyChangeListener > xPeer(getPeer(), UNO_QUERY); 498 if ( xPeer.is() ) 499 xPeer->propertyChange( evt ); 500 } 501 502 } 503 504