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 //_________________________________________________________________________________________________________________ 28 // my own includes 29 //_________________________________________________________________________________________________________________ 30 #include <helper/oframes.hxx> 31 32 #ifndef _FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_ 33 #include <threadhelp/resetableguard.hxx> 34 #endif 35 36 //_________________________________________________________________________________________________________________ 37 // interface includes 38 //_________________________________________________________________________________________________________________ 39 #include <com/sun/star/frame/XDesktop.hpp> 40 #include <com/sun/star/frame/FrameSearchFlag.hpp> 41 42 //_________________________________________________________________________________________________________________ 43 // includes of other projects 44 //_________________________________________________________________________________________________________________ 45 #include <vcl/svapp.hxx> 46 47 //_________________________________________________________________________________________________________________ 48 // namespace 49 //_________________________________________________________________________________________________________________ 50 51 namespace framework{ 52 53 using namespace ::com::sun::star::container ; 54 using namespace ::com::sun::star::frame ; 55 using namespace ::com::sun::star::lang ; 56 using namespace ::com::sun::star::uno ; 57 using namespace ::cppu ; 58 using namespace ::osl ; 59 using namespace ::rtl ; 60 using namespace ::std ; 61 using namespace ::vos ; 62 63 //_________________________________________________________________________________________________________________ 64 // non exported const 65 //_________________________________________________________________________________________________________________ 66 67 //_________________________________________________________________________________________________________________ 68 // non exported definitions 69 //_________________________________________________________________________________________________________________ 70 71 //_________________________________________________________________________________________________________________ 72 // declarations 73 //_________________________________________________________________________________________________________________ 74 75 //***************************************************************************************************************** 76 // constructor 77 //***************************************************************************************************************** 78 OFrames::OFrames( const css::uno::Reference< XMultiServiceFactory >& xFactory , 79 const css::uno::Reference< XFrame >& xOwner , 80 FrameContainer* pFrameContainer ) 81 // Init baseclasses first 82 : ThreadHelpBase ( &Application::GetSolarMutex() ) 83 // Init member 84 , m_xFactory ( xFactory ) 85 , m_xOwner ( xOwner ) 86 , m_pFrameContainer ( pFrameContainer ) 87 , m_bRecursiveSearchProtection( sal_False ) 88 { 89 // Safe impossible cases 90 // Method is not defined for ALL incoming parameters! 91 LOG_ASSERT( impldbg_checkParameter_OFramesCtor( xFactory, xOwner, pFrameContainer ), "OFrames::OFrames()\nInvalid parameter detected!\n" ) 92 } 93 94 //***************************************************************************************************************** 95 // (proteced!) destructor 96 //***************************************************************************************************************** 97 OFrames::~OFrames() 98 { 99 // Reset instance, free memory .... 100 impl_resetObject(); 101 } 102 103 //***************************************************************************************************************** 104 // XFrames 105 //***************************************************************************************************************** 106 void SAL_CALL OFrames::append( const css::uno::Reference< XFrame >& xFrame ) throw( RuntimeException ) 107 { 108 // Ready for multithreading 109 ResetableGuard aGuard( m_aLock ); 110 111 // Safe impossible cases 112 // Method is not defined for ALL incoming parameters! 113 LOG_ASSERT( impldbg_checkParameter_append( xFrame ), "OFrames::append()\nInvalid parameter detected!\n" ) 114 115 // Do the follow only, if owner instance valid! 116 // Lock owner for follow operations - make a "hard reference"! 117 css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY ); 118 if ( xOwner.is() == sal_True ) 119 { 120 // Append frame to the end of the container ... 121 m_pFrameContainer->append( xFrame ); 122 // Set owner of this instance as parent of the new frame in container! 123 xFrame->setCreator( xOwner ); 124 } 125 // Else; Do nothing! Ouer owner is dead. 126 LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::append()\nOuer owner is dead - you can't append any frames ...!\n" ) 127 } 128 129 //***************************************************************************************************************** 130 // XFrames 131 //***************************************************************************************************************** 132 void SAL_CALL OFrames::remove( const css::uno::Reference< XFrame >& xFrame ) throw( RuntimeException ) 133 { 134 // Ready for multithreading 135 ResetableGuard aGuard( m_aLock ); 136 137 // Safe impossible cases 138 // Method is not defined for ALL incoming parameters! 139 LOG_ASSERT( impldbg_checkParameter_remove( xFrame ), "OFrames::remove()\nInvalid parameter detected!\n" ) 140 141 // Do the follow only, if owner instance valid! 142 // Lock owner for follow operations - make a "hard reference"! 143 css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY ); 144 if ( xOwner.is() == sal_True ) 145 { 146 // Search frame and remove it from container ... 147 m_pFrameContainer->remove( xFrame ); 148 // Don't reset owner-property of removed frame! 149 // This must do the caller of this method himself. 150 // See documentation of interface XFrames for further informations. 151 } 152 // Else; Do nothing! Ouer owner is dead. 153 LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::remove()\nOuer owner is dead - you can't remove any frames ...!\n" ) 154 } 155 156 //***************************************************************************************************************** 157 // XFrames 158 //***************************************************************************************************************** 159 Sequence< css::uno::Reference< XFrame > > SAL_CALL OFrames::queryFrames( sal_Int32 nSearchFlags ) throw( RuntimeException ) 160 { 161 // Ready for multithreading 162 ResetableGuard aGuard( m_aLock ); 163 164 // Safe impossible cases 165 // Method is not defined for ALL incoming parameters! 166 LOG_ASSERT( impldbg_checkParameter_queryFrames( nSearchFlags ), "OFrames::queryFrames()\nInvalid parameter detected!\n" ) 167 168 // Set default return value. (empty sequence) 169 Sequence< css::uno::Reference< XFrame > > seqFrames; 170 171 // Do the follow only, if owner instance valid. 172 // Lock owner for follow operations - make a "hard reference"! 173 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); 174 if ( xOwner.is() == sal_True ) 175 { 176 // Work only, if search was not started here ...! 177 if( m_bRecursiveSearchProtection == sal_False ) 178 { 179 // This class is a helper for services, which must implement XFrames. 180 // His parent and childs are MY parent and childs to. 181 // All searchflags are supported by this implementation! 182 // If some flags should not be supported - don't call me with this flags!!! 183 184 //_____________________________________________________________________________________________________________ 185 // Search with AUTO-flag is not supported yet! 186 // We think about right implementation. 187 LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch with AUTO-flag is not supported yet!\nWe think about right implementation.\n" ) 188 // If searched for tasks ... 189 // Its not supported yet. 190 LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch for tasks not supported yet!\n" ) 191 192 //_____________________________________________________________________________________________________________ 193 // Search for ALL and GLOBAL is superflous! 194 // We support all necessary flags, from which these two flags are derived. 195 // ALL = PARENT + SELF + CHILDREN + SIBLINGS 196 // GLOBAL = ALL + TASKS 197 198 //_____________________________________________________________________________________________________________ 199 // Add parent to list ... if any exist! 200 if( nSearchFlags & FrameSearchFlag::PARENT ) 201 { 202 css::uno::Reference< XFrame > xParent( xOwner->getCreator(), UNO_QUERY ); 203 if( xParent.is() == sal_True ) 204 { 205 Sequence< css::uno::Reference< XFrame > > seqParent( 1 ); 206 seqParent[0] = xParent; 207 impl_appendSequence( seqFrames, seqParent ); 208 } 209 } 210 211 //_____________________________________________________________________________________________________________ 212 // Add owner to list if SELF is searched. 213 if( nSearchFlags & FrameSearchFlag::SELF ) 214 { 215 Sequence< css::uno::Reference< XFrame > > seqSelf( 1 ); 216 seqSelf[0] = xOwner; 217 impl_appendSequence( seqFrames, seqSelf ); 218 } 219 220 //_____________________________________________________________________________________________________________ 221 // Add SIBLINGS to list. 222 if( nSearchFlags & FrameSearchFlag::SIBLINGS ) 223 { 224 // Else; start a new search. 225 // Protect this instance against recursive calls from parents. 226 m_bRecursiveSearchProtection = sal_True; 227 // Ask parent of my owner for frames and append results to return list. 228 css::uno::Reference< XFramesSupplier > xParent( xOwner->getCreator(), UNO_QUERY ); 229 // If a parent exist ... 230 if ( xParent.is() == sal_True ) 231 { 232 // ... ask him for right frames. 233 impl_appendSequence( seqFrames, xParent->getFrames()->queryFrames( nSearchFlags ) ); 234 } 235 // We have all searched informations. 236 // Reset protection-mode. 237 m_bRecursiveSearchProtection = sal_False; 238 } 239 240 //_____________________________________________________________________________________________________________ 241 // If searched for children, step over all elements in container and collect the informations. 242 if ( nSearchFlags & FrameSearchFlag::CHILDREN ) 243 { 244 // Don't search for parents, siblings and self at childrens! 245 // These things are supported by this instance himself. 246 sal_Int32 nChildSearchFlags = FrameSearchFlag::SELF | FrameSearchFlag::CHILDREN; 247 // Step over all items of container and ask childrens for frames. 248 sal_uInt32 nCount = m_pFrameContainer->getCount(); 249 for ( sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex ) 250 { 251 // We don't must control this conversion. 252 // We have done this at append()! 253 css::uno::Reference< XFramesSupplier > xItem( (*m_pFrameContainer)[nIndex], UNO_QUERY ); 254 impl_appendSequence( seqFrames, xItem->getFrames()->queryFrames( nChildSearchFlags ) ); 255 } 256 } 257 } 258 } 259 // Else; Do nothing! Ouer owner is dead. 260 LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::queryFrames()\nOuer owner is dead - you can't query for frames ...!\n" ) 261 262 // Resturn result of this operation. 263 return seqFrames; 264 } 265 266 //***************************************************************************************************************** 267 // XIndexAccess 268 //***************************************************************************************************************** 269 sal_Int32 SAL_CALL OFrames::getCount() throw( RuntimeException ) 270 { 271 // Ready for multithreading 272 ResetableGuard aGuard( m_aLock ); 273 274 // Set default return value. 275 sal_Int32 nCount = 0; 276 277 // Do the follow only, if owner instance valid. 278 // Lock owner for follow operations - make a "hard reference"! 279 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); 280 if ( xOwner.is() == sal_True ) 281 { 282 // Set CURRENT size of container for return. 283 nCount = m_pFrameContainer->getCount(); 284 } 285 286 // Return result. 287 return nCount; 288 } 289 290 //***************************************************************************************************************** 291 // XIndexAccess 292 //***************************************************************************************************************** 293 Any SAL_CALL OFrames::getByIndex( sal_Int32 nIndex ) throw( IndexOutOfBoundsException , 294 WrappedTargetException , 295 RuntimeException ) 296 { 297 // Ready for multithreading 298 ResetableGuard aGuard( m_aLock ); 299 300 sal_uInt32 nCount = m_pFrameContainer->getCount(); 301 if ( nIndex < 0 || ( sal::static_int_cast< sal_uInt32 >( nIndex ) >= nCount )) 302 throw IndexOutOfBoundsException( OUString::createFromAscii( "OFrames::getByIndex - Index out of bounds" ), 303 (OWeakObject *)this ); 304 305 // Set default return value. 306 Any aReturnValue; 307 308 // Do the follow only, if owner instance valid. 309 // Lock owner for follow operations - make a "hard reference"! 310 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); 311 if ( xOwner.is() == sal_True ) 312 { 313 // Get element form container. 314 // (If index not valid, FrameContainer return NULL!) 315 aReturnValue <<= (*m_pFrameContainer)[nIndex]; 316 } 317 318 // Return result of this operation. 319 return aReturnValue; 320 } 321 322 //***************************************************************************************************************** 323 // XElementAccess 324 //***************************************************************************************************************** 325 Type SAL_CALL OFrames::getElementType() throw( RuntimeException ) 326 { 327 // This "container" support XFrame-interfaces only! 328 return ::getCppuType( (const css::uno::Reference< XFrame >*)NULL ); 329 } 330 331 //***************************************************************************************************************** 332 // XElementAccess 333 //***************************************************************************************************************** 334 sal_Bool SAL_CALL OFrames::hasElements() throw( RuntimeException ) 335 { 336 // Ready for multithreading 337 ResetableGuard aGuard( m_aLock ); 338 339 // Set default return value. 340 sal_Bool bHasElements = sal_False; 341 // Do the follow only, if owner instance valid. 342 // Lock owner for follow operations - make a "hard reference"! 343 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); 344 if ( xOwner.is() == sal_True ) 345 { 346 // If some elements exist ... 347 if ( m_pFrameContainer->getCount() > 0 ) 348 { 349 // ... change this state value! 350 bHasElements = sal_True; 351 } 352 } 353 // Return result of this operation. 354 return bHasElements; 355 } 356 357 //***************************************************************************************************************** 358 // proteced method 359 //***************************************************************************************************************** 360 void OFrames::impl_resetObject() 361 { 362 // Attention: 363 // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)! 364 // It exist two ways to call this method. From destructor and from disposing(). 365 // I can't say, which one is the first. Normaly the disposing-call - but other way .... 366 367 // This instance can't work if the weakreference to owner is invalid! 368 // Destroy this to reset this object. 369 m_xOwner = WeakReference< XFrame >(); 370 // Reset pointer to shared container to! 371 m_pFrameContainer = NULL; 372 } 373 374 //***************************************************************************************************************** 375 // private method 376 //***************************************************************************************************************** 377 void OFrames::impl_appendSequence( Sequence< css::uno::Reference< XFrame > >& seqDestination , 378 const Sequence< css::uno::Reference< XFrame > >& seqSource ) 379 { 380 // Get some informations about the sequences. 381 sal_Int32 nSourceCount = seqSource.getLength(); 382 sal_Int32 nDestinationCount = seqDestination.getLength(); 383 const css::uno::Reference< XFrame >* pSourceAccess = seqSource.getConstArray(); 384 css::uno::Reference< XFrame >* pDestinationAccess = seqDestination.getArray(); 385 386 // Get memory for result list. 387 Sequence< css::uno::Reference< XFrame > > seqResult ( nSourceCount + nDestinationCount ); 388 css::uno::Reference< XFrame >* pResultAccess = seqResult.getArray(); 389 sal_Int32 nResultPosition = 0; 390 391 // Copy all items from first sequence. 392 for ( sal_Int32 nSourcePosition=0; nSourcePosition<nSourceCount; ++nSourcePosition ) 393 { 394 pResultAccess[nResultPosition] = pSourceAccess[nSourcePosition]; 395 ++nResultPosition; 396 } 397 398 // Don't manipulate nResultPosition between these two loops! 399 // Its the current position in the result list. 400 401 // Copy all items from second sequence. 402 for ( sal_Int32 nDestinationPosition=0; nDestinationPosition<nDestinationCount; ++nDestinationPosition ) 403 { 404 pResultAccess[nResultPosition] = pDestinationAccess[nDestinationPosition]; 405 ++nResultPosition; 406 } 407 408 // Return result of this operation. 409 seqDestination.realloc( 0 ); 410 seqDestination = seqResult; 411 } 412 413 //_________________________________________________________________________________________________________________ 414 // debug methods 415 //_________________________________________________________________________________________________________________ 416 417 /*----------------------------------------------------------------------------------------------------------------- 418 The follow methods checks the parameter for other functions. If a parameter or his value is non valid, 419 we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT! 420 421 ATTENTION 422 423 If you miss a test for one of this parameters, contact the autor or add it himself !(?) 424 But ... look for right testing! See using of this methods! 425 -----------------------------------------------------------------------------------------------------------------*/ 426 427 #ifdef ENABLE_ASSERTIONS 428 429 //***************************************************************************************************************** 430 // An instance of this class can only work with valid initialization. 431 // We share the mutex with ouer owner class, need a valid factory to instanciate new services and 432 // use the access to ouer owner for some operations. 433 sal_Bool OFrames::impldbg_checkParameter_OFramesCtor( const css::uno::Reference< XMultiServiceFactory >& xFactory , 434 const css::uno::Reference< XFrame >& xOwner , 435 FrameContainer* pFrameContainer ) 436 { 437 // Set default return value. 438 sal_Bool bOK = sal_True; 439 // Check parameter. 440 if ( 441 ( &xFactory == NULL ) || 442 ( &xOwner == NULL ) || 443 ( xFactory.is() == sal_False ) || 444 ( xOwner.is() == sal_False ) || 445 ( pFrameContainer == NULL ) 446 ) 447 { 448 bOK = sal_False ; 449 } 450 // Return result of check. 451 return bOK ; 452 } 453 454 //***************************************************************************************************************** 455 // Its only allowed to add valid references to container. 456 // AND - alle frames must support XFrames-interface! 457 sal_Bool OFrames::impldbg_checkParameter_append( const css::uno::Reference< XFrame >& xFrame ) 458 { 459 // Set default return value. 460 sal_Bool bOK = sal_True; 461 // Check parameter. 462 if ( 463 ( &xFrame == NULL ) || 464 ( xFrame.is() == sal_False ) 465 ) 466 { 467 bOK = sal_False ; 468 } 469 // Return result of check. 470 return bOK ; 471 } 472 473 //***************************************************************************************************************** 474 // Its only allowed to add valid references to container... 475 // ... => You can only delete valid references! 476 sal_Bool OFrames::impldbg_checkParameter_remove( const css::uno::Reference< XFrame >& xFrame ) 477 { 478 // Set default return value. 479 sal_Bool bOK = sal_True; 480 // Check parameter. 481 if ( 482 ( &xFrame == NULL ) || 483 ( xFrame.is() == sal_False ) 484 ) 485 { 486 bOK = sal_False ; 487 } 488 // Return result of check. 489 return bOK ; 490 } 491 492 //***************************************************************************************************************** 493 // A search for frames must initiate with right flags. 494 // Some one are superflous and not supported yet. But here we control only the range of incoming parameter! 495 sal_Bool OFrames::impldbg_checkParameter_queryFrames( sal_Int32 nSearchFlags ) 496 { 497 // Set default return value. 498 sal_Bool bOK = sal_True; 499 // Check parameter. 500 if ( 501 ( nSearchFlags != FrameSearchFlag::AUTO ) && 502 ( !( nSearchFlags & FrameSearchFlag::PARENT ) ) && 503 ( !( nSearchFlags & FrameSearchFlag::SELF ) ) && 504 ( !( nSearchFlags & FrameSearchFlag::CHILDREN ) ) && 505 ( !( nSearchFlags & FrameSearchFlag::CREATE ) ) && 506 ( !( nSearchFlags & FrameSearchFlag::SIBLINGS ) ) && 507 ( !( nSearchFlags & FrameSearchFlag::TASKS ) ) && 508 ( !( nSearchFlags & FrameSearchFlag::ALL ) ) && 509 ( !( nSearchFlags & FrameSearchFlag::GLOBAL ) ) 510 ) 511 { 512 bOK = sal_False ; 513 } 514 // Return result of check. 515 return bOK ; 516 } 517 518 #endif // #ifdef ENABLE_ASSERTIONS 519 520 } // namespace framework 521