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