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