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_framework.hxx" 30 31 #include <classes/rootactiontriggercontainer.hxx> 32 #include <classes/actiontriggercontainer.hxx> 33 #include <classes/actiontriggerpropertyset.hxx> 34 #include <classes/actiontriggerseparatorpropertyset.hxx> 35 #include <framework/actiontriggerhelper.hxx> 36 #include <threadhelp/resetableguard.hxx> 37 #include <osl/mutex.hxx> 38 #include <vcl/svapp.hxx> 39 #include <cppuhelper/typeprovider.hxx> 40 41 42 using namespace cppu; 43 using namespace com::sun::star::uno; 44 using namespace com::sun::star::lang; 45 using namespace com::sun::star::container; 46 using namespace com::sun::star::beans; 47 48 49 namespace framework 50 { 51 52 static Sequence< sal_Int8 > impl_getStaticIdentifier() 53 { 54 static sal_uInt8 pGUID[16] = { 0x17, 0x0F, 0xA2, 0xC9, 0xCA, 0x50, 0x4A, 0xD3, 0xA6, 0x3B, 0x39, 0x99, 0xC5, 0x96, 0x43, 0x27 }; 55 static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ; 56 return seqID ; 57 } 58 59 60 RootActionTriggerContainer::RootActionTriggerContainer( const Menu* pMenu, const ::rtl::OUString* pMenuIdentifier, const Reference< XMultiServiceFactory >& rServiceManager ) : 61 PropertySetContainer( rServiceManager ) 62 , m_bContainerCreated( sal_False ) 63 , m_bContainerChanged( sal_False ) 64 , m_bInContainerCreation( sal_False ) 65 , m_pMenu( pMenu ) 66 , m_pMenuIdentifier( pMenuIdentifier ) 67 { 68 } 69 70 RootActionTriggerContainer::~RootActionTriggerContainer() 71 { 72 } 73 74 Sequence< sal_Int8 > RootActionTriggerContainer::GetUnoTunnelId() const 75 { 76 return impl_getStaticIdentifier(); 77 } 78 79 const Menu* RootActionTriggerContainer::GetMenu() 80 { 81 if ( !m_bContainerChanged ) 82 return m_pMenu; 83 else 84 { 85 ResetableGuard aGuard( m_aLock ); 86 87 Menu* pNewMenu = new PopupMenu; 88 89 ActionTriggerHelper::CreateMenuFromActionTriggerContainer( pNewMenu, this ); 90 m_pMenu = pNewMenu; 91 m_bContainerChanged = sal_False; 92 93 return m_pMenu; 94 } 95 } 96 97 98 // XInterface 99 Any SAL_CALL RootActionTriggerContainer::queryInterface( const Type& aType ) 100 throw ( RuntimeException ) 101 { 102 Any a = ::cppu::queryInterface( 103 aType , 104 SAL_STATIC_CAST( XMultiServiceFactory* , this ), 105 SAL_STATIC_CAST( XServiceInfo* , this ), 106 SAL_STATIC_CAST( XUnoTunnel* , this ), 107 SAL_STATIC_CAST( XTypeProvider* , this ), 108 SAL_STATIC_CAST( XNamed* , this )); 109 110 if( a.hasValue() ) 111 { 112 return a; 113 } 114 115 return PropertySetContainer::queryInterface( aType ); 116 } 117 118 void SAL_CALL RootActionTriggerContainer::acquire() throw () 119 { 120 PropertySetContainer::acquire(); 121 } 122 123 void SAL_CALL RootActionTriggerContainer::release() throw () 124 { 125 PropertySetContainer::release(); 126 } 127 128 // XMultiServiceFactory 129 Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstance( const ::rtl::OUString& aServiceSpecifier ) 130 throw ( Exception, RuntimeException ) 131 { 132 if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGER )) 133 return (OWeakObject *)( new ActionTriggerPropertySet( m_xServiceManager )); 134 else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER )) 135 return (OWeakObject *)( new ActionTriggerContainer( m_xServiceManager )); 136 else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR )) 137 return (OWeakObject *)( new ActionTriggerSeparatorPropertySet( m_xServiceManager )); 138 else 139 throw com::sun::star::uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown service specifier!" )), (OWeakObject *)this ); 140 } 141 142 Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/ ) 143 throw ( Exception, RuntimeException ) 144 { 145 return createInstance( ServiceSpecifier ); 146 } 147 148 Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getAvailableServiceNames() 149 throw ( RuntimeException ) 150 { 151 Sequence< ::rtl::OUString > aSeq( 3 ); 152 153 aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER )); 154 aSeq[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER )); 155 aSeq[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR )); 156 157 return aSeq; 158 } 159 160 161 // XIndexContainer 162 void SAL_CALL RootActionTriggerContainer::insertByIndex( sal_Int32 Index, const Any& Element ) 163 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 164 { 165 ResetableGuard aGuard( m_aLock ); 166 167 if ( !m_bContainerCreated ) 168 FillContainer(); 169 170 if ( !m_bInContainerCreation ) 171 m_bContainerChanged = sal_True; 172 PropertySetContainer::insertByIndex( Index, Element ); 173 } 174 175 void SAL_CALL RootActionTriggerContainer::removeByIndex( sal_Int32 Index ) 176 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 177 { 178 ResetableGuard aGuard( m_aLock ); 179 180 if ( !m_bContainerCreated ) 181 FillContainer(); 182 183 if ( !m_bInContainerCreation ) 184 m_bContainerChanged = sal_True; 185 PropertySetContainer::removeByIndex( Index ); 186 } 187 188 189 // XIndexReplace 190 void SAL_CALL RootActionTriggerContainer::replaceByIndex( sal_Int32 Index, const Any& Element ) 191 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 192 { 193 ResetableGuard aGuard( m_aLock ); 194 195 if ( !m_bContainerCreated ) 196 FillContainer(); 197 198 if ( !m_bInContainerCreation ) 199 m_bContainerChanged = sal_True; 200 PropertySetContainer::replaceByIndex( Index, Element ); 201 } 202 203 204 // XIndexAccess 205 sal_Int32 SAL_CALL RootActionTriggerContainer::getCount() 206 throw ( RuntimeException ) 207 { 208 ResetableGuard aGuard( m_aLock ); 209 210 if ( !m_bContainerCreated ) 211 { 212 if ( m_pMenu ) 213 { 214 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 215 return m_pMenu->GetItemCount(); 216 } 217 else 218 return 0; 219 } 220 else 221 { 222 return PropertySetContainer::getCount(); 223 } 224 } 225 226 Any SAL_CALL RootActionTriggerContainer::getByIndex( sal_Int32 Index ) 227 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 228 { 229 ResetableGuard aGuard( m_aLock ); 230 231 if ( !m_bContainerCreated ) 232 FillContainer(); 233 234 return PropertySetContainer::getByIndex( Index ); 235 } 236 237 238 // XElementAccess 239 Type SAL_CALL RootActionTriggerContainer::getElementType() 240 throw (::com::sun::star::uno::RuntimeException) 241 { 242 return ::getCppuType(( Reference< XPropertySet >*)0); 243 } 244 245 sal_Bool SAL_CALL RootActionTriggerContainer::hasElements() 246 throw (::com::sun::star::uno::RuntimeException) 247 { 248 if ( m_pMenu ) 249 { 250 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 251 return ( m_pMenu->GetItemCount() > 0 ); 252 } 253 254 return sal_False; 255 } 256 257 258 // XServiceInfo 259 ::rtl::OUString SAL_CALL RootActionTriggerContainer::getImplementationName() 260 throw ( RuntimeException ) 261 { 262 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ROOTACTIONTRIGGERCONTAINER )); 263 } 264 265 sal_Bool SAL_CALL RootActionTriggerContainer::supportsService( const ::rtl::OUString& ServiceName ) 266 throw ( RuntimeException ) 267 { 268 if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER )) 269 return sal_True; 270 271 return sal_False; 272 } 273 274 Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getSupportedServiceNames() 275 throw ( RuntimeException ) 276 { 277 Sequence< ::rtl::OUString > seqServiceNames( 1 ); 278 279 seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER )); 280 return seqServiceNames; 281 } 282 283 // XUnoTunnel 284 sal_Int64 SAL_CALL RootActionTriggerContainer::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw ( RuntimeException ) 285 { 286 if ( aIdentifier == impl_getStaticIdentifier() ) 287 return reinterpret_cast< sal_Int64 >( this ); 288 else 289 return 0; 290 } 291 292 // XTypeProvider 293 Sequence< Type > SAL_CALL RootActionTriggerContainer::getTypes() throw ( RuntimeException ) 294 { 295 // Optimize this method ! 296 // We initialize a static variable only one time. And we don't must use a mutex at every call! 297 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL! 298 static ::cppu::OTypeCollection* pTypeCollection = NULL ; 299 300 if ( pTypeCollection == NULL ) 301 { 302 // Ready for multithreading; get global mutex for first call of this method only! see before 303 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; 304 305 // Control these pointer again ... it can be, that another instance will be faster then these! 306 if ( pTypeCollection == NULL ) 307 { 308 // Create a static typecollection ... 309 static ::cppu::OTypeCollection aTypeCollection( 310 ::getCppuType(( const Reference< XMultiServiceFactory >*)NULL ) , 311 ::getCppuType(( const Reference< XIndexContainer >*)NULL ) , 312 ::getCppuType(( const Reference< XIndexAccess >*)NULL ) , 313 ::getCppuType(( const Reference< XIndexReplace >*)NULL ) , 314 ::getCppuType(( const Reference< XServiceInfo >*)NULL ) , 315 ::getCppuType(( const Reference< XTypeProvider >*)NULL ) , 316 ::getCppuType(( const Reference< XUnoTunnel >*)NULL ) , 317 ::getCppuType(( const Reference< XNamed >*)NULL )) ; 318 319 // ... and set his address to static pointer! 320 pTypeCollection = &aTypeCollection ; 321 } 322 } 323 324 return pTypeCollection->getTypes() ; 325 } 326 327 Sequence< sal_Int8 > SAL_CALL RootActionTriggerContainer::getImplementationId() throw ( RuntimeException ) 328 { 329 // Create one Id for all instances of this class. 330 // Use ethernet address to do this! (sal_True) 331 332 // Optimize this method 333 // We initialize a static variable only one time. And we don't must use a mutex at every call! 334 // For the first call; pID is NULL - for the second call pID is different from NULL! 335 static ::cppu::OImplementationId* pID = NULL ; 336 337 if ( pID == NULL ) 338 { 339 // Ready for multithreading; get global mutex for first call of this method only! see before 340 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; 341 342 // Control these pointer again ... it can be, that another instance will be faster then these! 343 if ( pID == NULL ) 344 { 345 // Create a new static ID ... 346 static ::cppu::OImplementationId aID( sal_False ) ; 347 // ... and set his address to static pointer! 348 pID = &aID ; 349 } 350 } 351 352 return pID->getImplementationId() ; 353 } 354 355 // private implementation helper 356 void RootActionTriggerContainer::FillContainer() 357 { 358 m_bContainerCreated = sal_True; 359 m_bInContainerCreation = sal_True; 360 Reference<XIndexContainer> xXIndexContainer( (OWeakObject *)this, UNO_QUERY ); 361 ActionTriggerHelper::FillActionTriggerContainerFromMenu( 362 xXIndexContainer, 363 m_pMenu ); 364 m_bInContainerCreation = sal_False; 365 } 366 ::rtl::OUString RootActionTriggerContainer::getName() throw ( RuntimeException ) 367 { 368 ::rtl::OUString sRet; 369 if( m_pMenuIdentifier ) 370 sRet = *m_pMenuIdentifier; 371 return sRet; 372 } 373 374 void RootActionTriggerContainer::setName( const ::rtl::OUString& ) throw ( RuntimeException) 375 { 376 throw RuntimeException(); 377 } 378 } 379 380