xref: /trunk/main/embeddedobj/source/general/docholder.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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