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