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