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