| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_embeddedobj.hxx" |
| #include <com/sun/star/embed/Aspects.hpp> |
| #include <com/sun/star/uno/XComponentContext.hpp> |
| #include <com/sun/star/frame/XComponentLoader.hpp> |
| #include <com/sun/star/frame/XSynchronousFrameLoader.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/XSingleServiceFactory.hpp> |
| #include <com/sun/star/lang/XSingleComponentFactory.hpp> |
| #include <com/sun/star/util/XCloseBroadcaster.hpp> |
| #include <com/sun/star/util/XCloseable.hpp> |
| #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACESS_HPP_ |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #endif |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/frame/XModel.hpp> |
| #include <com/sun/star/frame/XDesktop.hpp> |
| #include <com/sun/star/frame/XFramesSupplier.hpp> |
| #include <com/sun/star/frame/XDispatchHelper.hpp> |
| #include <com/sun/star/frame/FrameSearchFlag.hpp> |
| #include <com/sun/star/frame/XControllerBorder.hpp> |
| #include <com/sun/star/util/XModifyBroadcaster.hpp> |
| #include <com/sun/star/frame/XDispatchProviderInterception.hpp> |
| #include <com/sun/star/awt/XTopWindow.hpp> |
| #include <com/sun/star/awt/PosSize.hpp> |
| #include <com/sun/star/awt/XView.hpp> |
| #include <com/sun/star/awt/WindowAttribute.hpp> |
| #include <com/sun/star/awt/VclWindowPeerAttribute.hpp> |
| #include <com/sun/star/bridge/XBridgeSupplier2.hpp> |
| #include <com/sun/star/bridge/ModelDependent.hpp> |
| #include <com/sun/star/embed/XHatchWindow.hpp> |
| #include <com/sun/star/embed/XHatchWindowFactory.hpp> |
| #include <com/sun/star/embed/XInplaceClient.hpp> |
| #include <com/sun/star/frame/XLayoutManager.hpp> |
| #include <com/sun/star/frame/XMenuBarMergingAcceptor.hpp> |
| #include <com/sun/star/frame/XModuleManager.hpp> |
| #include <com/sun/star/ui/XDockingAreaAcceptor.hpp> |
| #include <com/sun/star/ui/XUIElementSettings.hpp> |
| #ifndef _COM_SUN_STAR_UI_XCONFIGURATIONMANAGER_HPP_ |
| #include <com/sun/star/ui/XUIConfigurationManager.hpp> |
| #endif |
| #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> |
| #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/embed/StateChangeInProgressException.hpp> |
| |
| #include <com/sun/star/embed/EmbedMisc.hpp> |
| #include <com/sun/star/embed/EmbedStates.hpp> |
| #include <osl/diagnose.h> |
| #include <rtl/process.h> |
| |
| #include <comphelper/processfactory.hxx> |
| #include <comphelper/namedvaluecollection.hxx> |
| |
| #include "docholder.hxx" |
| #include "commonembobj.hxx" |
| #include "intercept.hxx" |
| |
| |
| // #include <toolkit/helper/vclunohelper.hxx> |
| // #include <vcl/window.hxx> |
| |
| #define HATCH_BORDER_WIDTH (((m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) && \ |
| m_pEmbedObj->getCurrentState()!=embed::EmbedStates::UI_ACTIVE) ? 0 : 4 ) |
| |
| using namespace ::com::sun::star; |
| |
| //=========================================================================== |
| |
| class IntCounterGuard { |
| sal_Int32& m_nFlag; |
| public: |
| IntCounterGuard( sal_Int32& nFlag ) |
| : m_nFlag( nFlag ) |
| { |
| m_nFlag++; |
| } |
| |
| ~IntCounterGuard() |
| { |
| if ( m_nFlag ) |
| m_nFlag--; |
| } |
| }; |
| |
| //=========================================================================== |
| |
| static void InsertMenu_Impl( const uno::Reference< container::XIndexContainer >& xTargetMenu, |
| sal_Int32 nTargetIndex, |
| const uno::Reference< container::XIndexAccess >& xSourceMenu, |
| sal_Int32 nSourceIndex, |
| const ::rtl::OUString aContModuleName, |
| const uno::Reference< frame::XDispatchProvider >& xSourceDisp ) |
| { |
| sal_Int32 nInd = 0; |
| ::rtl::OUString aModuleIdentPropName( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ) ); |
| ::rtl::OUString aDispProvPropName( RTL_CONSTASCII_USTRINGPARAM( "DispatchProvider" ) ); |
| sal_Bool bModuleNameSet = sal_False; |
| sal_Bool bDispProvSet = sal_False; |
| |
| uno::Sequence< beans::PropertyValue > aSourceProps; |
| xSourceMenu->getByIndex( nSourceIndex ) >>= aSourceProps; |
| uno::Sequence< beans::PropertyValue > aTargetProps( aSourceProps.getLength() ); |
| for ( nInd = 0; nInd < aSourceProps.getLength(); nInd++ ) |
| { |
| aTargetProps[nInd].Name = aSourceProps[nInd].Name; |
| if ( aContModuleName.getLength() && aTargetProps[nInd].Name.equals( aModuleIdentPropName ) ) |
| { |
| aTargetProps[nInd].Value <<= aContModuleName; |
| bModuleNameSet = sal_True; |
| } |
| else if ( aTargetProps[nInd].Name.equals( aDispProvPropName ) ) |
| { |
| aTargetProps[nInd].Value <<= xSourceDisp; |
| bDispProvSet = sal_True; |
| } |
| else |
| aTargetProps[nInd].Value = aSourceProps[nInd].Value; |
| } |
| |
| if ( !bModuleNameSet && aContModuleName.getLength() ) |
| { |
| aTargetProps.realloc( ++nInd ); |
| aTargetProps[nInd-1].Name = aModuleIdentPropName; |
| aTargetProps[nInd-1].Value <<= aContModuleName; |
| } |
| |
| if ( !bDispProvSet && xSourceDisp.is() ) |
| { |
| aTargetProps.realloc( ++nInd ); |
| aTargetProps[nInd-1].Name = aDispProvPropName; |
| aTargetProps[nInd-1].Value <<= xSourceDisp; |
| } |
| |
| xTargetMenu->insertByIndex( nTargetIndex, uno::makeAny( aTargetProps ) ); |
| } |
| |
| //=========================================================================== |
| DocumentHolder::DocumentHolder( const uno::Reference< lang::XMultiServiceFactory >& xFactory, |
| OCommonEmbeddedObject* pEmbObj ) |
| : m_pEmbedObj( pEmbObj ), |
| m_pInterceptor( NULL ), |
| m_xFactory( xFactory ), |
| m_bReadOnly( sal_False ), |
| m_bWaitForClose( sal_False ), |
| m_bAllowClosing( sal_False ), |
| m_bDesktopTerminated( sal_False ), |
| m_nNoBorderResizeReact( 0 ), |
| m_nNoResizeReact( 0 ) |
| { |
| m_aOutplaceFrameProps.realloc( 3 ); |
| beans::NamedValue aArg; |
| |
| aArg.Name = ::rtl::OUString::createFromAscii("TopWindow"); |
| aArg.Value <<= sal_True; |
| m_aOutplaceFrameProps[0] <<= aArg; |
| |
| aArg.Name = ::rtl::OUString::createFromAscii("MakeVisible"); |
| aArg.Value <<= sal_False; |
| m_aOutplaceFrameProps[1] <<= aArg; |
| |
| const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); |
| uno::Reference< frame::XDesktop > xDesktop( m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); |
| if ( xDesktop.is() ) |
| { |
| m_refCount++; |
| try |
| { |
| xDesktop->addTerminateListener( this ); |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| m_refCount--; |
| |
| aArg.Name = ::rtl::OUString::createFromAscii("ParentFrame"); |
| aArg.Value <<= xDesktop; //TODO/LATER: should use parent document frame |
| m_aOutplaceFrameProps[2] <<= aArg; |
| } |
| else |
| m_aOutplaceFrameProps.realloc( 2 ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| DocumentHolder::~DocumentHolder() |
| { |
| m_refCount++; // to allow deregistration as a listener |
| |
| if( m_xFrame.is() ) |
| CloseFrame(); |
| |
| if ( m_xComponent.is() ) |
| { |
| try { |
| CloseDocument( sal_True, sal_False ); |
| } catch( uno::Exception& ) {} |
| } |
| |
| if ( m_pInterceptor ) |
| { |
| m_pInterceptor->DisconnectDocHolder(); |
| m_pInterceptor->release(); |
| } |
| |
| if ( !m_bDesktopTerminated ) |
| FreeOffice(); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::CloseFrame() |
| { |
| uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY ); |
| if ( xCloseBroadcaster.is() ) |
| xCloseBroadcaster->removeCloseListener( ( util::XCloseListener* )this ); |
| |
| uno::Reference<util::XCloseable> xCloseable( |
| m_xFrame,uno::UNO_QUERY ); |
| if( xCloseable.is() ) |
| try { |
| xCloseable->close( sal_True ); |
| } |
| catch( const uno::Exception& ) { |
| } |
| else { |
| uno::Reference<lang::XComponent> xComp( m_xFrame,uno::UNO_QUERY ); |
| if( xComp.is() ) |
| xComp->dispose(); |
| } |
| |
| uno::Reference< lang::XComponent > xComp( m_xHatchWindow, uno::UNO_QUERY ); |
| if ( xComp.is() ) |
| xComp->dispose(); |
| |
| m_xHatchWindow = uno::Reference< awt::XWindow >(); |
| m_xOwnWindow = uno::Reference< awt::XWindow >(); |
| m_xFrame = uno::Reference< frame::XFrame >(); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::FreeOffice() |
| { |
| const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); |
| uno::Reference< frame::XDesktop > xDesktop( m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); |
| if ( xDesktop.is() ) |
| { |
| xDesktop->removeTerminateListener( this ); |
| |
| // the following code is commented out since for now there is still no completely correct way to detect |
| // whether the office can be terminated, so it is better to have unnecessary process running than |
| // to loose any data |
| |
| // uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY ); |
| // if ( xFramesSupplier.is() ) |
| // { |
| // uno::Reference< frame::XFrames > xFrames = xFramesSupplier->getFrames(); |
| // if ( xFrames.is() && !xFrames->hasElements() ) |
| // { |
| // try |
| // { |
| // xDesktop->terminate(); |
| // } |
| // catch( uno::Exception & ) |
| // {} |
| // } |
| // } |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::CloseDocument( sal_Bool bDeliverOwnership, sal_Bool bWaitForClose ) |
| { |
| uno::Reference< util::XCloseBroadcaster > xBroadcaster( m_xComponent, uno::UNO_QUERY ); |
| if ( xBroadcaster.is() ) |
| { |
| uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY ); |
| if ( xEventBroadcaster.is() ) |
| xEventBroadcaster->removeEventListener( ( document::XEventListener* )this ); |
| else |
| { |
| // the object does not support document::XEventBroadcaster interface |
| // use the workaround, register for modified events |
| uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY ); |
| if ( xModifyBroadcaster.is() ) |
| xModifyBroadcaster->removeModifyListener( ( util::XModifyListener* )this ); |
| } |
| |
| uno::Reference< util::XCloseable > xCloseable( xBroadcaster, uno::UNO_QUERY ); |
| if ( xCloseable.is() ) |
| { |
| m_bAllowClosing = sal_True; |
| m_bWaitForClose = bWaitForClose; |
| xCloseable->close( bDeliverOwnership ); |
| } |
| } |
| |
| m_xComponent = 0; |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::PlaceFrame( const awt::Rectangle& aNewRect ) |
| { |
| OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is(), |
| "The object does not have windows required for inplace mode!" ); |
| |
| //TODO: may need mutex locking??? |
| if ( m_xFrame.is() && m_xOwnWindow.is() ) |
| { |
| // the frame can be replaced only in inplace mode |
| frame::BorderWidths aOldWidths; |
| IntCounterGuard aGuard( m_nNoBorderResizeReact ); |
| |
| do |
| { |
| aOldWidths = m_aBorderWidths; |
| |
| awt::Rectangle aHatchRect = AddBorderToArea( aNewRect ); |
| |
| ResizeWindows_Impl( aHatchRect ); |
| |
| } while ( aOldWidths.Left != m_aBorderWidths.Left |
| || aOldWidths.Top != m_aBorderWidths.Top |
| || aOldWidths.Right != m_aBorderWidths.Right |
| || aOldWidths.Bottom != m_aBorderWidths.Bottom ); |
| |
| m_aObjRect = aNewRect; |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::ResizeWindows_Impl( const awt::Rectangle& aHatchRect ) |
| { |
| OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is() /*&& m_xHatchWindow.is()*/, |
| "The object does not have windows required for inplace mode!" ); |
| if ( m_xHatchWindow.is() ) |
| { |
| m_xOwnWindow->setPosSize( HATCH_BORDER_WIDTH, |
| HATCH_BORDER_WIDTH, |
| aHatchRect.Width - 2*HATCH_BORDER_WIDTH, |
| aHatchRect.Height - 2*HATCH_BORDER_WIDTH, |
| awt::PosSize::POSSIZE ); |
| |
| // Window* pWindow = VCLUnoHelper::GetWindow( m_xOwnWindow ); |
| |
| m_xHatchWindow->setPosSize( aHatchRect.X, |
| aHatchRect.Y, |
| aHatchRect.Width, |
| aHatchRect.Height, |
| awt::PosSize::POSSIZE ); |
| } |
| else |
| m_xOwnWindow->setPosSize( aHatchRect.X + HATCH_BORDER_WIDTH, |
| aHatchRect.Y + HATCH_BORDER_WIDTH, |
| aHatchRect.Width - 2*HATCH_BORDER_WIDTH, |
| aHatchRect.Height - 2*HATCH_BORDER_WIDTH, |
| awt::PosSize::POSSIZE ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::SetFrameLMVisibility( const uno::Reference< frame::XFrame >& xFrame, sal_Bool bVisible ) |
| { |
| sal_Bool bResult = sal_False; |
| |
| try |
| { |
| uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; |
| uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY_THROW ); |
| xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager; |
| if ( xLayoutManager.is() ) |
| { |
| xLayoutManager->setVisible( bVisible ); |
| |
| // MBA: locking is done only on the container LM, because it is not about hiding windows, it's about |
| // giving up control over the component window (and stopping to listen for resize events of the container window) |
| if ( bVisible ) |
| xLayoutManager->unlock(); |
| else |
| xLayoutManager->lock(); |
| |
| bResult = sal_True; |
| } |
| } |
| catch( uno::Exception& ) |
| {} |
| |
| return bResult; |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::ShowInplace( const uno::Reference< awt::XWindowPeer >& xParent, |
| const awt::Rectangle& aRectangleToShow, |
| const uno::Reference< frame::XDispatchProvider >& xContDisp ) |
| { |
| OSL_ENSURE( !m_xFrame.is(), "A frame exists already!" ); |
| |
| if ( !m_xFrame.is() ) |
| { |
| uno::Reference < frame::XModel > xModel( GetComponent(), uno::UNO_QUERY ); |
| awt::Rectangle aHatchRectangle = AddBorderToArea( aRectangleToShow ); |
| |
| awt::Rectangle aOwnRectangle( HATCH_BORDER_WIDTH, |
| HATCH_BORDER_WIDTH, |
| aHatchRectangle.Width - 2*HATCH_BORDER_WIDTH, |
| aHatchRectangle.Height - 2*HATCH_BORDER_WIDTH ); |
| uno::Reference< awt::XWindow > xHWindow; |
| uno::Reference< awt::XWindowPeer > xMyParent( xParent ); |
| |
| if ( xModel.is() ) |
| { |
| |
| uno::Reference< embed::XHatchWindowFactory > xHatchFactory( |
| m_xFactory->createInstance( |
| ::rtl::OUString::createFromAscii( "com.sun.star.embed.HatchWindowFactory" ) ), |
| uno::UNO_QUERY ); |
| |
| if ( !xHatchFactory.is() ) |
| throw uno::RuntimeException(); |
| |
| uno::Reference< embed::XHatchWindow > xHatchWindow = |
| xHatchFactory->createHatchWindowInstance( xParent, |
| aHatchRectangle, |
| awt::Size( HATCH_BORDER_WIDTH, HATCH_BORDER_WIDTH ) ); |
| |
| uno::Reference< awt::XWindowPeer > xHatchWinPeer( xHatchWindow, uno::UNO_QUERY ); |
| xHWindow = uno::Reference< awt::XWindow >( xHatchWinPeer, uno::UNO_QUERY ); |
| if ( !xHWindow.is() ) |
| throw uno::RuntimeException(); // TODO: can not create own window |
| |
| xHatchWindow->setController( uno::Reference< embed::XHatchWindowController >( |
| static_cast< embed::XHatchWindowController* >( this ) ) ); |
| |
| xMyParent = xHatchWinPeer; |
| } |
| else |
| { |
| aOwnRectangle.X += aHatchRectangle.X; |
| aOwnRectangle.Y += aHatchRectangle.Y; |
| } |
| |
| awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_TOP, |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("dockingwindow") ), |
| xMyParent, |
| 0, |
| awt::Rectangle(),//aOwnRectangle, |
| awt::WindowAttribute::SHOW | awt::VclWindowPeerAttribute::CLIPCHILDREN ); |
| |
| uno::Reference< awt::XToolkit > xToolkit( |
| m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ), |
| uno::UNO_QUERY ); |
| if ( !xToolkit.is() ) |
| throw uno::RuntimeException(); |
| |
| uno::Reference< awt::XWindowPeer > xNewWinPeer = xToolkit->createWindow( aOwnWinDescriptor ); |
| uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer, uno::UNO_QUERY ); |
| if ( !xOwnWindow.is() ) |
| throw uno::RuntimeException(); // TODO: can not create own window |
| |
| // create a frame based on the specified window |
| uno::Reference< lang::XSingleServiceFactory > xFrameFact( |
| m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.TaskCreator" ) ), |
| uno::UNO_QUERY_THROW ); |
| |
| uno::Sequence< uno::Any > aArgs( 2 ); |
| beans::NamedValue aArg; |
| |
| aArg.Name = ::rtl::OUString::createFromAscii("ContainerWindow"); |
| aArg.Value <<= xOwnWindow; |
| aArgs[0] <<= aArg; |
| |
| uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY ); |
| if ( xContFrame.is() ) |
| { |
| aArg.Name = ::rtl::OUString::createFromAscii("ParentFrame"); |
| aArg.Value <<= xContFrame; |
| aArgs[1] <<= aArg; |
| } |
| else |
| aArgs.realloc( 1 ); |
| |
| // the call will create, initialize the frame, and register it in the parent |
| m_xFrame.set( xFrameFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY_THROW ); |
| |
| m_xHatchWindow = xHWindow; |
| m_xOwnWindow = xOwnWindow; |
| |
| if ( !SetFrameLMVisibility( m_xFrame, sal_False ) ) |
| { |
| OSL_ENSURE( sal_False, "Can't deactivate LayoutManager!\n" ); |
| // TODO/LATER: error handling? |
| } |
| |
| // m_bIsInplace = sal_True; TODO: ? |
| |
| uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY ); |
| if ( xCloseBroadcaster.is() ) |
| xCloseBroadcaster->addCloseListener( ( util::XCloseListener* )this ); |
| |
| // TODO: some listeners to the frame and the window ( resize for example ) |
| } |
| |
| if ( m_xComponent.is() ) |
| { |
| if ( !LoadDocToFrame( sal_True ) ) |
| { |
| CloseFrame(); |
| return sal_False; |
| } |
| |
| uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY ); |
| if ( xControllerBorder.is() ) |
| { |
| m_aBorderWidths = xControllerBorder->getBorder(); |
| xControllerBorder->addBorderResizeListener( (frame::XBorderResizeListener*)this ); |
| } |
| |
| PlaceFrame( aRectangleToShow ); |
| |
| if ( m_xHatchWindow.is() ) |
| m_xHatchWindow->setVisible( sal_True ); |
| |
| return sal_True; |
| } |
| |
| return sal_False; |
| } |
| |
| //--------------------------------------------------------------------------- |
| uno::Reference< container::XIndexAccess > DocumentHolder::RetrieveOwnMenu_Impl() |
| { |
| uno::Reference< container::XIndexAccess > xResult; |
| |
| uno::Reference< ::com::sun::star::ui::XUIConfigurationManagerSupplier > xUIConfSupplier( |
| m_xComponent, |
| uno::UNO_QUERY ); |
| uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > xUIConfigManager; |
| if( xUIConfSupplier.is()) |
| { |
| xUIConfigManager.set( |
| xUIConfSupplier->getUIConfigurationManager(), |
| uno::UNO_QUERY_THROW ); |
| } |
| |
| try |
| { |
| if( xUIConfigManager.is()) |
| { |
| xResult = xUIConfigManager->getSettings( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ), |
| sal_False ); |
| } |
| } |
| catch( uno::Exception ) |
| {} |
| |
| if ( !xResult.is() ) |
| { |
| // no internal document configuration, use the one from the module |
| uno::Reference< ::com::sun::star::frame::XModuleManager > xModuleMan( |
| m_xFactory->createInstance( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ), |
| uno::UNO_QUERY_THROW ); |
| ::rtl::OUString aModuleIdent = |
| xModuleMan->identify( uno::Reference< uno::XInterface >( m_xComponent, uno::UNO_QUERY ) ); |
| |
| if ( aModuleIdent.getLength() ) |
| { |
| uno::Reference< ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier > xModConfSupplier( |
| m_xFactory->createInstance( ::rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ) ) ), |
| uno::UNO_QUERY_THROW ); |
| uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > xModUIConfMan( |
| xModConfSupplier->getUIConfigurationManager( aModuleIdent ), |
| uno::UNO_QUERY_THROW ); |
| xResult = xModUIConfMan->getSettings( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ), |
| sal_False ); |
| } |
| } |
| |
| if ( !xResult.is() ) |
| throw uno::RuntimeException(); |
| |
| return xResult; |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::FindConnectPoints( |
| const uno::Reference< container::XIndexAccess >& xMenu, |
| sal_Int32 nConnectPoints[2] ) |
| throw ( uno::Exception ) |
| { |
| nConnectPoints[0] = -1; |
| nConnectPoints[1] = -1; |
| for ( sal_Int32 nInd = 0; nInd < xMenu->getCount(); nInd++ ) |
| { |
| uno::Sequence< beans::PropertyValue > aProps; |
| xMenu->getByIndex( nInd ) >>= aProps; |
| rtl::OUString aCommand; |
| for ( sal_Int32 nSeqInd = 0; nSeqInd < aProps.getLength(); nSeqInd++ ) |
| if ( aProps[nSeqInd].Name.equalsAscii( "CommandURL" ) ) |
| { |
| aProps[nSeqInd].Value >>= aCommand; |
| break; |
| } |
| |
| if ( !aCommand.getLength() ) |
| throw uno::RuntimeException(); |
| |
| if ( aCommand.equalsAscii( ".uno:PickList" ) ) |
| nConnectPoints[0] = nInd; |
| else if ( aCommand.equalsAscii( ".uno:WindowList" ) ) |
| nConnectPoints[1] = nInd; |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| uno::Reference< container::XIndexAccess > DocumentHolder::MergeMenuesForInplace( |
| const uno::Reference< container::XIndexAccess >& xContMenu, |
| const uno::Reference< frame::XDispatchProvider >& xContDisp, |
| const ::rtl::OUString& aContModuleName, |
| const uno::Reference< container::XIndexAccess >& xOwnMenu, |
| const uno::Reference< frame::XDispatchProvider >& xOwnDisp ) |
| throw ( uno::Exception ) |
| { |
| // TODO/LATER: use dispatch providers on merge |
| |
| sal_Int32 nContPoints[2]; |
| sal_Int32 nOwnPoints[2]; |
| |
| uno::Reference< lang::XSingleComponentFactory > xIndAccessFact( xContMenu, uno::UNO_QUERY_THROW ); |
| |
| uno::Reference< uno::XComponentContext > xComponentContext; |
| |
| uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); |
| if ( xProps.is() ) |
| xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= |
| xComponentContext; |
| |
| uno::Reference< container::XIndexContainer > xMergedMenu( |
| xIndAccessFact->createInstanceWithContext( xComponentContext ), |
| uno::UNO_QUERY_THROW ); |
| |
| FindConnectPoints( xContMenu, nContPoints ); |
| FindConnectPoints( xOwnMenu, nOwnPoints ); |
| |
| for ( sal_Int32 nInd = 0; nInd < xOwnMenu->getCount(); nInd++ ) |
| { |
| if ( nOwnPoints[0] == nInd ) |
| { |
| if ( nContPoints[0] >= 0 && nContPoints[0] < xContMenu->getCount() ) |
| { |
| InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[0], aContModuleName, xContDisp ); |
| } |
| } |
| else if ( nOwnPoints[1] == nInd ) |
| { |
| if ( nContPoints[1] >= 0 && nContPoints[1] < xContMenu->getCount() ) |
| { |
| InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[1], aContModuleName, xContDisp ); |
| } |
| } |
| else |
| InsertMenu_Impl( xMergedMenu, nInd, xOwnMenu, nInd, ::rtl::OUString(), xOwnDisp ); |
| } |
| |
| return uno::Reference< container::XIndexAccess >( xMergedMenu, uno::UNO_QUERY_THROW ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::MergeMenues_Impl( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xOwnLM, |
| const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContLM, |
| const uno::Reference< frame::XDispatchProvider >& xContDisp, |
| const ::rtl::OUString& aContModuleName ) |
| { |
| sal_Bool bMenuMerged = sal_False; |
| try |
| { |
| uno::Reference< ::com::sun::star::ui::XUIElementSettings > xUISettings( |
| xContLM->getElement( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ) ), |
| uno::UNO_QUERY_THROW ); |
| uno::Reference< container::XIndexAccess > xContMenu = xUISettings->getSettings( sal_True ); |
| if ( !xContMenu.is() ) |
| throw uno::RuntimeException(); |
| |
| uno::Reference< container::XIndexAccess > xOwnMenu = RetrieveOwnMenu_Impl(); |
| uno::Reference< frame::XDispatchProvider > xOwnDisp( m_xFrame, uno::UNO_QUERY_THROW ); |
| |
| uno::Reference< container::XIndexAccess > xMergedMenu = MergeMenuesForInplace( xContMenu, xContDisp, aContModuleName, xOwnMenu, xOwnDisp ); |
| uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, |
| uno::UNO_QUERY_THROW ); |
| bMenuMerged = xMerge->setMergedMenuBar( xMergedMenu ); |
| } |
| catch( uno::Exception& ) |
| {} |
| |
| return bMenuMerged; |
| } |
| |
| sal_Bool DocumentHolder::ShowUI( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContainerLM, |
| const uno::Reference< frame::XDispatchProvider >& xContainerDP, |
| const ::rtl::OUString& aContModuleName ) |
| { |
| sal_Bool bResult = sal_False; |
| if ( xContainerLM.is() ) |
| { |
| // the LM of the embedded frame and its current DockingAreaAcceptor |
| uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM; |
| uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xDocAreaAcc; |
| |
| try |
| { |
| uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW ); |
| xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM; |
| xDocAreaAcc = xContainerLM->getDockingAreaAcceptor(); |
| } |
| catch( uno::Exception& ){} |
| |
| // make sure that lock state of LM is correct even if an exception is thrown in between |
| sal_Bool bUnlock = sal_False; |
| sal_Bool bLock = sal_False; |
| if ( xOwnLM.is() && xDocAreaAcc.is() ) |
| { |
| try |
| { |
| // take over the control over the containers window |
| // as long as the LM is invisible and locked an empty tool space will be used on resizing |
| xOwnLM->setDockingAreaAcceptor( xDocAreaAcc ); |
| |
| // try to merge menues; don't do anything else if it fails |
| if ( MergeMenues_Impl( xOwnLM, xContainerLM, xContainerDP, aContModuleName ) ) |
| { |
| // make sure that the container LM does not control the size of the containers window anymore |
| // this must be done after merging menues as we won't get the container menu otherwise |
| xContainerLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() ); |
| |
| // prevent further changes at this LM |
| xContainerLM->setVisible( sal_False ); |
| xContainerLM->lock(); |
| bUnlock = sal_True; |
| |
| // by unlocking the LM each layout change will now resize the containers window; pending layouts will be processed now |
| xOwnLM->setVisible( sal_True ); |
| |
| uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); |
| if ( xSupp.is() ) |
| xSupp->setActiveFrame( m_xFrame ); |
| |
| xOwnLM->unlock(); |
| bLock = sal_True; |
| bResult = sal_True; |
| |
| // TODO/LATER: The following action should be done only if the window is not hidden |
| // otherwise the activation must fail, unfortunatelly currently it is not possible |
| // to detect whether the window is hidden using UNO API |
| m_xOwnWindow->setFocus(); |
| } |
| } |
| catch( uno::Exception& ) |
| { |
| // activation failed; reestablish old state |
| try |
| { |
| uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); |
| if ( xSupp.is() ) |
| xSupp->setActiveFrame( 0 ); |
| |
| // remove control about containers window from own LM |
| if ( bLock ) |
| xOwnLM->lock(); |
| xOwnLM->setVisible( sal_False ); |
| xOwnLM->setDockingAreaAcceptor( uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor >() ); |
| |
| // unmerge menu |
| uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW ); |
| xMerge->removeMergedMenuBar(); |
| } |
| catch( uno::Exception& ) {} |
| |
| try |
| { |
| // reestablish control of containers window |
| xContainerLM->setDockingAreaAcceptor( xDocAreaAcc ); |
| xContainerLM->setVisible( sal_True ); |
| if ( bUnlock ) |
| xContainerLM->unlock(); |
| } |
| catch( uno::Exception& ) {} |
| } |
| } |
| } |
| |
| return bResult; |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::HideUI( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContainerLM ) |
| { |
| sal_Bool bResult = sal_False; |
| |
| if ( xContainerLM.is() ) |
| { |
| uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM; |
| |
| try { |
| uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW ); |
| xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM; |
| } catch( uno::Exception& ) |
| {} |
| |
| if ( xOwnLM.is() ) |
| { |
| try { |
| uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); |
| if ( xSupp.is() ) |
| xSupp->setActiveFrame( 0 ); |
| |
| uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xDocAreaAcc = xOwnLM->getDockingAreaAcceptor(); |
| |
| xOwnLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() ); |
| xOwnLM->lock(); |
| xOwnLM->setVisible( sal_False ); |
| |
| uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW ); |
| xMerge->removeMergedMenuBar(); |
| |
| xContainerLM->setDockingAreaAcceptor( xDocAreaAcc ); |
| xContainerLM->setVisible( sal_True ); |
| xContainerLM->unlock(); |
| |
| xContainerLM->doLayout(); |
| bResult = sal_True; |
| } |
| catch( uno::Exception& ) |
| { |
| SetFrameLMVisibility( m_xFrame, sal_True ); |
| } |
| } |
| } |
| |
| return bResult; |
| } |
| |
| //--------------------------------------------------------------------------- |
| uno::Reference< frame::XFrame > DocumentHolder::GetDocFrame() |
| { |
| // the frame for outplace activation |
| if ( !m_xFrame.is() ) |
| { |
| uno::Reference< lang::XSingleServiceFactory > xFrameFact( |
| m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.TaskCreator" ) ), |
| uno::UNO_QUERY_THROW ); |
| |
| m_xFrame.set(xFrameFact->createInstanceWithArguments( m_aOutplaceFrameProps ), uno::UNO_QUERY_THROW); |
| |
| uno::Reference< frame::XDispatchProviderInterception > xInterception( m_xFrame, uno::UNO_QUERY ); |
| if ( xInterception.is() ) |
| { |
| if ( m_pInterceptor ) |
| { |
| m_pInterceptor->DisconnectDocHolder(); |
| m_pInterceptor->release(); |
| m_pInterceptor = NULL; |
| } |
| |
| m_pInterceptor = new Interceptor( this ); |
| m_pInterceptor->acquire(); |
| |
| // register interceptor from outside |
| if ( m_xOutplaceInterceptor.is() ) |
| xInterception->registerDispatchProviderInterceptor( m_xOutplaceInterceptor ); |
| |
| xInterception->registerDispatchProviderInterceptor( m_pInterceptor ); |
| } |
| |
| uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY ); |
| if ( xCloseBroadcaster.is() ) |
| xCloseBroadcaster->addCloseListener( ( util::XCloseListener* )this ); |
| } |
| |
| if ( m_xComponent.is() ) |
| { |
| uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM; |
| try { |
| uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW ); |
| xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM; |
| } catch( uno::Exception& ) |
| {} |
| |
| if ( xOwnLM.is() ) |
| xOwnLM->lock(); |
| |
| // TODO/LATER: get it for the real aspect |
| awt::Size aSize; |
| GetExtent( embed::Aspects::MSOLE_CONTENT, &aSize ); |
| LoadDocToFrame(sal_False); |
| |
| if ( xOwnLM.is() ) |
| { |
| xOwnLM->unlock(); |
| xOwnLM->lock(); |
| } |
| |
| SetExtent( embed::Aspects::MSOLE_CONTENT, aSize ); |
| |
| if ( xOwnLM.is() ) |
| xOwnLM->unlock(); |
| } |
| |
| try |
| { |
| uno::Reference< awt::XWindow > xHWindow = m_xFrame->getContainerWindow(); |
| |
| if( xHWindow.is() ) |
| { |
| uno::Reference< beans::XPropertySet > xMonProps( m_xFactory->createInstance(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) ) ), uno::UNO_QUERY_THROW ); |
| const rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "DefaultDisplay" ) ); |
| sal_Int32 nDisplay = 0; |
| xMonProps->getPropertyValue( sPropName ) >>= nDisplay; |
| |
| uno::Reference< container::XIndexAccess > xMultiMon( xMonProps, uno::UNO_QUERY_THROW ); |
| uno::Reference< beans::XPropertySet > xMonitor( xMultiMon->getByIndex( nDisplay ), uno::UNO_QUERY_THROW ); |
| awt::Rectangle aWorkRect; |
| xMonitor->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WorkArea" ) ) ) >>= aWorkRect; |
| awt::Rectangle aWindowRect = xHWindow->getPosSize(); |
| |
| if (( aWindowRect.Width < aWorkRect.Width) && ( aWindowRect.Height < aWorkRect.Height )) |
| { |
| int OffsetX = ( aWorkRect.Width - aWindowRect.Width ) / 2 + aWorkRect.X; |
| int OffsetY = ( aWorkRect.Height - aWindowRect.Height ) /2 + aWorkRect.Y; |
| xHWindow->setPosSize( OffsetX, OffsetY, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POS ); |
| } |
| else |
| { |
| xHWindow->setPosSize( aWorkRect.X, aWorkRect.Y, aWorkRect.Width, aWorkRect.Height, awt::PosSize::POSSIZE ); |
| } |
| |
| xHWindow->setVisible( sal_True ); |
| } |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| |
| return m_xFrame; |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::SetComponent( const uno::Reference< util::XCloseable >& xDoc, sal_Bool bReadOnly ) |
| { |
| if ( m_xComponent.is() ) |
| { |
| // May be should be improved |
| try { |
| CloseDocument( sal_True, sal_False ); |
| } catch( uno::Exception& ) |
| {} |
| } |
| |
| m_xComponent = xDoc; |
| // done outside currently uno::Reference < container::XChild > xChild( m_xComponent, uno::UNO_QUERY ); |
| // done outside currently if ( xChild.is() && m_pEmbedObj ) |
| // done outside currently xChild->setParent( m_pEmbedObj->getParent() ); |
| |
| m_bReadOnly = bReadOnly; |
| m_bAllowClosing = sal_False; |
| |
| uno::Reference< util::XCloseBroadcaster > xBroadcaster( m_xComponent, uno::UNO_QUERY ); |
| if ( xBroadcaster.is() ) |
| xBroadcaster->addCloseListener( ( util::XCloseListener* )this ); |
| |
| uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY ); |
| if ( xEventBroadcaster.is() ) |
| xEventBroadcaster->addEventListener( ( document::XEventListener* )this ); |
| else |
| { |
| // the object does not support document::XEventBroadcaster interface |
| // use the workaround, register for modified events |
| uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY ); |
| if ( xModifyBroadcaster.is() ) |
| xModifyBroadcaster->addModifyListener( ( util::XModifyListener* )this ); |
| } |
| |
| if ( m_xFrame.is() ) |
| LoadDocToFrame(sal_False); |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::LoadDocToFrame( sal_Bool bInPlace ) |
| { |
| if ( m_xFrame.is() && m_xComponent.is() ) |
| { |
| uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY ); |
| if ( xDoc.is() ) |
| { |
| // load new document in to the frame |
| uno::Reference< frame::XComponentLoader > xComponentLoader( m_xFrame, uno::UNO_QUERY_THROW ); |
| |
| ::comphelper::NamedValueCollection aArgs; |
| aArgs.put( "Model", m_xComponent ); |
| aArgs.put( "ReadOnly", m_bReadOnly ); |
| //aArgs.put( "Hidden", sal_True ); |
| if ( bInPlace ) |
| aArgs.put( "PluginMode", sal_Int16(1) ); |
| ::rtl::OUString sUrl; |
| uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY); |
| if ( xServiceInfo.is() |
| && xServiceInfo->supportsService(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.ReportDefinition"))) ) |
| { |
| sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".component:DB/ReportDesign")); |
| } |
| else if( xServiceInfo.is() |
| && xServiceInfo->supportsService( ::rtl::OUString::createFromAscii("com.sun.star.chart2.ChartDocument")) ) |
| sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/schart")); |
| else |
| sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:object")); |
| |
| xComponentLoader->loadComponentFromURL( sUrl, |
| rtl::OUString::createFromAscii( "_self" ), |
| 0, |
| aArgs.getPropertyValues() ); |
| |
| return sal_True; |
| } |
| else |
| { |
| uno::Reference < frame::XSynchronousFrameLoader > xLoader( m_xComponent, uno::UNO_QUERY ); |
| if ( xLoader.is() ) |
| return xLoader->load( uno::Sequence < beans::PropertyValue >(), m_xFrame ); |
| else |
| return sal_False; |
| } |
| } |
| |
| return sal_True; |
| } |
| |
| //--------------------------------------------------------------------------- |
| void DocumentHolder::Show() |
| { |
| if( m_xFrame.is() ) |
| { |
| m_xFrame->activate(); |
| uno::Reference<awt::XTopWindow> xTopWindow( m_xFrame->getContainerWindow(), uno::UNO_QUERY ); |
| if( xTopWindow.is() ) |
| xTopWindow->toFront(); |
| } |
| else |
| GetDocFrame(); |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::SetExtent( sal_Int64 nAspect, const awt::Size& aSize ) |
| { |
| uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY ); |
| if ( xDocVis.is() ) |
| { |
| try |
| { |
| xDocVis->setVisualAreaSize( nAspect, aSize ); |
| return sal_True; |
| } |
| catch( uno::Exception& ) |
| { |
| // TODO: Error handling |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Bool DocumentHolder::GetExtent( sal_Int64 nAspect, awt::Size *pSize ) |
| { |
| uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY ); |
| if ( pSize && xDocVis.is() ) |
| { |
| try |
| { |
| *pSize = xDocVis->getVisualAreaSize( nAspect ); |
| return sal_True; |
| } |
| catch( uno::Exception& ) |
| { |
| // TODO: Error handling |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| //--------------------------------------------------------------------------- |
| sal_Int32 DocumentHolder::GetMapUnit( sal_Int64 nAspect ) |
| { |
| uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY ); |
| if ( xDocVis.is() ) |
| { |
| try |
| { |
| return xDocVis->getMapUnit( nAspect ); |
| } |
| catch( uno::Exception& ) |
| { |
| // TODO: Error handling |
| } |
| } |
| |
| return 0; |
| } |
| |
| //--------------------------------------------------------------------------- |
| awt::Rectangle DocumentHolder::CalculateBorderedArea( const awt::Rectangle& aRect ) |
| { |
| return awt::Rectangle( aRect.X + m_aBorderWidths.Left + HATCH_BORDER_WIDTH, |
| aRect.Y + m_aBorderWidths.Top + HATCH_BORDER_WIDTH, |
| aRect.Width - m_aBorderWidths.Left - m_aBorderWidths.Right - 2*HATCH_BORDER_WIDTH, |
| aRect.Height - m_aBorderWidths.Top - m_aBorderWidths.Bottom - 2*HATCH_BORDER_WIDTH ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| awt::Rectangle DocumentHolder::AddBorderToArea( const awt::Rectangle& aRect ) |
| { |
| return awt::Rectangle( aRect.X - m_aBorderWidths.Left - HATCH_BORDER_WIDTH, |
| aRect.Y - m_aBorderWidths.Top - HATCH_BORDER_WIDTH, |
| aRect.Width + m_aBorderWidths.Left + m_aBorderWidths.Right + 2*HATCH_BORDER_WIDTH, |
| aRect.Height + m_aBorderWidths.Top + m_aBorderWidths.Bottom + 2*HATCH_BORDER_WIDTH ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::disposing( const com::sun::star::lang::EventObject& aSource ) |
| throw (uno::RuntimeException) |
| { |
| if ( m_xComponent.is() && m_xComponent == aSource.Source ) |
| { |
| m_xComponent = 0; |
| if ( m_bWaitForClose ) |
| { |
| m_bWaitForClose = sal_False; |
| FreeOffice(); |
| } |
| } |
| |
| if( m_xFrame.is() && m_xFrame == aSource.Source ) |
| { |
| m_xHatchWindow = uno::Reference< awt::XWindow >(); |
| m_xOwnWindow = uno::Reference< awt::XWindow >(); |
| m_xFrame = uno::Reference< frame::XFrame >(); |
| } |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::queryClosing( const lang::EventObject& aSource, sal_Bool /*bGetsOwnership*/ ) |
| throw (util::CloseVetoException, uno::RuntimeException) |
| { |
| if ( m_xComponent.is() && m_xComponent == aSource.Source && !m_bAllowClosing ) |
| throw util::CloseVetoException(); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::notifyClosing( const lang::EventObject& aSource ) |
| throw (uno::RuntimeException) |
| { |
| if ( m_xComponent.is() && m_xComponent == aSource.Source ) |
| { |
| m_xComponent = 0; |
| if ( m_bWaitForClose ) |
| { |
| m_bWaitForClose = sal_False; |
| FreeOffice(); |
| } |
| } |
| |
| if( m_xFrame.is() && m_xFrame == aSource.Source ) |
| { |
| m_xHatchWindow = uno::Reference< awt::XWindow >(); |
| m_xOwnWindow = uno::Reference< awt::XWindow >(); |
| m_xFrame = uno::Reference< frame::XFrame >(); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::queryTermination( const lang::EventObject& ) |
| throw (frame::TerminationVetoException, uno::RuntimeException) |
| { |
| if ( m_bWaitForClose ) |
| throw frame::TerminationVetoException(); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::notifyTermination( const lang::EventObject& aSource ) |
| throw (uno::RuntimeException) |
| { |
| OSL_ENSURE( !m_xComponent.is(), "Just a disaster..." ); |
| |
| uno::Reference< frame::XDesktop > xDesktop( aSource.Source, uno::UNO_QUERY ); |
| m_bDesktopTerminated = sal_True; |
| if ( xDesktop.is() ) |
| xDesktop->removeTerminateListener( ( frame::XTerminateListener* )this ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::modified( const lang::EventObject& aEvent ) |
| throw ( uno::RuntimeException ) |
| { |
| // if the component does not support document::XEventBroadcaster |
| // the modify notifications are used as workaround, but only for running state |
| if( aEvent.Source == m_xComponent && m_pEmbedObj && m_pEmbedObj->getCurrentState() == embed::EmbedStates::RUNNING ) |
| m_pEmbedObj->PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ), aEvent.Source ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::notifyEvent( const document::EventObject& Event ) |
| throw ( uno::RuntimeException ) |
| { |
| if( m_pEmbedObj && Event.Source == m_xComponent ) |
| { |
| // for now the ignored events are not forwarded, but sent by the object itself |
| if ( !Event.EventName.equalsAscii( "OnSave" ) |
| && !Event.EventName.equalsAscii( "OnSaveDone" ) |
| && !Event.EventName.equalsAscii( "OnSaveAs" ) |
| && !Event.EventName.equalsAscii( "OnSaveAsDone" ) |
| && !( Event.EventName.equalsAscii( "OnVisAreaChanged" ) && m_nNoResizeReact ) ) |
| m_pEmbedObj->PostEvent_Impl( Event.EventName, Event.Source ); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject, |
| const frame::BorderWidths& aNewSize ) |
| throw ( uno::RuntimeException ) |
| { |
| // TODO: may require mutex introduction ??? |
| if ( m_pEmbedObj && m_xFrame.is() && aObject == m_xFrame->getController() ) |
| { |
| if ( m_aBorderWidths.Left != aNewSize.Left |
| || m_aBorderWidths.Right != aNewSize.Right |
| || m_aBorderWidths.Top != aNewSize.Top |
| || m_aBorderWidths.Bottom != aNewSize.Bottom ) |
| { |
| m_aBorderWidths = aNewSize; |
| if ( !m_nNoBorderResizeReact ) |
| PlaceFrame( m_aObjRect ); |
| } |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| void SAL_CALL DocumentHolder::requestPositioning( const awt::Rectangle& aRect ) |
| throw (uno::RuntimeException) |
| { |
| // TODO: may require mutex introduction ??? |
| if ( m_pEmbedObj ) |
| { |
| // borders should not be counted |
| awt::Rectangle aObjRect = CalculateBorderedArea( aRect ); |
| IntCounterGuard aGuard( m_nNoResizeReact ); |
| m_pEmbedObj->requestPositioning( aObjRect ); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| awt::Rectangle SAL_CALL DocumentHolder::calcAdjustedRectangle( const awt::Rectangle& aRect ) |
| throw (uno::RuntimeException) |
| { |
| // Solar mutex should be locked already since this is a call from HatchWindow with focus |
| awt::Rectangle aResult( aRect ); |
| |
| if ( m_xFrame.is() ) |
| { |
| // borders should not be counted |
| uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY ); |
| if ( xControllerBorder.is() ) |
| { |
| awt::Rectangle aObjRect = CalculateBorderedArea( aRect ); |
| aObjRect = xControllerBorder->queryBorderedArea( aObjRect ); |
| aResult = AddBorderToArea( aObjRect ); |
| } |
| } |
| |
| awt::Rectangle aMinRectangle = AddBorderToArea( awt::Rectangle() ); |
| if ( aResult.Width < aMinRectangle.Width + 2 ) |
| aResult.Width = aMinRectangle.Width + 2; |
| if ( aResult.Height < aMinRectangle.Height + 2 ) |
| aResult.Height = aMinRectangle.Height + 2; |
| |
| return aResult; |
| } |
| |
| void SAL_CALL DocumentHolder::activated( ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| if ( (m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) ) |
| { |
| if ( m_pEmbedObj->getCurrentState() != embed::EmbedStates::UI_ACTIVE && |
| !(m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_NOUIACTIVATE) ) |
| { |
| try |
| { |
| m_pEmbedObj->changeState( embed::EmbedStates::UI_ACTIVE ); |
| } |
| catch ( com::sun::star::embed::StateChangeInProgressException& ) |
| { |
| // must catch this exception because focus is grabbed while UI activation in doVerb() |
| } |
| catch ( com::sun::star::uno::Exception& ) |
| { |
| // no outgoing exceptions specified here |
| } |
| } |
| else |
| { |
| uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY ); |
| if ( xSupp.is() ) |
| xSupp->setActiveFrame( m_xFrame ); |
| } |
| } |
| } |
| |
| void DocumentHolder::ResizeHatchWindow() |
| { |
| awt::Rectangle aHatchRect = AddBorderToArea( m_aObjRect ); |
| ResizeWindows_Impl( aHatchRect ); |
| uno::Reference< embed::XHatchWindow > xHatchWindow( m_xHatchWindow, uno::UNO_QUERY ); |
| xHatchWindow->setHatchBorderSize( awt::Size( HATCH_BORDER_WIDTH, HATCH_BORDER_WIDTH ) ); |
| } |
| |
| void SAL_CALL DocumentHolder::deactivated( ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| // deactivation is too unspecific to be useful; usually we only trigger code from activation |
| // so UIDeactivation is actively triggered by the container |
| } |