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_embeddedobj.hxx" 30 #include <com/sun/star/embed/Aspects.hpp> 31 #include <com/sun/star/uno/XComponentContext.hpp> 32 #include <com/sun/star/frame/XComponentLoader.hpp> 33 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp> 34 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 35 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 36 #include <com/sun/star/lang/XSingleComponentFactory.hpp> 37 #include <com/sun/star/util/XCloseBroadcaster.hpp> 38 #include <com/sun/star/util/XCloseable.hpp> 39 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACESS_HPP_ 40 #include <com/sun/star/container/XNameAccess.hpp> 41 #endif 42 #include <com/sun/star/lang/XServiceInfo.hpp> 43 #include <com/sun/star/lang/XServiceInfo.hpp> 44 #include <com/sun/star/beans/XPropertySet.hpp> 45 #include <com/sun/star/beans/NamedValue.hpp> 46 #include <com/sun/star/frame/XModel.hpp> 47 #include <com/sun/star/frame/XDesktop.hpp> 48 #include <com/sun/star/frame/XFramesSupplier.hpp> 49 #include <com/sun/star/frame/XDispatchHelper.hpp> 50 #include <com/sun/star/frame/FrameSearchFlag.hpp> 51 #include <com/sun/star/frame/XControllerBorder.hpp> 52 #include <com/sun/star/util/XModifyBroadcaster.hpp> 53 #include <com/sun/star/frame/XDispatchProviderInterception.hpp> 54 #include <com/sun/star/awt/XTopWindow.hpp> 55 #include <com/sun/star/awt/PosSize.hpp> 56 #include <com/sun/star/awt/XView.hpp> 57 #include <com/sun/star/awt/WindowAttribute.hpp> 58 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp> 59 #include <com/sun/star/bridge/XBridgeSupplier2.hpp> 60 #include <com/sun/star/bridge/ModelDependent.hpp> 61 #include <com/sun/star/embed/XHatchWindow.hpp> 62 #include <com/sun/star/embed/XHatchWindowFactory.hpp> 63 #include <com/sun/star/embed/XInplaceClient.hpp> 64 #include <com/sun/star/frame/XLayoutManager.hpp> 65 #include <com/sun/star/frame/XMenuBarMergingAcceptor.hpp> 66 #include <com/sun/star/frame/XModuleManager.hpp> 67 #include <com/sun/star/ui/XDockingAreaAcceptor.hpp> 68 #include <com/sun/star/ui/XUIElementSettings.hpp> 69 #ifndef _COM_SUN_STAR_UI_XCONFIGURATIONMANAGER_HPP_ 70 #include <com/sun/star/ui/XUIConfigurationManager.hpp> 71 #endif 72 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> 73 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> 74 #include <com/sun/star/lang/XServiceInfo.hpp> 75 #include <com/sun/star/embed/StateChangeInProgressException.hpp> 76 77 #include <com/sun/star/embed/EmbedMisc.hpp> 78 #include <com/sun/star/embed/EmbedStates.hpp> 79 #include <osl/diagnose.h> 80 #include <rtl/process.h> 81 82 #include <comphelper/processfactory.hxx> 83 #include <comphelper/namedvaluecollection.hxx> 84 85 #include "docholder.hxx" 86 #include "commonembobj.hxx" 87 #include "intercept.hxx" 88 89 90 // #include <toolkit/helper/vclunohelper.hxx> 91 // #include <vcl/window.hxx> 92 93 #define HATCH_BORDER_WIDTH (((m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) && \ 94 m_pEmbedObj->getCurrentState()!=embed::EmbedStates::UI_ACTIVE) ? 0 : 4 ) 95 96 using namespace ::com::sun::star; 97 98 //=========================================================================== 99 100 class IntCounterGuard { 101 sal_Int32& m_nFlag; 102 public: 103 IntCounterGuard( sal_Int32& nFlag ) 104 : m_nFlag( nFlag ) 105 { 106 m_nFlag++; 107 } 108 109 ~IntCounterGuard() 110 { 111 if ( m_nFlag ) 112 m_nFlag--; 113 } 114 }; 115 116 //=========================================================================== 117 118 static void InsertMenu_Impl( const uno::Reference< container::XIndexContainer >& xTargetMenu, 119 sal_Int32 nTargetIndex, 120 const uno::Reference< container::XIndexAccess >& xSourceMenu, 121 sal_Int32 nSourceIndex, 122 const ::rtl::OUString aContModuleName, 123 const uno::Reference< frame::XDispatchProvider >& xSourceDisp ) 124 { 125 sal_Int32 nInd = 0; 126 ::rtl::OUString aModuleIdentPropName( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ) ); 127 ::rtl::OUString aDispProvPropName( RTL_CONSTASCII_USTRINGPARAM( "DispatchProvider" ) ); 128 sal_Bool bModuleNameSet = sal_False; 129 sal_Bool bDispProvSet = sal_False; 130 131 uno::Sequence< beans::PropertyValue > aSourceProps; 132 xSourceMenu->getByIndex( nSourceIndex ) >>= aSourceProps; 133 uno::Sequence< beans::PropertyValue > aTargetProps( aSourceProps.getLength() ); 134 for ( nInd = 0; nInd < aSourceProps.getLength(); nInd++ ) 135 { 136 aTargetProps[nInd].Name = aSourceProps[nInd].Name; 137 if ( aContModuleName.getLength() && aTargetProps[nInd].Name.equals( aModuleIdentPropName ) ) 138 { 139 aTargetProps[nInd].Value <<= aContModuleName; 140 bModuleNameSet = sal_True; 141 } 142 else if ( aTargetProps[nInd].Name.equals( aDispProvPropName ) ) 143 { 144 aTargetProps[nInd].Value <<= xSourceDisp; 145 bDispProvSet = sal_True; 146 } 147 else 148 aTargetProps[nInd].Value = aSourceProps[nInd].Value; 149 } 150 151 if ( !bModuleNameSet && aContModuleName.getLength() ) 152 { 153 aTargetProps.realloc( ++nInd ); 154 aTargetProps[nInd-1].Name = aModuleIdentPropName; 155 aTargetProps[nInd-1].Value <<= aContModuleName; 156 } 157 158 if ( !bDispProvSet && xSourceDisp.is() ) 159 { 160 aTargetProps.realloc( ++nInd ); 161 aTargetProps[nInd-1].Name = aDispProvPropName; 162 aTargetProps[nInd-1].Value <<= xSourceDisp; 163 } 164 165 xTargetMenu->insertByIndex( nTargetIndex, uno::makeAny( aTargetProps ) ); 166 } 167 168 //=========================================================================== 169 DocumentHolder::DocumentHolder( const uno::Reference< lang::XMultiServiceFactory >& xFactory, 170 OCommonEmbeddedObject* pEmbObj ) 171 : m_pEmbedObj( pEmbObj ), 172 m_pInterceptor( NULL ), 173 m_xFactory( xFactory ), 174 m_bReadOnly( sal_False ), 175 m_bWaitForClose( sal_False ), 176 m_bAllowClosing( sal_False ), 177 m_bDesktopTerminated( sal_False ), 178 m_nNoBorderResizeReact( 0 ), 179 m_nNoResizeReact( 0 ) 180 { 181 m_aOutplaceFrameProps.realloc( 3 ); 182 beans::NamedValue aArg; 183 184 aArg.Name = ::rtl::OUString::createFromAscii("TopWindow"); 185 aArg.Value <<= sal_True; 186 m_aOutplaceFrameProps[0] <<= aArg; 187 188 aArg.Name = ::rtl::OUString::createFromAscii("MakeVisible"); 189 aArg.Value <<= sal_False; 190 m_aOutplaceFrameProps[1] <<= aArg; 191 192 const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); 193 uno::Reference< frame::XDesktop > xDesktop( m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); 194 if ( xDesktop.is() ) 195 { 196 m_refCount++; 197 try 198 { 199 xDesktop->addTerminateListener( this ); 200 } 201 catch ( uno::Exception& ) 202 { 203 } 204 m_refCount--; 205 206 aArg.Name = ::rtl::OUString::createFromAscii("ParentFrame"); 207 aArg.Value <<= xDesktop; //TODO/LATER: should use parent document frame 208 m_aOutplaceFrameProps[2] <<= aArg; 209 } 210 else 211 m_aOutplaceFrameProps.realloc( 2 ); 212 } 213 214 //--------------------------------------------------------------------------- 215 DocumentHolder::~DocumentHolder() 216 { 217 m_refCount++; // to allow deregistration as a listener 218 219 if( m_xFrame.is() ) 220 CloseFrame(); 221 222 if ( m_xComponent.is() ) 223 { 224 try { 225 CloseDocument( sal_True, sal_False ); 226 } catch( uno::Exception& ) {} 227 } 228 229 if ( m_pInterceptor ) 230 { 231 m_pInterceptor->DisconnectDocHolder(); 232 m_pInterceptor->release(); 233 } 234 235 if ( !m_bDesktopTerminated ) 236 FreeOffice(); 237 } 238 239 //--------------------------------------------------------------------------- 240 void DocumentHolder::CloseFrame() 241 { 242 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY ); 243 if ( xCloseBroadcaster.is() ) 244 xCloseBroadcaster->removeCloseListener( ( util::XCloseListener* )this ); 245 246 uno::Reference<util::XCloseable> xCloseable( 247 m_xFrame,uno::UNO_QUERY ); 248 if( xCloseable.is() ) 249 try { 250 xCloseable->close( sal_True ); 251 } 252 catch( const uno::Exception& ) { 253 } 254 else { 255 uno::Reference<lang::XComponent> xComp( m_xFrame,uno::UNO_QUERY ); 256 if( xComp.is() ) 257 xComp->dispose(); 258 } 259 260 uno::Reference< lang::XComponent > xComp( m_xHatchWindow, uno::UNO_QUERY ); 261 if ( xComp.is() ) 262 xComp->dispose(); 263 264 m_xHatchWindow = uno::Reference< awt::XWindow >(); 265 m_xOwnWindow = uno::Reference< awt::XWindow >(); 266 m_xFrame = uno::Reference< frame::XFrame >(); 267 } 268 269 //--------------------------------------------------------------------------- 270 void DocumentHolder::FreeOffice() 271 { 272 const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); 273 uno::Reference< frame::XDesktop > xDesktop( m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); 274 if ( xDesktop.is() ) 275 { 276 xDesktop->removeTerminateListener( this ); 277 278 // the following code is commented out since for now there is still no completely correct way to detect 279 // whether the office can be terminated, so it is better to have unnecessary process running than 280 // to loose any data 281 282 // uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY ); 283 // if ( xFramesSupplier.is() ) 284 // { 285 // uno::Reference< frame::XFrames > xFrames = xFramesSupplier->getFrames(); 286 // if ( xFrames.is() && !xFrames->hasElements() ) 287 // { 288 // try 289 // { 290 // xDesktop->terminate(); 291 // } 292 // catch( uno::Exception & ) 293 // {} 294 // } 295 // } 296 } 297 } 298 299 //--------------------------------------------------------------------------- 300 void DocumentHolder::CloseDocument( sal_Bool bDeliverOwnership, sal_Bool bWaitForClose ) 301 { 302 uno::Reference< util::XCloseBroadcaster > xBroadcaster( m_xComponent, uno::UNO_QUERY ); 303 if ( xBroadcaster.is() ) 304 { 305 uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY ); 306 if ( xEventBroadcaster.is() ) 307 xEventBroadcaster->removeEventListener( ( document::XEventListener* )this ); 308 else 309 { 310 // the object does not support document::XEventBroadcaster interface 311 // use the workaround, register for modified events 312 uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY ); 313 if ( xModifyBroadcaster.is() ) 314 xModifyBroadcaster->removeModifyListener( ( util::XModifyListener* )this ); 315 } 316 317 uno::Reference< util::XCloseable > xCloseable( xBroadcaster, uno::UNO_QUERY ); 318 if ( xCloseable.is() ) 319 { 320 m_bAllowClosing = sal_True; 321 m_bWaitForClose = bWaitForClose; 322 xCloseable->close( bDeliverOwnership ); 323 } 324 } 325 326 m_xComponent = 0; 327 } 328 329 //--------------------------------------------------------------------------- 330 void DocumentHolder::PlaceFrame( const awt::Rectangle& aNewRect ) 331 { 332 OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is(), 333 "The object does not have windows required for inplace mode!" ); 334 335 //TODO: may need mutex locking??? 336 if ( m_xFrame.is() && m_xOwnWindow.is() ) 337 { 338 // the frame can be replaced only in inplace mode 339 frame::BorderWidths aOldWidths; 340 IntCounterGuard aGuard( m_nNoBorderResizeReact ); 341 342 do 343 { 344 aOldWidths = m_aBorderWidths; 345 346 awt::Rectangle aHatchRect = AddBorderToArea( aNewRect ); 347 348 ResizeWindows_Impl( aHatchRect ); 349 350 } while ( aOldWidths.Left != m_aBorderWidths.Left 351 || aOldWidths.Top != m_aBorderWidths.Top 352 || aOldWidths.Right != m_aBorderWidths.Right 353 || aOldWidths.Bottom != m_aBorderWidths.Bottom ); 354 355 m_aObjRect = aNewRect; 356 } 357 } 358 359 //--------------------------------------------------------------------------- 360 void DocumentHolder::ResizeWindows_Impl( const awt::Rectangle& aHatchRect ) 361 { 362 OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is() /*&& m_xHatchWindow.is()*/, 363 "The object does not have windows required for inplace mode!" ); 364 if ( m_xHatchWindow.is() ) 365 { 366 m_xOwnWindow->setPosSize( HATCH_BORDER_WIDTH, 367 HATCH_BORDER_WIDTH, 368 aHatchRect.Width - 2*HATCH_BORDER_WIDTH, 369 aHatchRect.Height - 2*HATCH_BORDER_WIDTH, 370 awt::PosSize::POSSIZE ); 371 372 // Window* pWindow = VCLUnoHelper::GetWindow( m_xOwnWindow ); 373 374 m_xHatchWindow->setPosSize( aHatchRect.X, 375 aHatchRect.Y, 376 aHatchRect.Width, 377 aHatchRect.Height, 378 awt::PosSize::POSSIZE ); 379 } 380 else 381 m_xOwnWindow->setPosSize( aHatchRect.X + HATCH_BORDER_WIDTH, 382 aHatchRect.Y + HATCH_BORDER_WIDTH, 383 aHatchRect.Width - 2*HATCH_BORDER_WIDTH, 384 aHatchRect.Height - 2*HATCH_BORDER_WIDTH, 385 awt::PosSize::POSSIZE ); 386 } 387 388 //--------------------------------------------------------------------------- 389 sal_Bool DocumentHolder::SetFrameLMVisibility( const uno::Reference< frame::XFrame >& xFrame, sal_Bool bVisible ) 390 { 391 sal_Bool bResult = sal_False; 392 393 try 394 { 395 uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; 396 uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY_THROW ); 397 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager; 398 if ( xLayoutManager.is() ) 399 { 400 xLayoutManager->setVisible( bVisible ); 401 402 // MBA: locking is done only on the container LM, because it is not about hiding windows, it's about 403 // giving up control over the component window (and stopping to listen for resize events of the container window) 404 if ( bVisible ) 405 xLayoutManager->unlock(); 406 else 407 xLayoutManager->lock(); 408 409 bResult = sal_True; 410 } 411 } 412 catch( uno::Exception& ) 413 {} 414 415 return bResult; 416 } 417 418 //--------------------------------------------------------------------------- 419 sal_Bool DocumentHolder::ShowInplace( const uno::Reference< awt::XWindowPeer >& xParent, 420 const awt::Rectangle& aRectangleToShow, 421 const uno::Reference< frame::XDispatchProvider >& xContDisp ) 422 { 423 OSL_ENSURE( !m_xFrame.is(), "A frame exists already!" ); 424 425 if ( !m_xFrame.is() ) 426 { 427 uno::Reference < frame::XModel > xModel( GetComponent(), uno::UNO_QUERY ); 428 awt::Rectangle aHatchRectangle = AddBorderToArea( aRectangleToShow ); 429 430 awt::Rectangle aOwnRectangle( HATCH_BORDER_WIDTH, 431 HATCH_BORDER_WIDTH, 432 aHatchRectangle.Width - 2*HATCH_BORDER_WIDTH, 433 aHatchRectangle.Height - 2*HATCH_BORDER_WIDTH ); 434 uno::Reference< awt::XWindow > xHWindow; 435 uno::Reference< awt::XWindowPeer > xMyParent( xParent ); 436 437 if ( xModel.is() ) 438 { 439 440 uno::Reference< embed::XHatchWindowFactory > xHatchFactory( 441 m_xFactory->createInstance( 442 ::rtl::OUString::createFromAscii( "com.sun.star.embed.HatchWindowFactory" ) ), 443 uno::UNO_QUERY ); 444 445 if ( !xHatchFactory.is() ) 446 throw uno::RuntimeException(); 447 448 uno::Reference< embed::XHatchWindow > xHatchWindow = 449 xHatchFactory->createHatchWindowInstance( xParent, 450 aHatchRectangle, 451 awt::Size( HATCH_BORDER_WIDTH, HATCH_BORDER_WIDTH ) ); 452 453 uno::Reference< awt::XWindowPeer > xHatchWinPeer( xHatchWindow, uno::UNO_QUERY ); 454 xHWindow = uno::Reference< awt::XWindow >( xHatchWinPeer, uno::UNO_QUERY ); 455 if ( !xHWindow.is() ) 456 throw uno::RuntimeException(); // TODO: can not create own window 457 458 xHatchWindow->setController( uno::Reference< embed::XHatchWindowController >( 459 static_cast< embed::XHatchWindowController* >( this ) ) ); 460 461 xMyParent = xHatchWinPeer; 462 } 463 else 464 { 465 aOwnRectangle.X += aHatchRectangle.X; 466 aOwnRectangle.Y += aHatchRectangle.Y; 467 } 468 469 awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_TOP, 470 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("dockingwindow") ), 471 xMyParent, 472 0, 473 awt::Rectangle(),//aOwnRectangle, 474 awt::WindowAttribute::SHOW | awt::VclWindowPeerAttribute::CLIPCHILDREN ); 475 476 uno::Reference< awt::XToolkit > xToolkit( 477 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ), 478 uno::UNO_QUERY ); 479 if ( !xToolkit.is() ) 480 throw uno::RuntimeException(); 481 482 uno::Reference< awt::XWindowPeer > xNewWinPeer = xToolkit->createWindow( aOwnWinDescriptor ); 483 uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer, uno::UNO_QUERY ); 484 if ( !xOwnWindow.is() ) 485 throw uno::RuntimeException(); // TODO: can not create own window 486 487 // create a frame based on the specified window 488 uno::Reference< lang::XSingleServiceFactory > xFrameFact( 489 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.TaskCreator" ) ), 490 uno::UNO_QUERY_THROW ); 491 492 uno::Sequence< uno::Any > aArgs( 2 ); 493 beans::NamedValue aArg; 494 495 aArg.Name = ::rtl::OUString::createFromAscii("ContainerWindow"); 496 aArg.Value <<= xOwnWindow; 497 aArgs[0] <<= aArg; 498 499 uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY ); 500 if ( xContFrame.is() ) 501 { 502 aArg.Name = ::rtl::OUString::createFromAscii("ParentFrame"); 503 aArg.Value <<= xContFrame; 504 aArgs[1] <<= aArg; 505 } 506 else 507 aArgs.realloc( 1 ); 508 509 // the call will create, initialize the frame, and register it in the parent 510 m_xFrame.set( xFrameFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY_THROW ); 511 512 m_xHatchWindow = xHWindow; 513 m_xOwnWindow = xOwnWindow; 514 515 if ( !SetFrameLMVisibility( m_xFrame, sal_False ) ) 516 { 517 OSL_ENSURE( sal_False, "Can't deactivate LayoutManager!\n" ); 518 // TODO/LATER: error handling? 519 } 520 521 // m_bIsInplace = sal_True; TODO: ? 522 523 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY ); 524 if ( xCloseBroadcaster.is() ) 525 xCloseBroadcaster->addCloseListener( ( util::XCloseListener* )this ); 526 527 // TODO: some listeners to the frame and the window ( resize for example ) 528 } 529 530 if ( m_xComponent.is() ) 531 { 532 if ( !LoadDocToFrame( sal_True ) ) 533 { 534 CloseFrame(); 535 return sal_False; 536 } 537 538 uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY ); 539 if ( xControllerBorder.is() ) 540 { 541 m_aBorderWidths = xControllerBorder->getBorder(); 542 xControllerBorder->addBorderResizeListener( (frame::XBorderResizeListener*)this ); 543 } 544 545 PlaceFrame( aRectangleToShow ); 546 547 if ( m_xHatchWindow.is() ) 548 m_xHatchWindow->setVisible( sal_True ); 549 550 return sal_True; 551 } 552 553 return sal_False; 554 } 555 556 //--------------------------------------------------------------------------- 557 uno::Reference< container::XIndexAccess > DocumentHolder::RetrieveOwnMenu_Impl() 558 { 559 uno::Reference< container::XIndexAccess > xResult; 560 561 uno::Reference< ::com::sun::star::ui::XUIConfigurationManagerSupplier > xUIConfSupplier( 562 m_xComponent, 563 uno::UNO_QUERY ); 564 uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > xUIConfigManager; 565 if( xUIConfSupplier.is()) 566 { 567 xUIConfigManager.set( 568 xUIConfSupplier->getUIConfigurationManager(), 569 uno::UNO_QUERY_THROW ); 570 } 571 572 try 573 { 574 if( xUIConfigManager.is()) 575 { 576 xResult = xUIConfigManager->getSettings( 577 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ), 578 sal_False ); 579 } 580 } 581 catch( uno::Exception ) 582 {} 583 584 if ( !xResult.is() ) 585 { 586 // no internal document configuration, use the one from the module 587 uno::Reference< ::com::sun::star::frame::XModuleManager > xModuleMan( 588 m_xFactory->createInstance( 589 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ), 590 uno::UNO_QUERY_THROW ); 591 ::rtl::OUString aModuleIdent = 592 xModuleMan->identify( uno::Reference< uno::XInterface >( m_xComponent, uno::UNO_QUERY ) ); 593 594 if ( aModuleIdent.getLength() ) 595 { 596 uno::Reference< ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier > xModConfSupplier( 597 m_xFactory->createInstance( ::rtl::OUString( 598 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ) ) ), 599 uno::UNO_QUERY_THROW ); 600 uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > xModUIConfMan( 601 xModConfSupplier->getUIConfigurationManager( aModuleIdent ), 602 uno::UNO_QUERY_THROW ); 603 xResult = xModUIConfMan->getSettings( 604 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ), 605 sal_False ); 606 } 607 } 608 609 if ( !xResult.is() ) 610 throw uno::RuntimeException(); 611 612 return xResult; 613 } 614 615 //--------------------------------------------------------------------------- 616 void DocumentHolder::FindConnectPoints( 617 const uno::Reference< container::XIndexAccess >& xMenu, 618 sal_Int32 nConnectPoints[2] ) 619 throw ( uno::Exception ) 620 { 621 nConnectPoints[0] = -1; 622 nConnectPoints[1] = -1; 623 for ( sal_Int32 nInd = 0; nInd < xMenu->getCount(); nInd++ ) 624 { 625 uno::Sequence< beans::PropertyValue > aProps; 626 xMenu->getByIndex( nInd ) >>= aProps; 627 rtl::OUString aCommand; 628 for ( sal_Int32 nSeqInd = 0; nSeqInd < aProps.getLength(); nSeqInd++ ) 629 if ( aProps[nSeqInd].Name.equalsAscii( "CommandURL" ) ) 630 { 631 aProps[nSeqInd].Value >>= aCommand; 632 break; 633 } 634 635 if ( !aCommand.getLength() ) 636 throw uno::RuntimeException(); 637 638 if ( aCommand.equalsAscii( ".uno:PickList" ) ) 639 nConnectPoints[0] = nInd; 640 else if ( aCommand.equalsAscii( ".uno:WindowList" ) ) 641 nConnectPoints[1] = nInd; 642 } 643 } 644 645 //--------------------------------------------------------------------------- 646 uno::Reference< container::XIndexAccess > DocumentHolder::MergeMenuesForInplace( 647 const uno::Reference< container::XIndexAccess >& xContMenu, 648 const uno::Reference< frame::XDispatchProvider >& xContDisp, 649 const ::rtl::OUString& aContModuleName, 650 const uno::Reference< container::XIndexAccess >& xOwnMenu, 651 const uno::Reference< frame::XDispatchProvider >& xOwnDisp ) 652 throw ( uno::Exception ) 653 { 654 // TODO/LATER: use dispatch providers on merge 655 656 sal_Int32 nContPoints[2]; 657 sal_Int32 nOwnPoints[2]; 658 659 uno::Reference< lang::XSingleComponentFactory > xIndAccessFact( xContMenu, uno::UNO_QUERY_THROW ); 660 661 uno::Reference< uno::XComponentContext > xComponentContext; 662 663 uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); 664 if ( xProps.is() ) 665 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= 666 xComponentContext; 667 668 uno::Reference< container::XIndexContainer > xMergedMenu( 669 xIndAccessFact->createInstanceWithContext( xComponentContext ), 670 uno::UNO_QUERY_THROW ); 671 672 FindConnectPoints( xContMenu, nContPoints ); 673 FindConnectPoints( xOwnMenu, nOwnPoints ); 674 675 for ( sal_Int32 nInd = 0; nInd < xOwnMenu->getCount(); nInd++ ) 676 { 677 if ( nOwnPoints[0] == nInd ) 678 { 679 if ( nContPoints[0] >= 0 && nContPoints[0] < xContMenu->getCount() ) 680 { 681 InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[0], aContModuleName, xContDisp ); 682 } 683 } 684 else if ( nOwnPoints[1] == nInd ) 685 { 686 if ( nContPoints[1] >= 0 && nContPoints[1] < xContMenu->getCount() ) 687 { 688 InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[1], aContModuleName, xContDisp ); 689 } 690 } 691 else 692 InsertMenu_Impl( xMergedMenu, nInd, xOwnMenu, nInd, ::rtl::OUString(), xOwnDisp ); 693 } 694 695 return uno::Reference< container::XIndexAccess >( xMergedMenu, uno::UNO_QUERY_THROW ); 696 } 697 698 //--------------------------------------------------------------------------- 699 sal_Bool DocumentHolder::MergeMenues_Impl( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xOwnLM, 700 const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContLM, 701 const uno::Reference< frame::XDispatchProvider >& xContDisp, 702 const ::rtl::OUString& aContModuleName ) 703 { 704 sal_Bool bMenuMerged = sal_False; 705 try 706 { 707 uno::Reference< ::com::sun::star::ui::XUIElementSettings > xUISettings( 708 xContLM->getElement( 709 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ) ), 710 uno::UNO_QUERY_THROW ); 711 uno::Reference< container::XIndexAccess > xContMenu = xUISettings->getSettings( sal_True ); 712 if ( !xContMenu.is() ) 713 throw uno::RuntimeException(); 714 715 uno::Reference< container::XIndexAccess > xOwnMenu = RetrieveOwnMenu_Impl(); 716 uno::Reference< frame::XDispatchProvider > xOwnDisp( m_xFrame, uno::UNO_QUERY_THROW ); 717 718 uno::Reference< container::XIndexAccess > xMergedMenu = MergeMenuesForInplace( xContMenu, xContDisp, aContModuleName, xOwnMenu, xOwnDisp ); 719 uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, 720 uno::UNO_QUERY_THROW ); 721 bMenuMerged = xMerge->setMergedMenuBar( xMergedMenu ); 722 } 723 catch( uno::Exception& ) 724 {} 725 726 return bMenuMerged; 727 } 728 729 sal_Bool DocumentHolder::ShowUI( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContainerLM, 730 const uno::Reference< frame::XDispatchProvider >& xContainerDP, 731 const ::rtl::OUString& aContModuleName ) 732 { 733 sal_Bool bResult = sal_False; 734 if ( xContainerLM.is() ) 735 { 736 // the LM of the embedded frame and its current DockingAreaAcceptor 737 uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM; 738 uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xDocAreaAcc; 739 740 try 741 { 742 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW ); 743 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM; 744 xDocAreaAcc = xContainerLM->getDockingAreaAcceptor(); 745 } 746 catch( uno::Exception& ){} 747 748 // make sure that lock state of LM is correct even if an exception is thrown in between 749 sal_Bool bUnlock = sal_False; 750 sal_Bool bLock = sal_False; 751 if ( xOwnLM.is() && xDocAreaAcc.is() ) 752 { 753 try 754 { 755 // take over the control over the containers window 756 // as long as the LM is invisible and locked an empty tool space will be used on resizing 757 xOwnLM->setDockingAreaAcceptor( xDocAreaAcc ); 758 759 // try to merge menues; don't do anything else if it fails 760 if ( MergeMenues_Impl( xOwnLM, xContainerLM, xContainerDP, aContModuleName ) ) 761 { 762 // make sure that the container LM does not control the size of the containers window anymore 763 // this must be done after merging menues as we won't get the container menu otherwise 764 xContainerLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() ); 765 766 // prevent further changes at this LM 767 xContainerLM->setVisible( sal_False ); 768 xContainerLM->lock(); 769 bUnlock = sal_True; 770 771 // by unlocking the LM each layout change will now resize the containers window; pending layouts will be processed now 772 xOwnLM->setVisible( sal_True ); 773 774 uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); 775 if ( xSupp.is() ) 776 xSupp->setActiveFrame( m_xFrame ); 777 778 xOwnLM->unlock(); 779 bLock = sal_True; 780 bResult = sal_True; 781 782 // TODO/LATER: The following action should be done only if the window is not hidden 783 // otherwise the activation must fail, unfortunatelly currently it is not possible 784 // to detect whether the window is hidden using UNO API 785 m_xOwnWindow->setFocus(); 786 } 787 } 788 catch( uno::Exception& ) 789 { 790 // activation failed; reestablish old state 791 try 792 { 793 uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); 794 if ( xSupp.is() ) 795 xSupp->setActiveFrame( 0 ); 796 797 // remove control about containers window from own LM 798 if ( bLock ) 799 xOwnLM->lock(); 800 xOwnLM->setVisible( sal_False ); 801 xOwnLM->setDockingAreaAcceptor( uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor >() ); 802 803 // unmerge menu 804 uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW ); 805 xMerge->removeMergedMenuBar(); 806 } 807 catch( uno::Exception& ) {} 808 809 try 810 { 811 // reestablish control of containers window 812 xContainerLM->setDockingAreaAcceptor( xDocAreaAcc ); 813 xContainerLM->setVisible( sal_True ); 814 if ( bUnlock ) 815 xContainerLM->unlock(); 816 } 817 catch( uno::Exception& ) {} 818 } 819 } 820 } 821 822 return bResult; 823 } 824 825 //--------------------------------------------------------------------------- 826 sal_Bool DocumentHolder::HideUI( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContainerLM ) 827 { 828 sal_Bool bResult = sal_False; 829 830 if ( xContainerLM.is() ) 831 { 832 uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM; 833 834 try { 835 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW ); 836 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM; 837 } catch( uno::Exception& ) 838 {} 839 840 if ( xOwnLM.is() ) 841 { 842 try { 843 uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); 844 if ( xSupp.is() ) 845 xSupp->setActiveFrame( 0 ); 846 847 uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xDocAreaAcc = xOwnLM->getDockingAreaAcceptor(); 848 849 xOwnLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() ); 850 xOwnLM->lock(); 851 xOwnLM->setVisible( sal_False ); 852 853 uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW ); 854 xMerge->removeMergedMenuBar(); 855 856 xContainerLM->setDockingAreaAcceptor( xDocAreaAcc ); 857 xContainerLM->setVisible( sal_True ); 858 xContainerLM->unlock(); 859 860 xContainerLM->doLayout(); 861 bResult = sal_True; 862 } 863 catch( uno::Exception& ) 864 { 865 SetFrameLMVisibility( m_xFrame, sal_True ); 866 } 867 } 868 } 869 870 return bResult; 871 } 872 873 //--------------------------------------------------------------------------- 874 uno::Reference< frame::XFrame > DocumentHolder::GetDocFrame() 875 { 876 // the frame for outplace activation 877 if ( !m_xFrame.is() ) 878 { 879 uno::Reference< lang::XSingleServiceFactory > xFrameFact( 880 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.TaskCreator" ) ), 881 uno::UNO_QUERY_THROW ); 882 883 m_xFrame.set(xFrameFact->createInstanceWithArguments( m_aOutplaceFrameProps ), uno::UNO_QUERY_THROW); 884 885 uno::Reference< frame::XDispatchProviderInterception > xInterception( m_xFrame, uno::UNO_QUERY ); 886 if ( xInterception.is() ) 887 { 888 if ( m_pInterceptor ) 889 { 890 m_pInterceptor->DisconnectDocHolder(); 891 m_pInterceptor->release(); 892 m_pInterceptor = NULL; 893 } 894 895 m_pInterceptor = new Interceptor( this ); 896 m_pInterceptor->acquire(); 897 898 // register interceptor from outside 899 if ( m_xOutplaceInterceptor.is() ) 900 xInterception->registerDispatchProviderInterceptor( m_xOutplaceInterceptor ); 901 902 xInterception->registerDispatchProviderInterceptor( m_pInterceptor ); 903 } 904 905 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY ); 906 if ( xCloseBroadcaster.is() ) 907 xCloseBroadcaster->addCloseListener( ( util::XCloseListener* )this ); 908 } 909 910 if ( m_xComponent.is() ) 911 { 912 uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM; 913 try { 914 uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW ); 915 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM; 916 } catch( uno::Exception& ) 917 {} 918 919 if ( xOwnLM.is() ) 920 xOwnLM->lock(); 921 922 // TODO/LATER: get it for the real aspect 923 awt::Size aSize; 924 GetExtent( embed::Aspects::MSOLE_CONTENT, &aSize ); 925 LoadDocToFrame(sal_False); 926 927 if ( xOwnLM.is() ) 928 { 929 xOwnLM->unlock(); 930 xOwnLM->lock(); 931 } 932 933 SetExtent( embed::Aspects::MSOLE_CONTENT, aSize ); 934 935 if ( xOwnLM.is() ) 936 xOwnLM->unlock(); 937 } 938 939 try 940 { 941 uno::Reference< awt::XWindow > xHWindow = m_xFrame->getContainerWindow(); 942 943 if( xHWindow.is() ) 944 { 945 uno::Reference< beans::XPropertySet > xMonProps( m_xFactory->createInstance(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) ) ), uno::UNO_QUERY_THROW ); 946 const rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "DefaultDisplay" ) ); 947 sal_Int32 nDisplay = 0; 948 xMonProps->getPropertyValue( sPropName ) >>= nDisplay; 949 950 uno::Reference< container::XIndexAccess > xMultiMon( xMonProps, uno::UNO_QUERY_THROW ); 951 uno::Reference< beans::XPropertySet > xMonitor( xMultiMon->getByIndex( nDisplay ), uno::UNO_QUERY_THROW ); 952 awt::Rectangle aWorkRect; 953 xMonitor->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WorkArea" ) ) ) >>= aWorkRect; 954 awt::Rectangle aWindowRect = xHWindow->getPosSize(); 955 956 if (( aWindowRect.Width < aWorkRect.Width) && ( aWindowRect.Height < aWorkRect.Height )) 957 { 958 int OffsetX = ( aWorkRect.Width - aWindowRect.Width ) / 2 + aWorkRect.X; 959 int OffsetY = ( aWorkRect.Height - aWindowRect.Height ) /2 + aWorkRect.Y; 960 xHWindow->setPosSize( OffsetX, OffsetY, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POS ); 961 } 962 else 963 { 964 xHWindow->setPosSize( aWorkRect.X, aWorkRect.Y, aWorkRect.Width, aWorkRect.Height, awt::PosSize::POSSIZE ); 965 } 966 967 xHWindow->setVisible( sal_True ); 968 } 969 } 970 catch ( uno::Exception& ) 971 { 972 } 973 974 return m_xFrame; 975 } 976 977 //--------------------------------------------------------------------------- 978 void DocumentHolder::SetComponent( const uno::Reference< util::XCloseable >& xDoc, sal_Bool bReadOnly ) 979 { 980 if ( m_xComponent.is() ) 981 { 982 // May be should be improved 983 try { 984 CloseDocument( sal_True, sal_False ); 985 } catch( uno::Exception& ) 986 {} 987 } 988 989 m_xComponent = xDoc; 990 // done outside currently uno::Reference < container::XChild > xChild( m_xComponent, uno::UNO_QUERY ); 991 // done outside currently if ( xChild.is() && m_pEmbedObj ) 992 // done outside currently xChild->setParent( m_pEmbedObj->getParent() ); 993 994 m_bReadOnly = bReadOnly; 995 m_bAllowClosing = sal_False; 996 997 uno::Reference< util::XCloseBroadcaster > xBroadcaster( m_xComponent, uno::UNO_QUERY ); 998 if ( xBroadcaster.is() ) 999 xBroadcaster->addCloseListener( ( util::XCloseListener* )this ); 1000 1001 uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY ); 1002 if ( xEventBroadcaster.is() ) 1003 xEventBroadcaster->addEventListener( ( document::XEventListener* )this ); 1004 else 1005 { 1006 // the object does not support document::XEventBroadcaster interface 1007 // use the workaround, register for modified events 1008 uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY ); 1009 if ( xModifyBroadcaster.is() ) 1010 xModifyBroadcaster->addModifyListener( ( util::XModifyListener* )this ); 1011 } 1012 1013 if ( m_xFrame.is() ) 1014 LoadDocToFrame(sal_False); 1015 } 1016 1017 //--------------------------------------------------------------------------- 1018 sal_Bool DocumentHolder::LoadDocToFrame( sal_Bool bInPlace ) 1019 { 1020 if ( m_xFrame.is() && m_xComponent.is() ) 1021 { 1022 uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY ); 1023 if ( xDoc.is() ) 1024 { 1025 // load new document in to the frame 1026 uno::Reference< frame::XComponentLoader > xComponentLoader( m_xFrame, uno::UNO_QUERY_THROW ); 1027 1028 ::comphelper::NamedValueCollection aArgs; 1029 aArgs.put( "Model", m_xComponent ); 1030 aArgs.put( "ReadOnly", m_bReadOnly ); 1031 //aArgs.put( "Hidden", sal_True ); 1032 if ( bInPlace ) 1033 aArgs.put( "PluginMode", sal_Int16(1) ); 1034 ::rtl::OUString sUrl; 1035 uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY); 1036 if ( xServiceInfo.is() 1037 && xServiceInfo->supportsService(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.ReportDefinition"))) ) 1038 { 1039 sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".component:DB/ReportDesign")); 1040 } 1041 else if( xServiceInfo.is() 1042 && xServiceInfo->supportsService( ::rtl::OUString::createFromAscii("com.sun.star.chart2.ChartDocument")) ) 1043 sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/schart")); 1044 else 1045 sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:object")); 1046 1047 xComponentLoader->loadComponentFromURL( sUrl, 1048 rtl::OUString::createFromAscii( "_self" ), 1049 0, 1050 aArgs.getPropertyValues() ); 1051 1052 return sal_True; 1053 } 1054 else 1055 { 1056 uno::Reference < frame::XSynchronousFrameLoader > xLoader( m_xComponent, uno::UNO_QUERY ); 1057 if ( xLoader.is() ) 1058 return xLoader->load( uno::Sequence < beans::PropertyValue >(), m_xFrame ); 1059 else 1060 return sal_False; 1061 } 1062 } 1063 1064 return sal_True; 1065 } 1066 1067 //--------------------------------------------------------------------------- 1068 void DocumentHolder::Show() 1069 { 1070 if( m_xFrame.is() ) 1071 { 1072 m_xFrame->activate(); 1073 uno::Reference<awt::XTopWindow> xTopWindow( m_xFrame->getContainerWindow(), uno::UNO_QUERY ); 1074 if( xTopWindow.is() ) 1075 xTopWindow->toFront(); 1076 } 1077 else 1078 GetDocFrame(); 1079 } 1080 1081 //--------------------------------------------------------------------------- 1082 sal_Bool DocumentHolder::SetExtent( sal_Int64 nAspect, const awt::Size& aSize ) 1083 { 1084 uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY ); 1085 if ( xDocVis.is() ) 1086 { 1087 try 1088 { 1089 xDocVis->setVisualAreaSize( nAspect, aSize ); 1090 return sal_True; 1091 } 1092 catch( uno::Exception& ) 1093 { 1094 // TODO: Error handling 1095 } 1096 } 1097 1098 return sal_False; 1099 } 1100 1101 //--------------------------------------------------------------------------- 1102 sal_Bool DocumentHolder::GetExtent( sal_Int64 nAspect, awt::Size *pSize ) 1103 { 1104 uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY ); 1105 if ( pSize && xDocVis.is() ) 1106 { 1107 try 1108 { 1109 *pSize = xDocVis->getVisualAreaSize( nAspect ); 1110 return sal_True; 1111 } 1112 catch( uno::Exception& ) 1113 { 1114 // TODO: Error handling 1115 } 1116 } 1117 1118 return sal_False; 1119 } 1120 1121 //--------------------------------------------------------------------------- 1122 sal_Int32 DocumentHolder::GetMapUnit( sal_Int64 nAspect ) 1123 { 1124 uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY ); 1125 if ( xDocVis.is() ) 1126 { 1127 try 1128 { 1129 return xDocVis->getMapUnit( nAspect ); 1130 } 1131 catch( uno::Exception& ) 1132 { 1133 // TODO: Error handling 1134 } 1135 } 1136 1137 return 0; 1138 } 1139 1140 //--------------------------------------------------------------------------- 1141 awt::Rectangle DocumentHolder::CalculateBorderedArea( const awt::Rectangle& aRect ) 1142 { 1143 return awt::Rectangle( aRect.X + m_aBorderWidths.Left + HATCH_BORDER_WIDTH, 1144 aRect.Y + m_aBorderWidths.Top + HATCH_BORDER_WIDTH, 1145 aRect.Width - m_aBorderWidths.Left - m_aBorderWidths.Right - 2*HATCH_BORDER_WIDTH, 1146 aRect.Height - m_aBorderWidths.Top - m_aBorderWidths.Bottom - 2*HATCH_BORDER_WIDTH ); 1147 } 1148 1149 //--------------------------------------------------------------------------- 1150 awt::Rectangle DocumentHolder::AddBorderToArea( const awt::Rectangle& aRect ) 1151 { 1152 return awt::Rectangle( aRect.X - m_aBorderWidths.Left - HATCH_BORDER_WIDTH, 1153 aRect.Y - m_aBorderWidths.Top - HATCH_BORDER_WIDTH, 1154 aRect.Width + m_aBorderWidths.Left + m_aBorderWidths.Right + 2*HATCH_BORDER_WIDTH, 1155 aRect.Height + m_aBorderWidths.Top + m_aBorderWidths.Bottom + 2*HATCH_BORDER_WIDTH ); 1156 } 1157 1158 //--------------------------------------------------------------------------- 1159 void SAL_CALL DocumentHolder::disposing( const com::sun::star::lang::EventObject& aSource ) 1160 throw (uno::RuntimeException) 1161 { 1162 if ( m_xComponent.is() && m_xComponent == aSource.Source ) 1163 { 1164 m_xComponent = 0; 1165 if ( m_bWaitForClose ) 1166 { 1167 m_bWaitForClose = sal_False; 1168 FreeOffice(); 1169 } 1170 } 1171 1172 if( m_xFrame.is() && m_xFrame == aSource.Source ) 1173 { 1174 m_xHatchWindow = uno::Reference< awt::XWindow >(); 1175 m_xOwnWindow = uno::Reference< awt::XWindow >(); 1176 m_xFrame = uno::Reference< frame::XFrame >(); 1177 } 1178 } 1179 1180 1181 //--------------------------------------------------------------------------- 1182 void SAL_CALL DocumentHolder::queryClosing( const lang::EventObject& aSource, sal_Bool /*bGetsOwnership*/ ) 1183 throw (util::CloseVetoException, uno::RuntimeException) 1184 { 1185 if ( m_xComponent.is() && m_xComponent == aSource.Source && !m_bAllowClosing ) 1186 throw util::CloseVetoException(); 1187 } 1188 1189 //--------------------------------------------------------------------------- 1190 void SAL_CALL DocumentHolder::notifyClosing( const lang::EventObject& aSource ) 1191 throw (uno::RuntimeException) 1192 { 1193 if ( m_xComponent.is() && m_xComponent == aSource.Source ) 1194 { 1195 m_xComponent = 0; 1196 if ( m_bWaitForClose ) 1197 { 1198 m_bWaitForClose = sal_False; 1199 FreeOffice(); 1200 } 1201 } 1202 1203 if( m_xFrame.is() && m_xFrame == aSource.Source ) 1204 { 1205 m_xHatchWindow = uno::Reference< awt::XWindow >(); 1206 m_xOwnWindow = uno::Reference< awt::XWindow >(); 1207 m_xFrame = uno::Reference< frame::XFrame >(); 1208 } 1209 } 1210 1211 //--------------------------------------------------------------------------- 1212 void SAL_CALL DocumentHolder::queryTermination( const lang::EventObject& ) 1213 throw (frame::TerminationVetoException, uno::RuntimeException) 1214 { 1215 if ( m_bWaitForClose ) 1216 throw frame::TerminationVetoException(); 1217 } 1218 1219 //--------------------------------------------------------------------------- 1220 void SAL_CALL DocumentHolder::notifyTermination( const lang::EventObject& aSource ) 1221 throw (uno::RuntimeException) 1222 { 1223 OSL_ENSURE( !m_xComponent.is(), "Just a disaster..." ); 1224 1225 uno::Reference< frame::XDesktop > xDesktop( aSource.Source, uno::UNO_QUERY ); 1226 m_bDesktopTerminated = sal_True; 1227 if ( xDesktop.is() ) 1228 xDesktop->removeTerminateListener( ( frame::XTerminateListener* )this ); 1229 } 1230 1231 //--------------------------------------------------------------------------- 1232 void SAL_CALL DocumentHolder::modified( const lang::EventObject& aEvent ) 1233 throw ( uno::RuntimeException ) 1234 { 1235 // if the component does not support document::XEventBroadcaster 1236 // the modify notifications are used as workaround, but only for running state 1237 if( aEvent.Source == m_xComponent && m_pEmbedObj && m_pEmbedObj->getCurrentState() == embed::EmbedStates::RUNNING ) 1238 m_pEmbedObj->PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ), aEvent.Source ); 1239 } 1240 1241 //--------------------------------------------------------------------------- 1242 void SAL_CALL DocumentHolder::notifyEvent( const document::EventObject& Event ) 1243 throw ( uno::RuntimeException ) 1244 { 1245 if( m_pEmbedObj && Event.Source == m_xComponent ) 1246 { 1247 // for now the ignored events are not forwarded, but sent by the object itself 1248 if ( !Event.EventName.equalsAscii( "OnSave" ) 1249 && !Event.EventName.equalsAscii( "OnSaveDone" ) 1250 && !Event.EventName.equalsAscii( "OnSaveAs" ) 1251 && !Event.EventName.equalsAscii( "OnSaveAsDone" ) 1252 && !( Event.EventName.equalsAscii( "OnVisAreaChanged" ) && m_nNoResizeReact ) ) 1253 m_pEmbedObj->PostEvent_Impl( Event.EventName, Event.Source ); 1254 } 1255 } 1256 1257 //--------------------------------------------------------------------------- 1258 void SAL_CALL DocumentHolder::borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject, 1259 const frame::BorderWidths& aNewSize ) 1260 throw ( uno::RuntimeException ) 1261 { 1262 // TODO: may require mutex introduction ??? 1263 if ( m_pEmbedObj && m_xFrame.is() && aObject == m_xFrame->getController() ) 1264 { 1265 if ( m_aBorderWidths.Left != aNewSize.Left 1266 || m_aBorderWidths.Right != aNewSize.Right 1267 || m_aBorderWidths.Top != aNewSize.Top 1268 || m_aBorderWidths.Bottom != aNewSize.Bottom ) 1269 { 1270 m_aBorderWidths = aNewSize; 1271 if ( !m_nNoBorderResizeReact ) 1272 PlaceFrame( m_aObjRect ); 1273 } 1274 } 1275 } 1276 1277 //--------------------------------------------------------------------------- 1278 void SAL_CALL DocumentHolder::requestPositioning( const awt::Rectangle& aRect ) 1279 throw (uno::RuntimeException) 1280 { 1281 // TODO: may require mutex introduction ??? 1282 if ( m_pEmbedObj ) 1283 { 1284 // borders should not be counted 1285 awt::Rectangle aObjRect = CalculateBorderedArea( aRect ); 1286 IntCounterGuard aGuard( m_nNoResizeReact ); 1287 m_pEmbedObj->requestPositioning( aObjRect ); 1288 } 1289 } 1290 1291 //--------------------------------------------------------------------------- 1292 awt::Rectangle SAL_CALL DocumentHolder::calcAdjustedRectangle( const awt::Rectangle& aRect ) 1293 throw (uno::RuntimeException) 1294 { 1295 // Solar mutex should be locked already since this is a call from HatchWindow with focus 1296 awt::Rectangle aResult( aRect ); 1297 1298 if ( m_xFrame.is() ) 1299 { 1300 // borders should not be counted 1301 uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY ); 1302 if ( xControllerBorder.is() ) 1303 { 1304 awt::Rectangle aObjRect = CalculateBorderedArea( aRect ); 1305 aObjRect = xControllerBorder->queryBorderedArea( aObjRect ); 1306 aResult = AddBorderToArea( aObjRect ); 1307 } 1308 } 1309 1310 awt::Rectangle aMinRectangle = AddBorderToArea( awt::Rectangle() ); 1311 if ( aResult.Width < aMinRectangle.Width + 2 ) 1312 aResult.Width = aMinRectangle.Width + 2; 1313 if ( aResult.Height < aMinRectangle.Height + 2 ) 1314 aResult.Height = aMinRectangle.Height + 2; 1315 1316 return aResult; 1317 } 1318 1319 void SAL_CALL DocumentHolder::activated( ) throw (::com::sun::star::uno::RuntimeException) 1320 { 1321 if ( (m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) ) 1322 { 1323 if ( m_pEmbedObj->getCurrentState() != embed::EmbedStates::UI_ACTIVE && 1324 !(m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_NOUIACTIVATE) ) 1325 { 1326 try 1327 { 1328 m_pEmbedObj->changeState( embed::EmbedStates::UI_ACTIVE ); 1329 } 1330 catch ( com::sun::star::embed::StateChangeInProgressException& ) 1331 { 1332 // must catch this exception because focus is grabbed while UI activation in doVerb() 1333 } 1334 catch ( com::sun::star::uno::Exception& ) 1335 { 1336 // no outgoing exceptions specified here 1337 } 1338 } 1339 else 1340 { 1341 uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); 1342 if ( xSupp.is() ) 1343 xSupp->setActiveFrame( m_xFrame ); 1344 } 1345 } 1346 } 1347 1348 void DocumentHolder::ResizeHatchWindow() 1349 { 1350 awt::Rectangle aHatchRect = AddBorderToArea( m_aObjRect ); 1351 ResizeWindows_Impl( aHatchRect ); 1352 uno::Reference< embed::XHatchWindow > xHatchWindow( m_xHatchWindow, uno::UNO_QUERY ); 1353 xHatchWindow->setHatchBorderSize( awt::Size( HATCH_BORDER_WIDTH, HATCH_BORDER_WIDTH ) ); 1354 } 1355 1356 void SAL_CALL DocumentHolder::deactivated( ) throw (::com::sun::star::uno::RuntimeException) 1357 { 1358 // deactivation is too unspecific to be useful; usually we only trigger code from activation 1359 // so UIDeactivation is actively triggered by the container 1360 } 1361