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:
IntCounterGuard(sal_Int32 & nFlag)99 IntCounterGuard( sal_Int32& nFlag )
100 : m_nFlag( nFlag )
101 {
102 m_nFlag++;
103 }
104
~IntCounterGuard()105 ~IntCounterGuard()
106 {
107 if ( m_nFlag )
108 m_nFlag--;
109 }
110 };
111
112 //===========================================================================
113
InsertMenu_Impl(const uno::Reference<container::XIndexContainer> & xTargetMenu,sal_Int32 nTargetIndex,const uno::Reference<container::XIndexAccess> & xSourceMenu,sal_Int32 nSourceIndex,const::rtl::OUString aContModuleName,const uno::Reference<frame::XDispatchProvider> & xSourceDisp)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 //===========================================================================
DocumentHolder(const uno::Reference<lang::XMultiServiceFactory> & xFactory,OCommonEmbeddedObject * pEmbObj)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 //---------------------------------------------------------------------------
~DocumentHolder()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 //---------------------------------------------------------------------------
CloseFrame()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 //---------------------------------------------------------------------------
FreeOffice()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 //---------------------------------------------------------------------------
CloseDocument(sal_Bool bDeliverOwnership,sal_Bool bWaitForClose)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 //---------------------------------------------------------------------------
PlaceFrame(const awt::Rectangle & aNewRect)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 //---------------------------------------------------------------------------
ResizeWindows_Impl(const awt::Rectangle & aHatchRect)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 //---------------------------------------------------------------------------
SetFrameLMVisibility(const uno::Reference<frame::XFrame> & xFrame,sal_Bool bVisible)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 //---------------------------------------------------------------------------
ShowInplace(const uno::Reference<awt::XWindowPeer> & xParent,const awt::Rectangle & aRectangleToShow,const uno::Reference<frame::XDispatchProvider> & xContDisp)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 //---------------------------------------------------------------------------
RetrieveOwnMenu_Impl()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 //---------------------------------------------------------------------------
FindConnectPoints(const uno::Reference<container::XIndexAccess> & xMenu,sal_Int32 nConnectPoints[2])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 //---------------------------------------------------------------------------
MergeMenuesForInplace(const uno::Reference<container::XIndexAccess> & xContMenu,const uno::Reference<frame::XDispatchProvider> & xContDisp,const::rtl::OUString & aContModuleName,const uno::Reference<container::XIndexAccess> & xOwnMenu,const uno::Reference<frame::XDispatchProvider> & xOwnDisp)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 //---------------------------------------------------------------------------
MergeMenues_Impl(const uno::Reference<::com::sun::star::frame::XLayoutManager> & xOwnLM,const uno::Reference<::com::sun::star::frame::XLayoutManager> & xContLM,const uno::Reference<frame::XDispatchProvider> & xContDisp,const::rtl::OUString & aContModuleName)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
ShowUI(const uno::Reference<::com::sun::star::frame::XLayoutManager> & xContainerLM,const uno::Reference<frame::XDispatchProvider> & xContainerDP,const::rtl::OUString & aContModuleName)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 //---------------------------------------------------------------------------
HideUI(const uno::Reference<::com::sun::star::frame::XLayoutManager> & xContainerLM)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 //---------------------------------------------------------------------------
GetDocFrame()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 //---------------------------------------------------------------------------
SetComponent(const uno::Reference<util::XCloseable> & xDoc,sal_Bool bReadOnly)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 //---------------------------------------------------------------------------
LoadDocToFrame(sal_Bool bInPlace)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 //---------------------------------------------------------------------------
Show()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 //---------------------------------------------------------------------------
SetExtent(sal_Int64 nAspect,const awt::Size & aSize)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 //---------------------------------------------------------------------------
GetExtent(sal_Int64 nAspect,awt::Size * pSize)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 //---------------------------------------------------------------------------
GetMapUnit(sal_Int64 nAspect)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 //---------------------------------------------------------------------------
CalculateBorderedArea(const awt::Rectangle & aRect)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 //---------------------------------------------------------------------------
AddBorderToArea(const awt::Rectangle & aRect)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 //---------------------------------------------------------------------------
disposing(const com::sun::star::lang::EventObject & aSource)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 //---------------------------------------------------------------------------
queryClosing(const lang::EventObject & aSource,sal_Bool)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 //---------------------------------------------------------------------------
notifyClosing(const lang::EventObject & aSource)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 //---------------------------------------------------------------------------
queryTermination(const lang::EventObject &)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 //---------------------------------------------------------------------------
notifyTermination(const lang::EventObject & aSource)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 //---------------------------------------------------------------------------
modified(const lang::EventObject & aEvent)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 //---------------------------------------------------------------------------
notifyEvent(const document::EventObject & Event)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 //---------------------------------------------------------------------------
borderWidthsChanged(const uno::Reference<uno::XInterface> & aObject,const frame::BorderWidths & aNewSize)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 //---------------------------------------------------------------------------
requestPositioning(const awt::Rectangle & aRect)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 //---------------------------------------------------------------------------
calcAdjustedRectangle(const awt::Rectangle & aRect)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
activated()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
ResizeHatchWindow()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
deactivated()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