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