1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma warning(disable : 4917 4555)
25 #include "docholder.hxx"
26 #include "embeddoc.hxx"
27 #include "intercept.hxx"
28 #include "syswinwrapper.hxx"
29 #include "iipaobj.hxx"
33 #include <com/sun/star/awt/XTopWindow.hpp>
34 #include <com/sun/star/awt/PosSize.hpp>
35 #include <com/sun/star/awt/XView.hpp>
36 #include <com/sun/star/awt/Toolkit.hpp>
37 #include <com/sun/star/awt/XSystemChildFactory.hpp>
38 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
39 #include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
40 #include <com/sun/star/awt/WindowAttribute.hpp>
41 #include <com/sun/star/awt/XWindow.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/bridge/XBridgeSupplier2.hpp>
44 #include <com/sun/star/bridge/ModelDependent.hpp>
45 #include <com/sun/star/container/XNameAccess.hpp>
46 #include <com/sun/star/document/MacroExecMode.hpp>
47 #include <com/sun/star/embed/EmbedMapUnits.hpp>
48 #include <com/sun/star/embed/XVisualObject.hpp>
49 #include <com/sun/star/frame/XComponentLoader.hpp>
50 #include <com/sun/star/frame/Frame.hpp>
51 #include <com/sun/star/frame/XModel.hpp>
52 #include <com/sun/star/frame/Desktop.hpp>
53 #include <com/sun/star/frame/XFramesSupplier.hpp>
54 #include <com/sun/star/frame/FrameSearchFlag.hpp>
55 #include <com/sun/star/frame/XStatusListener.hpp>
56 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
57 #include <com/sun/star/lang/SystemDependent.hpp>
58 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
59 #include <com/sun/star/task/InteractionHandler.hpp>
60 #include <com/sun/star/ui/XUIElement.hpp>
61 #include <com/sun/star/util/XCloseBroadcaster.hpp>
62 #include <com/sun/star/util/XCloseAble.hpp>
63 #include <com/sun/star/util/XModifyBroadcaster.hpp>
64 #include <comphelper/processfactory.hxx>
65 #include <osl/diagnose.h>
66 #include <rtl/process.h>
68 using namespace ::com::sun::star
;
70 extern OUString
getFilterNameFromGUID_Impl( GUID
* );
72 // add mutex locking ???
74 DocumentHolder::DocumentHolder(
75 const uno::Reference
<lang::XMultiServiceFactory
>& xFactory
,
76 const ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
>& xOleAccess
)
78 m_bAllowInPlace(true),
83 m_xOleAccess( xOleAccess
),
85 m_xFactory( xFactory
),
86 m_bOnDeactivate(false),
87 m_hWndxWinParent(NULL
),
92 m_nMacroExecMode( document::MacroExecMode::USE_CONFIG
),
95 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
96 xDesktop
->addTerminateListener( (frame::XTerminateListener
*)this );
100 DocumentHolder::~DocumentHolder()
104 ClearInterceptorInternally();
108 void DocumentHolder::LoadDocInFrame( sal_Bool bPluginMode
)
110 uno::Reference
<frame::XComponentLoader
> xComponentLoader(
111 m_xFrame
,uno::UNO_QUERY
);
112 if( xComponentLoader
.is() && m_xDocument
.is() )
114 uno::Reference
< task::XInteractionHandler2
> xHandler(
115 task::InteractionHandler::createWithParent(comphelper::getComponentContext(m_xFactory
), 0) );
119 uno::Sequence
<beans::PropertyValue
> aSeq( nLen
);
121 aAny
<<= uno::Reference
<uno::XInterface
>(
122 m_xDocument
, uno::UNO_QUERY
);
123 aSeq
[0] = beans::PropertyValue(
127 beans::PropertyState_DIRECT_VALUE
);
130 aSeq
[1] = beans::PropertyValue(
131 OUString("ReadOnly"),
134 beans::PropertyState_DIRECT_VALUE
);
136 aAny
<<= (sal_Bool
) sal_True
;
137 aSeq
[2] = beans::PropertyValue(
138 OUString("NoAutoSave"),
141 beans::PropertyState_DIRECT_VALUE
);
145 aSeq
.realloc( ++nLen
);
146 aAny
<<= (sal_Int16
) 3;
147 aSeq
[nLen
-1] = beans::PropertyValue(
148 OUString("PluginMode"),
151 beans::PropertyState_DIRECT_VALUE
);
154 aSeq
.realloc( nLen
+=2 );
156 aSeq
[nLen
-2] = beans::PropertyValue(
157 OUString("InteractionHandler"),
160 beans::PropertyState_DIRECT_VALUE
);
162 aAny
<<= m_nMacroExecMode
;
163 aSeq
[nLen
-1] = beans::PropertyValue(
164 OUString("MacroExecutionMode"),
167 beans::PropertyState_DIRECT_VALUE
);
169 xComponentLoader
->loadComponentFromURL(
170 OUString("private:object"),
175 uno::Sequence
< beans::PropertyValue
> aResArgs
= m_xDocument
->getArgs();
176 for ( int nInd
= 0; nInd
< aResArgs
.getLength(); nInd
++ )
177 if ( aResArgs
[nInd
].Name
== "MacroExecutionMode" )
179 aResArgs
[nInd
].Value
>>= m_nMacroExecMode
;
185 void DocumentHolder::OnPosRectChanged(LPRECT lpRect
) const
187 lpRect
->left
+= m_aBorder
.left
;
188 lpRect
->right
-= m_aBorder
.right
;
189 lpRect
->top
+= m_aBorder
.top
;
190 lpRect
->bottom
-= m_aBorder
.bottom
;
192 m_pIOleIPSite
->OnPosRectChange(lpRect
);
197 void DocumentHolder::DisableInplaceActivation(BOOL b
)
199 m_bAllowInPlace
= ! b
;
202 BOOL
DocumentHolder::isActive() const
204 return m_pIOleIPSite
!= 0;
207 HRESULT
DocumentHolder::InPlaceActivate(
208 LPOLECLIENTSITE pActiveSite
,
211 m_bOnDeactivate
= false;
220 OLEINPLACEFRAMEINFO frameInfo
;
222 if (NULL
==pActiveSite
)
223 return ResultFromScode(E_INVALIDARG
);
225 if (NULL
!=m_pIOleIPSite
)
233 if ( !m_xDocument
.is() )
236 //1. Initialization, obtaining interfaces, OnInPlaceActivate.
237 hr
=pActiveSite
->QueryInterface(
239 (void**) &m_pIOleIPSite
);
244 hr
=m_pIOleIPSite
->CanInPlaceActivate();
248 m_pIOleIPSite
->Release(), m_pIOleIPSite
=NULL
;
249 return ResultFromScode(E_FAIL
);
252 m_pIOleIPSite
->OnInPlaceActivate();
254 //2. Get the site window
255 //3. and determine container frame and
256 // document window for tools and menus, as well
257 // as frameInfo for accelerators
258 m_pIOleIPSite
->GetWindow(&hWndSite
);
260 frameInfo
.cb
=sizeof(OLEINPLACEFRAMEINFO
);
261 m_pIOleIPSite
->GetWindowContext(
262 &m_pIOleIPFrame
,&m_pIOleIPUIWindow
,&rcPos
,&rcClip
,&frameInfo
);
264 // initialize the office as, with hwnd as parentwindow
266 uno::Sequence
<sal_Int8
> aProcessIdent(16);
267 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
271 if(!m_xEditWindow
.is())
272 { // determine XWindow and window handle of parent
273 HWND
hWndxWinParent(0);
274 uno::Reference
<awt::XWindow
> xWin
;
276 uno::Reference
<awt::XToolkit2
> xToolkit
=
277 awt::Toolkit::create(comphelper::getComponentContext(m_xFactory
));
279 // create system window wrapper for hwnd
281 m_pCHatchWin
= new winwrap::CHatchWin(
284 if(m_pCHatchWin
->Init(hWndSite
,/*ID_HATCHWINDOW*/2000, NULL
)) {
285 m_pCHatchWin
->RectsSet(&rcPos
,&rcClip
); //set visible area
286 hWndxWinParent
= m_pCHatchWin
->Window();
287 ShowWindow(hWndxWinParent
,SW_SHOW
); //Make visible.
290 // no success initializing hatch window
291 delete m_pCHatchWin
, m_pCHatchWin
= 0;
292 hWndxWinParent
= hWndSite
;
295 aAny
<<= sal_Int32(hWndxWinParent
);
296 xWin
= uno::Reference
<awt::XWindow
>(
297 xToolkit
->createSystemChild(
300 lang::SystemDependent::SYSTEM_WIN32
),
305 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
306 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
307 rcPos
.right
-rcPos
.left
,
308 rcPos
.bottom
- rcPos
.top
,
309 awt::PosSize::POSSIZE
);
310 xWin
->setVisible(sal_True
);
312 m_xEditWindow
= xWin
;
313 m_hWndxWinParent
= hWndxWinParent
;
319 if(m_hWndxWinParent
) {
320 SetParent(m_hWndxWinParent
,hWndSite
);
321 ShowWindow(m_hWndxWinParent
,SW_SHOW
); //Make visible.
324 if ( !m_xFrame
.is() )
325 // initially set size to "empty", this guarantees that the final resize
326 // is always executed (will be done by "SetObjectRects" after getting internal border)
327 m_xEditWindow
->setPosSize(
332 awt::PosSize::POSSIZE
);
333 m_xEditWindow
->setVisible(sal_True
);
336 if(m_xContainerWindow
.is()) {
340 m_pIOleIPFrame
->GetWindow(&hWndCont
);
341 SetParent(m_hWndxWinCont
,hWndCont
);
342 ShowWindow(m_hWndxWinCont
,SW_SHOW
);
345 m_xContainerWindow
->setVisible(true);
349 m_xFrame
->activate();
351 // create frame and initialize it with with the created window
352 m_xFrame
= frame::Frame::create( comphelper::getComponentContext(m_xFactory
) );
353 m_xFrame
->initialize(m_xEditWindow
);
355 m_xFrame
->registerDispatchProviderInterceptor( CreateNewInterceptor() );
357 m_xLayoutManager
.set( m_xFrame
->getLayoutManager(), uno::UNO_QUERY
);
359 if(m_xLayoutManager
.is())
360 m_xLayoutManager
->setDockingAreaAcceptor(this);
362 // load the model into the frame
363 LoadDocInFrame( sal_True
);
365 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
366 xDesktop
->getFrames()->append( uno::Reference
<frame::XFrame
>(m_xFrame
, uno::UNO_QUERY_THROW
) );
368 // determine the menuhandle to get menutitems.
369 if(m_xLayoutManager
.is()) {
370 uno::Reference
< ::com::sun::star::ui::XUIElement
> xUIEl(
371 m_xLayoutManager
->getElement(
373 "private:resource/menubar/menubar")));
374 OSL_ENSURE(xUIEl
.is(),"no menubar");
375 uno::Reference
<awt::XSystemDependentMenuPeer
> xSDMP(
376 xUIEl
->getRealInterface(),
378 aAny
= xSDMP
->getMenuHandle(
379 aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
382 m_nMenuHandle
= HMENU(tmp
);
383 m_xLayoutManager
->hideElement(
385 "private:resource/menubar/menubar" ));
389 // TODO/cd: Workaround for status indicator bug. It always makes the
390 // document window visible, when someone tries to use the status
391 // indicator. As we save our document when we get the deactivation
392 // from OLE this conflict to hide floating windows.
393 if(m_xLayoutManager
.is())
394 m_xLayoutManager
->setVisible(true);
396 // get document border and resize rects according to border
397 GetDocumentBorder( &m_aBorder
);
398 SetObjectRects( &rcPos
, &rcClip
);
400 if ( m_xOleAccess
.is() )
402 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
403 if ( aDocLock
.GetEmbedDocument() )
404 aDocLock
.GetEmbedDocument()->ShowObject();
407 // setTitle(m_aDocumentNamePart);
411 m_pIOleIPSite
->DiscardUndoState();
413 catch( const uno::Exception
& )
422 void DocumentHolder::InPlaceDeactivate(void)
424 m_bOnDeactivate
= true;
427 if(m_xFrame
.is()) m_xFrame
->deactivate();
429 if(m_xEditWindow
.is()) {
430 m_xEditWindow
->setVisible(false);
431 ShowWindow(m_hWndxWinParent
,SW_HIDE
);
432 SetParent(m_hWndxWinParent
,0);
435 if(m_xContainerWindow
.is()) {
436 m_xContainerWindow
->setVisible(false);
437 ShowWindow(m_hWndxWinCont
,SW_HIDE
);
438 SetParent(m_hWndxWinCont
,0);
441 // TODO/cd: Workaround for status indicator bug. It always makes the
442 // document window visible, when someone tries to use the status
443 // indicator. As we save our document when we get the deactivation
444 // from OLE this conflict to hide floating windows.
445 if (m_xLayoutManager
.is())
446 m_xLayoutManager
->setVisible(false);
448 if (NULL
!=m_pIOleIPSite
)
449 m_pIOleIPSite
->OnInPlaceDeactivate();
451 if(m_pIOleIPFrame
) m_pIOleIPFrame
->Release(); m_pIOleIPFrame
= 0;
452 if(m_pIOleIPUIWindow
) m_pIOleIPUIWindow
->Release(); m_pIOleIPUIWindow
= 0;
453 if(m_pIOleIPSite
) m_pIOleIPSite
->Release(); m_pIOleIPSite
= 0;
455 if ( m_xOleAccess
.is() )
457 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
458 if ( aDocLock
.GetEmbedDocument() )
460 aDocLock
.GetEmbedDocument()->SaveObject();
468 HRESULT
DocumentHolder::UIActivate()
470 // 1. Call IOleInPlaceSite::UIActivate
471 if (NULL
!=m_pIOleIPSite
)
472 m_pIOleIPSite
->OnUIActivate();
474 //2. Critical for accelerators to work initially.
475 SetFocus(m_pCHatchWin
->Window());
476 // if(m_xEditWindow.is()) m_xEditWindow->setFocus();
478 //3. Set the active object
480 OLECHAR starOffice
[] = {'S','t','a','r','O','f','f','i','c','e',0};
481 CComPtr
< IOleInPlaceActiveObject
> pObj
= new CIIAObj( this );
483 if (NULL
!=m_pIOleIPFrame
)
484 m_pIOleIPFrame
->SetActiveObject(
487 if (NULL
!=m_pIOleIPUIWindow
)
488 m_pIOleIPUIWindow
->SetActiveObject(
491 //4. Create the shared menu.
497 void DocumentHolder::UIDeactivate()
499 //1. Remove the shared menu.
500 InPlaceMenuDestroy();
502 if (NULL
!=m_pIOleIPFrame
)
503 m_pIOleIPFrame
->SetActiveObject(NULL
, NULL
);
505 if (NULL
!=m_pIOleIPUIWindow
)
506 m_pIOleIPUIWindow
->SetActiveObject(NULL
, NULL
);
508 //3. Call IOleInPlaceSite::OnUIDeactivate
509 if (NULL
!=m_pIOleIPSite
)
510 m_pIOleIPSite
->OnUIDeactivate(FALSE
);
515 void CopyToOLEMenu(HMENU hOrig
,WORD origPos
,HMENU hDest
,WORD destPos
)
518 UINT uTemp
= MF_BYPOSITION
| MF_POPUP
;
521 subMenu
= GetSubMenu(hOrig
,origPos
);
522 GetMenuString(hOrig
,origPos
,buffer
,256,MF_BYPOSITION
);
523 InsertMenu(hDest
,destPos
,uTemp
,
524 (UINT
)subMenu
,LPCTSTR(buffer
));
527 memset(&mi
,0,sizeof(mi
));
528 mi
.cbSize
= sizeof(mi
);
529 mi
.fMask
= MIIM_DATA
;
530 if(GetMenuItemInfoW(hOrig
,origPos
,TRUE
,&mi
))
531 SetMenuItemInfoW(hDest
,(WORD
)destPos
,TRUE
,&mi
);
534 BOOL
DocumentHolder::InPlaceMenuCreate(void)
538 OLEMENUGROUPWIDTHS mgw
;
543 //We already have popup menu handles in m_pFR->m_phMenu[]
545 //Create the new shared menu and let container do its thing
547 m_pIOleIPFrame
->InsertMenus(hMenu
,&mgw
);
549 int count
= GetMenuItemCount(m_nMenuHandle
);
552 // start with 1, because we don't include "File"
553 WORD pos
= (WORD
)mgw
.width
[0];
554 CopyToOLEMenu(m_nMenuHandle
,1,hMenu
,pos
);
557 // insert object menu here
558 pos
= ((WORD
)(mgw
.width
[0] + mgw
.width
[1] + mgw
.width
[2]));
559 for(WORD i
= 2; i
< help
-1; ++i
,++pos
)
560 CopyToOLEMenu(m_nMenuHandle
,i
,hMenu
,pos
);
561 mgw
.width
[3] = help
- 3;
564 pos
= (WORD
)(mgw
.width
[0] + mgw
.width
[1] + mgw
.width
[2] +
565 mgw
.width
[3] + mgw
.width
[4]);
566 CopyToOLEMenu(m_nMenuHandle
,WORD(help
),hMenu
,pos
);
569 m_nMenuShared
= hMenu
;
570 m_nOLEMenu
= OleCreateMenuDescriptor(m_nMenuShared
,&mgw
);
572 uno::Reference
<awt::XSystemDependentWindowPeer
> xSysDepWin(m_xContainerWindow
,uno::UNO_QUERY
);
573 if(xSysDepWin
.is()) {
574 uno::Sequence
<sal_Int8
> aProcessIdent(16);
575 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
576 uno::Any aAny
= xSysDepWin
->getWindowHandle(aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
579 HWND aHwnd
= (HWND
) tmp
;
580 m_pIOleIPFrame
->SetMenu(
581 m_nMenuShared
,m_nOLEMenu
,aHwnd
);
584 m_pIOleIPFrame
->SetMenu(
585 m_nMenuShared
,m_nOLEMenu
,::GetWindow(m_hWndxWinParent
,GW_CHILD
));
589 BOOL
DocumentHolder::InPlaceMenuDestroy(void)
591 if( NULL
== m_nMenuShared
)
594 m_pIOleIPFrame
->SetMenu(NULL
,NULL
,NULL
);
596 OleDestroyMenuDescriptor(m_nOLEMenu
),m_nOLEMenu
= NULL
;
600 void DocumentHolder::OpenIntoWindow(void)
605 BOOL
DocumentHolder::Undo(void)
612 void DocumentHolder::FreeOffice()
614 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
615 xDesktop
->removeTerminateListener(
616 (frame::XTerminateListener
*)this );
619 void DocumentHolder::DisconnectFrameDocument( sal_Bool bComplete
)
623 uno::Reference
< util::XModifyBroadcaster
> xModifiable( m_xDocument
, uno::UNO_QUERY_THROW
);
624 xModifiable
->removeModifyListener( (util::XModifyListener
*)this );
626 catch( const uno::Exception
& )
631 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
632 m_xDocument
, uno::UNO_QUERY_THROW
);
633 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
635 catch( const uno::Exception
& )
640 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
641 m_xFrame
, uno::UNO_QUERY_THROW
);
642 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
644 catch( const uno::Exception
& )
649 m_xFrame
= uno::Reference
<frame::XFrame2
>();
651 m_xDocument
= uno::Reference
< frame::XModel
>();
655 void DocumentHolder::CloseDocument()
657 DisconnectFrameDocument();
659 uno::Reference
< util::XCloseable
> xCloseable(
660 m_xDocument
, uno::UNO_QUERY
);
662 if ( xCloseable
.is() )
666 xCloseable
->close( sal_True
);
668 catch( const uno::Exception
& )
673 m_xDocument
= uno::Reference
< frame::XModel
>();
677 void DocumentHolder::CloseFrame()
681 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
682 m_xFrame
, uno::UNO_QUERY_THROW
);
683 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
685 catch( const uno::Exception
& )
688 uno::Reference
<util::XCloseable
> xCloseable(
689 m_xFrame
,uno::UNO_QUERY
);
692 xCloseable
->close(sal_True
);
694 catch( const uno::Exception
& ) {
700 m_xFrame
= uno::Reference
< frame::XFrame2
>();
703 void DocumentHolder::SetDocument( const uno::Reference
< frame::XModel
>& xDoc
, sal_Bool bLink
)
705 if ( m_xDocument
.is() )
711 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
712 m_xDocument
, uno::UNO_QUERY
);
714 if ( xBroadcaster
.is() )
715 xBroadcaster
->addCloseListener( (util::XCloseListener
*)this );
717 if ( m_xDocument
.is() && !m_bLink
)
719 // set the document mode to embedded
720 uno::Sequence
< beans::PropertyValue
> aSeq(1);
721 aSeq
[0].Name
= "SetEmbedded";
722 aSeq
[0].Value
<<= sal_True
;
723 m_xDocument
->attachResource(OUString(),aSeq
);
727 sal_Bool
DocumentHolder::ExecuteSuspendCloseFrame()
729 if ( m_xFrame
.is() && m_xFactory
.is() )
733 uno::Reference
< frame::XController
> xController
= m_xFrame
->getController();
734 if ( xController
.is() )
736 if ( !xController
->suspend( sal_True
) )
742 uno::Reference
<util::XCloseable
> xCloseable( m_xFrame
, uno::UNO_QUERY
);
743 if ( xCloseable
.is() )
744 xCloseable
->close(sal_True
);
750 catch( const util::CloseVetoException
& )
752 // should be called if the frame could not be closed
753 xController
->suspend( sal_False
);
757 catch( uno::Exception
& )
761 m_xFrame
= uno::Reference
< frame::XFrame2
>();
767 uno::Reference
< frame::XFrame2
> DocumentHolder::DocumentFrame()
771 uno::Reference
<frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
773 uno::Reference
<frame::XFrame2
> xFrame(xDesktop
,uno::UNO_QUERY
);
775 // the frame will be registered on desktop here, later when the document
776 // is loaded into the frame in ::show() method the terminate listener will be removed
777 // this is so only for outplace activation
779 m_xFrame
.set( xFrame
->findFrame( OUString("_blank"), 0 ), uno::UNO_QUERY_THROW
);
781 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
782 m_xFrame
, uno::UNO_QUERY
);
784 if ( xBroadcaster
.is() )
786 xBroadcaster
->addCloseListener( (util::XCloseListener
*)this );
787 FreeOffice(); // the frame is part of the desktop
794 m_xFrame
->registerDispatchProviderInterceptor( CreateNewInterceptor() );
801 uno::Reference
< frame::XDispatchProviderInterceptor
> DocumentHolder::CreateNewInterceptor()
803 ::osl::MutexGuard
aGuard( m_aMutex
);
805 ClearInterceptorInternally();
807 uno::Reference
< frame::XDispatchProviderInterceptor
> xInterceptor( m_pInterceptor
= new Interceptor( m_xOleAccess
, this, m_bLink
) );
808 m_xInterceptorLocker
= xInterceptor
;
812 void DocumentHolder::ClearInterceptorInternally()
814 ::osl::MutexGuard
aGuard( m_aMutex
);
815 uno::Reference
< frame::XDispatchProviderInterceptor
> xInterceptor( m_xInterceptorLocker
);
816 if ( xInterceptor
.is() && m_pInterceptor
)
817 m_pInterceptor
->DisconnectDocHolder();
819 m_xInterceptorLocker
= uno::Reference
< frame::XDispatchProviderInterceptor
>();
823 void DocumentHolder::ClearInterceptor()
825 ::osl::MutexGuard
aGuard( m_aMutex
);
826 m_xInterceptorLocker
= uno::Reference
< frame::XDispatchProviderInterceptor
>();
831 void DocumentHolder::show()
837 m_xFrame
->activate();
838 uno::Reference
<awt::XTopWindow
> xTopWindow(
839 m_xFrame
->getContainerWindow(),uno::UNO_QUERY
);
841 xTopWindow
->toFront();
843 else if( DocumentFrame().is() )
845 LoadDocInFrame( sal_False
);
847 // get rid of second closer if it is there
848 uno::Reference
< beans::XPropertySet
> xLMProps( m_xFrame
->getLayoutManager(), uno::UNO_QUERY
);
851 xLMProps
->setPropertyValue("MenuBarCloser",
852 uno::makeAny( uno::Reference
< frame::XStatusListener
>() ) );
859 uno::Reference
< util::XModifyBroadcaster
> xModifiable( m_xDocument
, uno::UNO_QUERY_THROW
);
860 xModifiable
->addModifyListener( (util::XModifyListener
*)this );
862 catch( const uno::Exception
& )
867 setTitle(m_aDocumentNamePart
);
870 catch( const uno::Exception
& )
872 OSL_FAIL( "Can not show the frame!\n" );
877 void DocumentHolder::resizeWin( const SIZEL
& rNewSize
)
879 LockedEmbedDocument_Impl aDocLock
;
881 if ( m_xOleAccess
.is() )
882 aDocLock
= m_xOleAccess
->GetEmbedDocument();
884 if ( m_xFrame
.is() && aDocLock
.GetEmbedDocument() )
886 uno::Reference
< awt::XWindow
> xWindow(
887 m_xFrame
->getContainerWindow(), uno::UNO_QUERY
);
888 uno::Reference
< awt::XView
> xView( xWindow
, uno::UNO_QUERY
);
890 if ( xWindow
.is() && xView
.is() )
893 xView
->setZoom( fScale
, fScale
);
896 GetExtent( &aOldSize
);
898 if ( aOldSize
.cx
!= rNewSize
.cx
|| aOldSize
.cy
!= rNewSize
.cy
)
900 HDC hdc
= GetDC( NULL
);
901 SetMapMode( hdc
, MM_HIMETRIC
);
904 aOldOffset
.x
= aOldSize
.cx
;
905 aOldOffset
.y
= aOldSize
.cy
;
906 BOOL bIsOk
= LPtoDP( hdc
, &aOldOffset
, 1 );
909 aNewOffset
.x
= rNewSize
.cx
;
910 aNewOffset
.y
= rNewSize
.cy
;
911 bIsOk
= LPtoDP( hdc
, &aNewOffset
, 1 );
913 ReleaseDC( NULL
, hdc
);
915 awt::Rectangle aWinRect
= xWindow
->getPosSize();
917 sal_Int32 aWidthDelta
= aWinRect
.Width
- aOldOffset
.x
;
918 sal_Int32 aHeightDelta
= aWinRect
.Height
- aOldOffset
.y
;
920 if ( aWidthDelta
> 0 && aHeightDelta
> 0 )
921 xWindow
->setPosSize(0,
923 aNewOffset
.x
+ aWidthDelta
,
924 aNewOffset
.y
+ aHeightDelta
,
925 awt::PosSize::SIZE
);
931 void DocumentHolder::setTitle(const OUString
& aDocumentName
)
935 if(m_aFilterName
.getLength() == 0)
937 OUString aFilterName
;
938 uno::Sequence
<beans::PropertyValue
> aSeq
;
942 m_xDocument
->getArgs();
943 for(sal_Int32 j
= 0; j
< aSeq
.getLength(); ++j
)
945 if(aSeq
[j
].Name
== "FilterName")
947 aSeq
[j
].Value
>>= aFilterName
;
953 if(aFilterName
.getLength())
955 uno::Reference
<container::XNameAccess
> xNameAccess(
956 m_xFactory
->createInstance(
958 "com.sun.star.document.FilterFactory")),
961 if(xNameAccess
.is() &&
962 (xNameAccess
->getByName(aFilterName
) >>= aSeq
))
964 for(sal_Int32 j
= 0; j
< aSeq
.getLength(); ++j
)
968 aSeq
[j
].Value
>>= m_aFilterName
;
973 catch(const uno::Exception
& ) {
974 // nothing better to do here
975 m_aFilterName
= aFilterName
;
980 static const sal_Unicode u
[] = { ' ','(',0 };
981 static const sal_Unicode c
[] = { ')',0 };
982 rtl::OUString
aTotalName(m_aFilterName
);
983 aTotalName
+= rtl::OUString(u
);
984 aTotalName
+= aDocumentName
;
985 aTotalName
+= rtl::OUString(c
);
987 m_xFrame
->setTitle( aTotalName
);
989 catch( const uno::Exception
& ) {
993 m_aDocumentNamePart
= aDocumentName
;
997 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
999 Interceptor
* pTmpInter
= NULL
;
1000 uno::Reference
< frame::XDispatchProviderInterceptor
> xLock( m_xInterceptorLocker
);
1001 if ( xLock
.is() && m_pInterceptor
)
1002 pTmpInter
= m_pInterceptor
;
1007 pTmpInter
->generateFeatureStateEvent();
1012 void DocumentHolder::setContainerName(const OUString
& aContainerName
)
1014 m_aContainerName
= aContainerName
;
1018 void DocumentHolder::hide()
1020 if(m_xFrame
.is()) m_xFrame
->deactivate();
1023 // after hiding the window it is always allowed to InPlaceActivate it
1024 m_bAllowInPlace
= true;
1027 IDispatch
* DocumentHolder::GetIDispatch()
1029 if ( !m_pIDispatch
&& m_xDocument
.is() )
1031 const OUString
aServiceName (
1032 "com.sun.star.bridge.OleBridgeSupplier2" );
1033 uno::Reference
< bridge::XBridgeSupplier2
> xSupplier(
1034 m_xFactory
->createInstance( aServiceName
), uno::UNO_QUERY
);
1036 if ( xSupplier
.is() )
1038 uno::Sequence
< sal_Int8
> aProcId( 16 );
1039 rtl_getGlobalProcessId( (sal_uInt8
*)aProcId
.getArray() );
1042 uno::Any anyResult
= xSupplier
->createBridge(
1043 uno::makeAny( m_xDocument
),
1045 bridge::ModelDependent::UNO
,
1046 bridge::ModelDependent::OLE
);
1048 if ( anyResult
.getValueTypeClass() ==
1049 getCppuType((sal_uInt32
*) 0).getTypeClass() )
1051 VARIANT
* pVariant
= *(VARIANT
**)anyResult
.getValue();
1052 if ( pVariant
->vt
== VT_DISPATCH
)
1053 m_pIDispatch
= pVariant
->pdispVal
;
1055 VariantClear( pVariant
);
1056 CoTaskMemFree( pVariant
);
1059 catch ( const uno::Exception
& )
1064 return m_pIDispatch
;
1067 HRESULT
DocumentHolder::GetDocumentBorder( RECT
*pRect
)
1069 if ( pRect
&& m_xDocument
.is() )
1071 uno::Sequence
< beans::PropertyValue
> aArgs
= m_xDocument
->getArgs();
1072 for ( sal_Int32 nInd
= 0; nInd
< aArgs
.getLength(); nInd
++ )
1073 if ( aArgs
[nInd
].Name
== "DocumentBorder" )
1075 uno::Sequence
< sal_Int32
> aRect
;
1076 if ( ( aArgs
[nInd
].Value
>>= aRect
) && aRect
.getLength() == 4 )
1078 pRect
->left
= aRect
[0];
1079 pRect
->top
= aRect
[1];
1080 pRect
->right
= aRect
[2];
1081 pRect
->bottom
= aRect
[3];
1093 HRESULT
DocumentHolder::SetExtent( const SIZEL
*pSize
)
1097 uno::Reference
< embed::XVisualObject
> xVisObj( m_xDocument
, uno::UNO_QUERY
);
1102 awt::Size
aNewSize( pSize
->cx
, pSize
->cy
);
1104 sal_Int32 aMapMode
= xVisObj
->getMapUnit( DVASPECT_CONTENT
);
1106 // TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1107 if ( aMapMode
== embed::EmbedMapUnits::TWIP
)
1109 // convertion from ONE_100TH_MM
1110 aNewSize
.Width
= aNewSize
.Width
* 144 / 254;
1111 aNewSize
.Height
= aNewSize
.Height
* 144 / 254;
1115 xVisObj
->setVisualAreaSize( DVASPECT_CONTENT
, aNewSize
);
1119 catch( const uno::Exception
& )
1127 HRESULT
DocumentHolder::GetExtent( SIZEL
*pSize
)
1131 uno::Reference
< embed::XVisualObject
> xVisObj( m_xDocument
, uno::UNO_QUERY
);
1136 awt::Size aDocSize
= xVisObj
->getVisualAreaSize( DVASPECT_CONTENT
);
1138 sal_Int32 aMapMode
= xVisObj
->getMapUnit( DVASPECT_CONTENT
);
1140 // TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1141 if ( aMapMode
== embed::EmbedMapUnits::TWIP
)
1143 // convertion to ONE_100TH_MM
1144 aDocSize
.Width
= aDocSize
.Width
* 254 / 144;
1145 aDocSize
.Height
= aDocSize
.Height
* 254 / 144;
1148 pSize
->cx
= aDocSize
.Width
;
1149 pSize
->cy
= aDocSize
.Height
;
1153 catch( const uno::Exception
& )
1162 HRESULT
DocumentHolder::SetContRects(LPCRECT aRect
)
1164 if(m_xContainerWindow
.is()) {
1166 memset(&wi
,0,sizeof(wi
));
1167 if(m_pIOleIPFrame
) {
1168 m_pIOleIPFrame
->GetBorder((LPRECT
)&wi
);
1169 m_xContainerWindow
->setPosSize(
1173 awt::PosSize::POSSIZE
);
1176 m_xContainerWindow
->setPosSize(
1178 aRect
->right
- aRect
->left
,
1179 aRect
->bottom
- aRect
->top
,
1180 awt::PosSize::POSSIZE
);
1189 HRESULT
DocumentHolder::SetObjectRects(LPCRECT aRect
, LPCRECT aClip
)
1191 ((LPRECT
)aRect
)->left
-= m_aBorder
.left
;
1192 ((LPRECT
)aRect
)->right
+= m_aBorder
.right
;
1193 ((LPRECT
)aRect
)->top
-= m_aBorder
.top
;
1194 ((LPRECT
)aRect
)->bottom
+= m_aBorder
.bottom
;
1195 ((LPRECT
)aClip
)->left
-= m_aBorder
.left
;
1196 ((LPRECT
)aClip
)->right
+= m_aBorder
.right
;
1197 ((LPRECT
)aClip
)->top
-= m_aBorder
.top
;
1198 ((LPRECT
)aClip
)->bottom
+= m_aBorder
.bottom
;
1201 m_pCHatchWin
->RectsSet((LPRECT
)aRect
, (LPRECT
)aClip
);
1202 if(m_xEditWindow
.is()) {
1203 m_xEditWindow
->setVisible(false);
1204 m_xEditWindow
->setPosSize(
1205 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
1206 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
1207 aRect
->right
- aRect
->left
,
1208 aRect
->bottom
- aRect
->top
,
1209 awt::PosSize::POSSIZE
);
1210 m_xEditWindow
->setVisible(true);
1216 ::com::sun::star::uno::Reference
<
1217 ::com::sun::star::awt::XWindow
> SAL_CALL
1218 DocumentHolder::getContainerWindow(
1221 ::com::sun::star::uno::RuntimeException
1224 if(m_xContainerWindow
.is())
1225 return m_xContainerWindow
;
1227 uno::Reference
<awt::XWindow
> xWin(0);
1229 uno::Reference
<awt::XToolkit2
> xToolkit
= awt::Toolkit::create( comphelper::getComponentContext(m_xFactory
) );
1231 if(m_pIOleIPFrame
) {
1233 m_pIOleIPFrame
->GetWindow(&hWnd
);
1235 uno::Sequence
<sal_Int8
> aProcessIdent(16);
1236 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
1239 aAny
<<= sal_Int32(hWnd
);
1240 xWin
= uno::Reference
<awt::XWindow
>(
1241 xToolkit
->createSystemChild(
1244 lang::SystemDependent::SYSTEM_WIN32
),
1248 memset(&wi
,0,sizeof(wi
));
1249 if(xWin
.is() && m_pIOleIPFrame
->GetBorder((LPRECT
)&wi
) == NOERROR
) {
1250 xWin
->setVisible(true);
1255 awt::PosSize::POSSIZE
);
1257 uno::Reference
<awt::XSystemDependentWindowPeer
> xSysWin(
1258 xWin
,uno::UNO_QUERY
);
1260 aAny
= xSysWin
->getWindowHandle(
1261 aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
1264 SetContainerWindowHandle((HWND
) tmp
);
1269 m_xContainerWindow
= xWin
;
1276 DocumentHolder::requestDockingAreaSpace(
1277 const ::com::sun::star::awt::Rectangle
& RequestedSpace
1280 ::com::sun::star::uno::RuntimeException
1287 SetRect((LPRECT
)&bw
,
1288 RequestedSpace
.X
,RequestedSpace
.Y
,
1289 RequestedSpace
.Width
,RequestedSpace
.Height
);
1290 if( m_pIOleIPFrame
)
1291 return m_pIOleIPFrame
->RequestBorderSpace(&bw
) == NOERROR
;
1293 return sal_Bool(false);
1298 DocumentHolder::setDockingAreaSpace(
1299 const ::com::sun::star::awt::Rectangle
& BorderSpace
1302 ::com::sun::star::uno::RuntimeException
1309 SetRect((LPRECT
)&bw
,
1310 BorderSpace
.X
,BorderSpace
.Y
,
1311 BorderSpace
.Width
,BorderSpace
.Height
);
1312 if( m_pIOleIPFrame
) {
1314 GetClientRect(m_hWndxWinCont
,&aRect
);
1315 HRGN hrgn1
= CreateRectRgn(
1317 aRect
.right
,BorderSpace
.Y
);
1318 HRGN hrgn2
= CreateRectRgn(aRect
.right
-BorderSpace
.Width
,0,aRect
.right
,aRect
.bottom
);
1319 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1320 DeleteObject(hrgn2
);
1321 hrgn2
= CreateRectRgn(0,aRect
.bottom
-BorderSpace
.Height
,aRect
.right
,aRect
.bottom
);
1322 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1323 DeleteObject(hrgn2
);
1324 hrgn2
= CreateRectRgn(0,0,BorderSpace
.X
,aRect
.bottom
);
1325 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1326 DeleteObject(hrgn2
);
1328 SetWindowRgn(m_hWndxWinCont
,hrgn1
,true);
1329 // not:: DeleteObject(hrgn1);
1330 m_pIOleIPFrame
->SetBorderSpace(&bw
);
1336 DocumentHolder::disposing(
1337 const com::sun::star::lang::EventObject
& aSource
1339 throw( uno::RuntimeException
)
1341 if ( m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1343 m_pIDispatch
= NULL
;
1344 m_xDocument
= uno::Reference
< frame::XModel
>();
1347 if( m_xFrame
.is() && m_xFrame
== aSource
.Source
)
1348 m_xFrame
= uno::Reference
< frame::XFrame2
>();
1353 DocumentHolder::queryClosing(
1354 const lang::EventObject
& aSource
,
1355 sal_Bool
/*bGetsOwnership*/
1358 util::CloseVetoException
1362 && ( m_xDocument
.is() && m_xDocument
== aSource
.Source
|| m_xFrame
.is() && m_xFrame
== aSource
.Source
) )
1363 throw util::CloseVetoException();
1368 DocumentHolder::notifyClosing(
1369 const lang::EventObject
& aSource
)
1370 throw( uno::RuntimeException
)
1374 uno::Reference
< util::XCloseBroadcaster
> xEventBroadcaster(
1375 aSource
.Source
, uno::UNO_QUERY_THROW
);
1376 xEventBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
1378 catch( const uno::Exception
& )
1381 if ( m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1383 // can happen only in case of links
1384 m_pIDispatch
= NULL
;
1385 m_xDocument
= uno::Reference
< frame::XModel
>();
1386 m_xFrame
= uno::Reference
< frame::XFrame2
>();
1388 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
1389 if ( aDocLock
.GetEmbedDocument() )
1390 aDocLock
.GetEmbedDocument()->OLENotifyClosing();
1392 else if( m_xFrame
.is() && m_xFrame
== aSource
.Source
)
1393 m_xFrame
= uno::Reference
< frame::XFrame2
>();
1397 DocumentHolder::queryTermination(
1398 const lang::EventObject
& /*aSource*/
1401 frame::TerminationVetoException
1404 if ( m_xDocument
.is() )
1405 throw frame::TerminationVetoException();
1409 DocumentHolder::notifyTermination(
1410 const lang::EventObject
& aSource
1412 throw( uno::RuntimeException
)
1414 OSL_ENSURE( !m_xDocument
.is(), "Just a disaster..." );
1415 uno::Reference
< frame::XDesktop
> xDesktop(
1416 aSource
.Source
, uno::UNO_QUERY
);
1418 if ( xDesktop
.is() )
1419 xDesktop
->removeTerminateListener( (frame::XTerminateListener
*)this );
1424 void SAL_CALL
DocumentHolder::modified( const lang::EventObject
& /*aEvent*/ )
1425 throw (uno::RuntimeException
)
1427 if ( m_xOleAccess
.is() )
1429 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
1430 if ( aDocLock
.GetEmbedDocument() )
1431 aDocLock
.GetEmbedDocument()->notify();
1435 // Fix strange warnings about some
1436 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
1437 // warning C4505: 'xxx' : unreferenced local function has been removed
1439 #pragma warning(disable: 4505)
1442 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */