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/lang/SystemDependent.hpp>
34 #include <com/sun/star/awt/Toolkit.hpp>
35 #include <com/sun/star/awt/XSystemChildFactory.hpp>
36 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
37 #include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
38 #include <com/sun/star/ui/XUIElement.hpp>
39 #include <com/sun/star/awt/WindowAttribute.hpp>
40 #include <com/sun/star/awt/XWindow.hpp>
41 #include <com/sun/star/frame/XComponentLoader.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <com/sun/star/util/XCloseBroadcaster.hpp>
44 #include <com/sun/star/util/XCloseAble.hpp>
45 #include <com/sun/star/container/XNameAccess.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/frame/XModel.hpp>
48 #include <com/sun/star/frame/XDesktop.hpp>
49 #include <com/sun/star/frame/XFramesSupplier.hpp>
50 #include <com/sun/star/frame/FrameSearchFlag.hpp>
51 #include <com/sun/star/frame/XStatusListener.hpp>
52 #include <com/sun/star/util/XModifyBroadcaster.hpp>
53 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
54 #include <com/sun/star/awt/XTopWindow.hpp>
55 #include <com/sun/star/awt/PosSize.hpp>
56 #include <com/sun/star/awt/XView.hpp>
57 #include <com/sun/star/bridge/XBridgeSupplier2.hpp>
58 #include <com/sun/star/bridge/ModelDependent.hpp>
59 #include <com/sun/star/embed/EmbedMapUnits.hpp>
60 #include <com/sun/star/embed/XVisualObject.hpp>
61 #include <com/sun/star/document/MacroExecMode.hpp>
62 #include <com/sun/star/task/InteractionHandler.hpp>
63 #include <comphelper/processfactory.hxx>
64 #include <osl/diagnose.h>
65 #include <rtl/process.h>
67 using namespace ::com::sun::star
;
69 extern ::rtl::OUString
getFilterNameFromGUID_Impl( GUID
* );
71 // add mutex locking ???
73 DocumentHolder::DocumentHolder(
74 const uno::Reference
<lang::XMultiServiceFactory
>& xFactory
,
75 const ::rtl::Reference
< EmbeddedDocumentInstanceAccess_Impl
>& xOleAccess
)
77 m_bAllowInPlace(true),
82 m_xOleAccess( xOleAccess
),
84 m_xFactory( xFactory
),
85 m_bOnDeactivate(false),
86 m_hWndxWinParent(NULL
),
91 m_nMacroExecMode( document::MacroExecMode::USE_CONFIG
),
94 static const ::rtl::OUString
aServiceName (
95 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
96 uno::Reference
< frame::XDesktop
> xDesktop(
97 m_xFactory
->createInstance( aServiceName
),
100 xDesktop
->addTerminateListener( (frame::XTerminateListener
*)this );
104 DocumentHolder::~DocumentHolder()
108 ClearInterceptorInternally();
112 void DocumentHolder::LoadDocInFrame( sal_Bool bPluginMode
)
114 uno::Reference
<frame::XComponentLoader
> xComponentLoader(
115 m_xFrame
,uno::UNO_QUERY
);
116 if( xComponentLoader
.is() && m_xDocument
.is() )
118 uno::Reference
< task::XInteractionHandler2
> xHandler(
119 task::InteractionHandler::createWithParent(comphelper::getComponentContext(m_xFactory
), 0) );
123 uno::Sequence
<beans::PropertyValue
> aSeq( nLen
);
125 aAny
<<= uno::Reference
<uno::XInterface
>(
126 m_xDocument
, uno::UNO_QUERY
);
127 aSeq
[0] = beans::PropertyValue(
129 RTL_CONSTASCII_USTRINGPARAM("Model")),
132 beans::PropertyState_DIRECT_VALUE
);
135 aSeq
[1] = beans::PropertyValue(
137 RTL_CONSTASCII_USTRINGPARAM("ReadOnly")),
140 beans::PropertyState_DIRECT_VALUE
);
142 aAny
<<= (sal_Bool
) sal_True
;
143 aSeq
[2] = beans::PropertyValue(
145 RTL_CONSTASCII_USTRINGPARAM("NoAutoSave")),
148 beans::PropertyState_DIRECT_VALUE
);
152 aSeq
.realloc( ++nLen
);
153 aAny
<<= (sal_Int16
) 3;
154 aSeq
[nLen
-1] = beans::PropertyValue(
156 RTL_CONSTASCII_USTRINGPARAM("PluginMode")),
159 beans::PropertyState_DIRECT_VALUE
);
162 aSeq
.realloc( nLen
+=2 );
164 aSeq
[nLen
-2] = beans::PropertyValue(
166 RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")),
169 beans::PropertyState_DIRECT_VALUE
);
171 aAny
<<= m_nMacroExecMode
;
172 aSeq
[nLen
-1] = beans::PropertyValue(
174 RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode")),
177 beans::PropertyState_DIRECT_VALUE
);
179 xComponentLoader
->loadComponentFromURL(
181 RTL_CONSTASCII_USTRINGPARAM("private:object")),
182 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")),
186 uno::Sequence
< beans::PropertyValue
> aResArgs
= m_xDocument
->getArgs();
187 for ( int nInd
= 0; nInd
< aResArgs
.getLength(); nInd
++ )
188 if ( aResArgs
[nInd
].Name
== "MacroExecutionMode" )
190 aResArgs
[nInd
].Value
>>= m_nMacroExecMode
;
196 void DocumentHolder::OnPosRectChanged(LPRECT lpRect
) const
198 lpRect
->left
+= m_aBorder
.left
;
199 lpRect
->right
-= m_aBorder
.right
;
200 lpRect
->top
+= m_aBorder
.top
;
201 lpRect
->bottom
-= m_aBorder
.bottom
;
203 m_pIOleIPSite
->OnPosRectChange(lpRect
);
208 void DocumentHolder::DisableInplaceActivation(BOOL b
)
210 m_bAllowInPlace
= ! b
;
213 BOOL
DocumentHolder::isActive() const
215 return m_pIOleIPSite
!= 0;
218 HRESULT
DocumentHolder::InPlaceActivate(
219 LPOLECLIENTSITE pActiveSite
,
222 m_bOnDeactivate
= false;
231 OLEINPLACEFRAMEINFO frameInfo
;
233 if (NULL
==pActiveSite
)
234 return ResultFromScode(E_INVALIDARG
);
236 if (NULL
!=m_pIOleIPSite
)
244 if ( !m_xDocument
.is() )
247 //1. Initialization, obtaining interfaces, OnInPlaceActivate.
248 hr
=pActiveSite
->QueryInterface(
250 (void**) &m_pIOleIPSite
);
255 hr
=m_pIOleIPSite
->CanInPlaceActivate();
259 m_pIOleIPSite
->Release(), m_pIOleIPSite
=NULL
;
260 return ResultFromScode(E_FAIL
);
263 m_pIOleIPSite
->OnInPlaceActivate();
265 //2. Get the site window
266 //3. and determine container frame and
267 // document window for tools and menus, as well
268 // as frameInfo for accelerators
269 m_pIOleIPSite
->GetWindow(&hWndSite
);
271 frameInfo
.cb
=sizeof(OLEINPLACEFRAMEINFO
);
272 m_pIOleIPSite
->GetWindowContext(
273 &m_pIOleIPFrame
,&m_pIOleIPUIWindow
,&rcPos
,&rcClip
,&frameInfo
);
275 // initialize the office as, with hwnd as parentwindow
277 uno::Sequence
<sal_Int8
> aProcessIdent(16);
278 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
282 if(!m_xEditWindow
.is())
283 { // determine XWindow and window handle of parent
284 HWND
hWndxWinParent(0);
285 uno::Reference
<awt::XWindow
> xWin
;
287 uno::Reference
<awt::XToolkit2
> xToolkit
=
288 awt::Toolkit::create(comphelper::getComponentContext(m_xFactory
));
290 // create system window wrapper for hwnd
292 m_pCHatchWin
= new winwrap::CHatchWin(
295 if(m_pCHatchWin
->Init(hWndSite
,/*ID_HATCHWINDOW*/2000, NULL
)) {
296 m_pCHatchWin
->RectsSet(&rcPos
,&rcClip
); //set visible area
297 hWndxWinParent
= m_pCHatchWin
->Window();
298 ShowWindow(hWndxWinParent
,SW_SHOW
); //Make visible.
301 // no success initializing hatch window
302 delete m_pCHatchWin
, m_pCHatchWin
= 0;
303 hWndxWinParent
= hWndSite
;
306 aAny
<<= sal_Int32(hWndxWinParent
);
307 xWin
= uno::Reference
<awt::XWindow
>(
308 xToolkit
->createSystemChild(
311 lang::SystemDependent::SYSTEM_WIN32
),
316 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
317 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
318 rcPos
.right
-rcPos
.left
,
319 rcPos
.bottom
- rcPos
.top
,
320 awt::PosSize::POSSIZE
);
321 xWin
->setVisible(sal_True
);
323 m_xEditWindow
= xWin
;
324 m_hWndxWinParent
= hWndxWinParent
;
330 if(m_hWndxWinParent
) {
331 SetParent(m_hWndxWinParent
,hWndSite
);
332 ShowWindow(m_hWndxWinParent
,SW_SHOW
); //Make visible.
335 if ( !m_xFrame
.is() )
336 // initially set size to "empty", this guarantees that the final resize
337 // is always executed (will be done by "SetObjectRects" after getting internal border)
338 m_xEditWindow
->setPosSize(
343 awt::PosSize::POSSIZE
);
344 m_xEditWindow
->setVisible(sal_True
);
347 if(m_xContainerWindow
.is()) {
351 m_pIOleIPFrame
->GetWindow(&hWndCont
);
352 SetParent(m_hWndxWinCont
,hWndCont
);
353 ShowWindow(m_hWndxWinCont
,SW_SHOW
);
356 m_xContainerWindow
->setVisible(true);
360 m_xFrame
->activate();
362 // create frame and initialize it with with the created window
363 static const ::rtl::OUString
aFrameServiceName(
364 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Frame" ) );
365 m_xFrame
= uno::Reference
<frame::XFrame
>(
366 m_xFactory
->createInstance(aFrameServiceName
),
372 m_xFrame
->initialize(m_xEditWindow
);
374 uno::Reference
<frame::XDispatchProviderInterception
>
375 xDPI(m_xFrame
,uno::UNO_QUERY
);
377 xDPI
->registerDispatchProviderInterceptor( CreateNewInterceptor() );
379 uno::Reference
<beans::XPropertySet
> xPS(m_xFrame
,uno::UNO_QUERY
);
382 aAny
= xPS
->getPropertyValue(
383 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager")));
384 aAny
>>= m_xLayoutManager
;
387 if(m_xLayoutManager
.is())
388 m_xLayoutManager
->setDockingAreaAcceptor(this);
390 // load the model into the frame
391 LoadDocInFrame( sal_True
);
393 static const ::rtl::OUString
aDesktopServiceName (
394 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
395 uno::Reference
< frame::XFramesSupplier
> xDesktop(
396 m_xFactory
->createInstance( aDesktopServiceName
),
399 xDesktop
->getFrames()->append(m_xFrame
);
401 // determine the menuhandle to get menutitems.
402 if(m_xLayoutManager
.is()) {
403 uno::Reference
< ::com::sun::star::ui::XUIElement
> xUIEl(
404 m_xLayoutManager
->getElement(
405 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
406 "private:resource/menubar/menubar"))));
407 OSL_ENSURE(xUIEl
.is(),"no menubar");
408 uno::Reference
<awt::XSystemDependentMenuPeer
> xSDMP(
409 xUIEl
->getRealInterface(),
411 aAny
= xSDMP
->getMenuHandle(
412 aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
415 m_nMenuHandle
= HMENU(tmp
);
416 m_xLayoutManager
->hideElement(
418 RTL_CONSTASCII_USTRINGPARAM(
419 "private:resource/menubar/menubar" )));
423 // TODO/cd: Workaround for status indicator bug. It always makes the
424 // document window visible, when someone tries to use the status
425 // indicator. As we save our document when we get the deactivation
426 // from OLE this conflict to hide floating windows.
427 if(m_xLayoutManager
.is())
428 m_xLayoutManager
->setVisible(true);
430 // get document border and resize rects according to border
431 GetDocumentBorder( &m_aBorder
);
432 SetObjectRects( &rcPos
, &rcClip
);
434 if ( m_xOleAccess
.is() )
436 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
437 if ( aDocLock
.GetEmbedDocument() )
438 aDocLock
.GetEmbedDocument()->ShowObject();
441 // setTitle(m_aDocumentNamePart);
445 m_pIOleIPSite
->DiscardUndoState();
447 catch( const uno::Exception
& )
456 void DocumentHolder::InPlaceDeactivate(void)
458 m_bOnDeactivate
= true;
461 if(m_xFrame
.is()) m_xFrame
->deactivate();
463 if(m_xEditWindow
.is()) {
464 m_xEditWindow
->setVisible(false);
465 ShowWindow(m_hWndxWinParent
,SW_HIDE
);
466 SetParent(m_hWndxWinParent
,0);
469 if(m_xContainerWindow
.is()) {
470 m_xContainerWindow
->setVisible(false);
471 ShowWindow(m_hWndxWinCont
,SW_HIDE
);
472 SetParent(m_hWndxWinCont
,0);
475 // TODO/cd: Workaround for status indicator bug. It always makes the
476 // document window visible, when someone tries to use the status
477 // indicator. As we save our document when we get the deactivation
478 // from OLE this conflict to hide floating windows.
479 if (m_xLayoutManager
.is())
480 m_xLayoutManager
->setVisible(false);
482 if (NULL
!=m_pIOleIPSite
)
483 m_pIOleIPSite
->OnInPlaceDeactivate();
485 if(m_pIOleIPFrame
) m_pIOleIPFrame
->Release(); m_pIOleIPFrame
= 0;
486 if(m_pIOleIPUIWindow
) m_pIOleIPUIWindow
->Release(); m_pIOleIPUIWindow
= 0;
487 if(m_pIOleIPSite
) m_pIOleIPSite
->Release(); m_pIOleIPSite
= 0;
489 if ( m_xOleAccess
.is() )
491 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
492 if ( aDocLock
.GetEmbedDocument() )
494 aDocLock
.GetEmbedDocument()->SaveObject();
502 HRESULT
DocumentHolder::UIActivate()
504 // 1. Call IOleInPlaceSite::UIActivate
505 if (NULL
!=m_pIOleIPSite
)
506 m_pIOleIPSite
->OnUIActivate();
508 //2. Critical for accelerators to work initially.
509 SetFocus(m_pCHatchWin
->Window());
510 // if(m_xEditWindow.is()) m_xEditWindow->setFocus();
512 //3. Set the active object
514 OLECHAR starOffice
[] = {'S','t','a','r','O','f','f','i','c','e',0};
515 CComPtr
< IOleInPlaceActiveObject
> pObj
= new CIIAObj( this );
517 if (NULL
!=m_pIOleIPFrame
)
518 m_pIOleIPFrame
->SetActiveObject(
521 if (NULL
!=m_pIOleIPUIWindow
)
522 m_pIOleIPUIWindow
->SetActiveObject(
525 //4. Create the shared menu.
531 void DocumentHolder::UIDeactivate()
533 //1. Remove the shared menu.
534 InPlaceMenuDestroy();
536 if (NULL
!=m_pIOleIPFrame
)
537 m_pIOleIPFrame
->SetActiveObject(NULL
, NULL
);
539 if (NULL
!=m_pIOleIPUIWindow
)
540 m_pIOleIPUIWindow
->SetActiveObject(NULL
, NULL
);
542 //3. Call IOleInPlaceSite::OnUIDeactivate
543 if (NULL
!=m_pIOleIPSite
)
544 m_pIOleIPSite
->OnUIDeactivate(FALSE
);
549 void CopyToOLEMenu(HMENU hOrig
,WORD origPos
,HMENU hDest
,WORD destPos
)
552 UINT uTemp
= MF_BYPOSITION
| MF_POPUP
;
555 subMenu
= GetSubMenu(hOrig
,origPos
);
556 GetMenuString(hOrig
,origPos
,buffer
,256,MF_BYPOSITION
);
557 InsertMenu(hDest
,destPos
,uTemp
,
558 (UINT
)subMenu
,LPCTSTR(buffer
));
561 memset(&mi
,0,sizeof(mi
));
562 mi
.cbSize
= sizeof(mi
);
563 mi
.fMask
= MIIM_DATA
;
564 if(GetMenuItemInfoW(hOrig
,origPos
,TRUE
,&mi
))
565 SetMenuItemInfoW(hDest
,(WORD
)destPos
,TRUE
,&mi
);
568 BOOL
DocumentHolder::InPlaceMenuCreate(void)
572 OLEMENUGROUPWIDTHS mgw
;
577 //We already have popup menu handles in m_pFR->m_phMenu[]
579 //Create the new shared menu and let container do its thing
581 m_pIOleIPFrame
->InsertMenus(hMenu
,&mgw
);
583 int count
= GetMenuItemCount(m_nMenuHandle
);
586 // start with 1, because we don't include "File"
587 WORD pos
= (WORD
)mgw
.width
[0];
588 CopyToOLEMenu(m_nMenuHandle
,1,hMenu
,pos
);
591 // insert object menu here
592 pos
= ((WORD
)(mgw
.width
[0] + mgw
.width
[1] + mgw
.width
[2]));
593 for(WORD i
= 2; i
< help
-1; ++i
,++pos
)
594 CopyToOLEMenu(m_nMenuHandle
,i
,hMenu
,pos
);
595 mgw
.width
[3] = help
- 3;
598 pos
= (WORD
)(mgw
.width
[0] + mgw
.width
[1] + mgw
.width
[2] +
599 mgw
.width
[3] + mgw
.width
[4]);
600 CopyToOLEMenu(m_nMenuHandle
,WORD(help
),hMenu
,pos
);
603 m_nMenuShared
= hMenu
;
604 m_nOLEMenu
= OleCreateMenuDescriptor(m_nMenuShared
,&mgw
);
606 uno::Reference
<awt::XSystemDependentWindowPeer
> xSysDepWin(m_xContainerWindow
,uno::UNO_QUERY
);
607 if(xSysDepWin
.is()) {
608 uno::Sequence
<sal_Int8
> aProcessIdent(16);
609 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
610 uno::Any aAny
= xSysDepWin
->getWindowHandle(aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
613 HWND aHwnd
= (HWND
) tmp
;
614 m_pIOleIPFrame
->SetMenu(
615 m_nMenuShared
,m_nOLEMenu
,aHwnd
);
618 m_pIOleIPFrame
->SetMenu(
619 m_nMenuShared
,m_nOLEMenu
,::GetWindow(m_hWndxWinParent
,GW_CHILD
));
623 BOOL
DocumentHolder::InPlaceMenuDestroy(void)
625 if( NULL
== m_nMenuShared
)
628 m_pIOleIPFrame
->SetMenu(NULL
,NULL
,NULL
);
630 OleDestroyMenuDescriptor(m_nOLEMenu
),m_nOLEMenu
= NULL
;
634 void DocumentHolder::OpenIntoWindow(void)
639 BOOL
DocumentHolder::Undo(void)
646 void DocumentHolder::FreeOffice()
648 const ::rtl::OUString
aServiceName(
649 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
650 uno::Reference
< frame::XDesktop
> xDesktop(
651 m_xFactory
->createInstance( aServiceName
), uno::UNO_QUERY
);
654 xDesktop
->removeTerminateListener(
655 (frame::XTerminateListener
*)this );
659 void DocumentHolder::DisconnectFrameDocument( sal_Bool bComplete
)
663 uno::Reference
< util::XModifyBroadcaster
> xModifiable( m_xDocument
, uno::UNO_QUERY_THROW
);
664 xModifiable
->removeModifyListener( (util::XModifyListener
*)this );
666 catch( const uno::Exception
& )
671 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
672 m_xDocument
, uno::UNO_QUERY_THROW
);
673 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
675 catch( const uno::Exception
& )
680 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
681 m_xFrame
, uno::UNO_QUERY_THROW
);
682 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
684 catch( const uno::Exception
& )
689 m_xFrame
= uno::Reference
< frame::XFrame
>();
691 m_xDocument
= uno::Reference
< frame::XModel
>();
695 void DocumentHolder::CloseDocument()
697 DisconnectFrameDocument();
699 uno::Reference
< util::XCloseable
> xCloseable(
700 m_xDocument
, uno::UNO_QUERY
);
702 if ( xCloseable
.is() )
706 xCloseable
->close( sal_True
);
708 catch( const uno::Exception
& )
713 m_xDocument
= uno::Reference
< frame::XModel
>();
717 void DocumentHolder::CloseFrame()
721 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
722 m_xFrame
, uno::UNO_QUERY_THROW
);
723 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
725 catch( const uno::Exception
& )
728 uno::Reference
<util::XCloseable
> xCloseable(
729 m_xFrame
,uno::UNO_QUERY
);
732 xCloseable
->close(sal_True
);
734 catch( const uno::Exception
& ) {
737 uno::Reference
<lang::XComponent
> xComp(m_xFrame
,uno::UNO_QUERY
);
742 m_xFrame
= uno::Reference
< frame::XFrame
>();
745 void DocumentHolder::SetDocument( const uno::Reference
< frame::XModel
>& xDoc
, sal_Bool bLink
)
747 if ( m_xDocument
.is() )
753 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
754 m_xDocument
, uno::UNO_QUERY
);
756 if ( xBroadcaster
.is() )
757 xBroadcaster
->addCloseListener( (util::XCloseListener
*)this );
759 if ( m_xDocument
.is() && !m_bLink
)
761 // set the document mode to embedded
762 uno::Sequence
< beans::PropertyValue
> aSeq(1);
763 aSeq
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "SetEmbedded" ));
764 aSeq
[0].Value
<<= sal_True
;
765 m_xDocument
->attachResource(::rtl::OUString(),aSeq
);
769 sal_Bool
DocumentHolder::ExecuteSuspendCloseFrame()
771 if ( m_xFrame
.is() && m_xFactory
.is() )
775 uno::Reference
< frame::XController
> xController
= m_xFrame
->getController();
776 if ( xController
.is() )
778 if ( !xController
->suspend( sal_True
) )
784 uno::Reference
<util::XCloseable
> xCloseable( m_xFrame
, uno::UNO_QUERY
);
785 if ( xCloseable
.is() )
786 xCloseable
->close(sal_True
);
789 uno::Reference
<lang::XComponent
> xComp( m_xFrame
, uno::UNO_QUERY_THROW
);
794 catch( const util::CloseVetoException
& )
796 // should be called if the frame could not be closed
797 xController
->suspend( sal_False
);
801 catch( uno::Exception
& )
805 m_xFrame
= uno::Reference
< frame::XFrame
>();
811 uno::Reference
< frame::XFrame
> DocumentHolder::DocumentFrame()
815 rtl::OUString
aDesktopSrvNm(
816 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"));
818 uno::Reference
<frame::XDesktop
> xDesktop(
819 m_xFactory
->createInstance(aDesktopSrvNm
),
822 uno::Reference
<frame::XFrame
> xFrame(
823 xDesktop
,uno::UNO_QUERY
);
825 // the frame will be registered on desktop here, later when the document
826 // is loaded into the frame in ::show() method the terminate listener will be removed
827 // this is so only for outplace activation
829 m_xFrame
= xFrame
->findFrame(
830 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")),0);
832 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
833 m_xFrame
, uno::UNO_QUERY
);
835 if ( xBroadcaster
.is() )
837 xBroadcaster
->addCloseListener( (util::XCloseListener
*)this );
838 FreeOffice(); // the frame is part of the desktop
845 uno::Reference
<frame::XDispatchProviderInterception
>
846 xDPI(m_xFrame
,uno::UNO_QUERY
);
848 xDPI
->registerDispatchProviderInterceptor( CreateNewInterceptor() );
855 uno::Reference
< frame::XDispatchProviderInterceptor
> DocumentHolder::CreateNewInterceptor()
857 ::osl::MutexGuard
aGuard( m_aMutex
);
859 ClearInterceptorInternally();
861 uno::Reference
< frame::XDispatchProviderInterceptor
> xInterceptor( m_pInterceptor
= new Interceptor( m_xOleAccess
, this, m_bLink
) );
862 m_xInterceptorLocker
= xInterceptor
;
866 void DocumentHolder::ClearInterceptorInternally()
868 ::osl::MutexGuard
aGuard( m_aMutex
);
869 uno::Reference
< frame::XDispatchProviderInterceptor
> xInterceptor( m_xInterceptorLocker
);
870 if ( xInterceptor
.is() && m_pInterceptor
)
871 m_pInterceptor
->DisconnectDocHolder();
873 m_xInterceptorLocker
= uno::Reference
< frame::XDispatchProviderInterceptor
>();
877 void DocumentHolder::ClearInterceptor()
879 ::osl::MutexGuard
aGuard( m_aMutex
);
880 m_xInterceptorLocker
= uno::Reference
< frame::XDispatchProviderInterceptor
>();
885 void DocumentHolder::show()
891 m_xFrame
->activate();
892 uno::Reference
<awt::XTopWindow
> xTopWindow(
893 m_xFrame
->getContainerWindow(),uno::UNO_QUERY
);
895 xTopWindow
->toFront();
897 else if( DocumentFrame().is() )
899 LoadDocInFrame( sal_False
);
901 // get rid of second closer if it is there
902 uno::Reference
< beans::XPropertySet
> xProps( m_xFrame
, uno::UNO_QUERY
);
905 uno::Reference
< frame::XLayoutManager
> xLayoutManager
;
906 xProps
->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )) ) >>= xLayoutManager
;
907 uno::Reference
< beans::XPropertySet
> xLMProps( xLayoutManager
, uno::UNO_QUERY
);
910 xLMProps
->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MenuBarCloser" )),
911 uno::makeAny( uno::Reference
< frame::XStatusListener
>() ) );
919 uno::Reference
< util::XModifyBroadcaster
> xModifiable( m_xDocument
, uno::UNO_QUERY_THROW
);
920 xModifiable
->addModifyListener( (util::XModifyListener
*)this );
922 catch( const uno::Exception
& )
927 setTitle(m_aDocumentNamePart
);
930 catch( const uno::Exception
& )
932 OSL_FAIL( "Can not show the frame!\n" );
937 void DocumentHolder::resizeWin( const SIZEL
& rNewSize
)
939 LockedEmbedDocument_Impl aDocLock
;
941 if ( m_xOleAccess
.is() )
942 aDocLock
= m_xOleAccess
->GetEmbedDocument();
944 if ( m_xFrame
.is() && aDocLock
.GetEmbedDocument() )
946 uno::Reference
< awt::XWindow
> xWindow(
947 m_xFrame
->getContainerWindow(), uno::UNO_QUERY
);
948 uno::Reference
< awt::XView
> xView( xWindow
, uno::UNO_QUERY
);
950 if ( xWindow
.is() && xView
.is() )
953 xView
->setZoom( fScale
, fScale
);
956 GetExtent( &aOldSize
);
958 if ( aOldSize
.cx
!= rNewSize
.cx
|| aOldSize
.cy
!= rNewSize
.cy
)
960 HDC hdc
= GetDC( NULL
);
961 SetMapMode( hdc
, MM_HIMETRIC
);
964 aOldOffset
.x
= aOldSize
.cx
;
965 aOldOffset
.y
= aOldSize
.cy
;
966 BOOL bIsOk
= LPtoDP( hdc
, &aOldOffset
, 1 );
969 aNewOffset
.x
= rNewSize
.cx
;
970 aNewOffset
.y
= rNewSize
.cy
;
971 bIsOk
= LPtoDP( hdc
, &aNewOffset
, 1 );
973 ReleaseDC( NULL
, hdc
);
975 awt::Rectangle aWinRect
= xWindow
->getPosSize();
977 sal_Int32 aWidthDelta
= aWinRect
.Width
- aOldOffset
.x
;
978 sal_Int32 aHeightDelta
= aWinRect
.Height
- aOldOffset
.y
;
980 if ( aWidthDelta
> 0 && aHeightDelta
> 0 )
981 xWindow
->setPosSize(0,
983 aNewOffset
.x
+ aWidthDelta
,
984 aNewOffset
.y
+ aHeightDelta
,
985 awt::PosSize::SIZE
);
991 void DocumentHolder::setTitle(const rtl::OUString
& aDocumentName
)
995 if(m_aFilterName
.getLength() == 0)
997 rtl::OUString aFilterName
;
998 uno::Sequence
<beans::PropertyValue
> aSeq
;
1002 m_xDocument
->getArgs();
1003 for(sal_Int32 j
= 0; j
< aSeq
.getLength(); ++j
)
1007 RTL_CONSTASCII_USTRINGPARAM("FilterName")))
1009 aSeq
[j
].Value
>>= aFilterName
;
1015 if(aFilterName
.getLength())
1017 uno::Reference
<container::XNameAccess
> xNameAccess(
1018 m_xFactory
->createInstance(
1019 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1020 "com.sun.star.document.FilterFactory"))),
1023 if(xNameAccess
.is() &&
1024 (xNameAccess
->getByName(aFilterName
) >>= aSeq
))
1026 for(sal_Int32 j
= 0; j
< aSeq
.getLength(); ++j
)
1029 RTL_CONSTASCII_USTRINGPARAM("UIName")))
1031 aSeq
[j
].Value
>>= m_aFilterName
;
1036 catch(const uno::Exception
& ) {
1037 // nothing better to do here
1038 m_aFilterName
= aFilterName
;
1043 uno::Reference
<beans::XPropertySet
> xPropSet(
1044 m_xFrame
,uno::UNO_QUERY
);
1047 static const sal_Unicode u
[] = { ' ','(',0 };
1048 static const sal_Unicode c
[] = { ')',0 };
1049 rtl::OUString
aTotalName(m_aFilterName
);
1050 aTotalName
+= rtl::OUString(u
);
1051 aTotalName
+= aDocumentName
;
1052 aTotalName
+= rtl::OUString(c
);
1053 aAny
<<= aTotalName
;
1055 xPropSet
->setPropertyValue(
1056 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")),
1059 catch( const uno::Exception
& ) {
1064 m_aDocumentNamePart
= aDocumentName
;
1068 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1070 Interceptor
* pTmpInter
= NULL
;
1071 uno::Reference
< frame::XDispatchProviderInterceptor
> xLock( m_xInterceptorLocker
);
1072 if ( xLock
.is() && m_pInterceptor
)
1073 pTmpInter
= m_pInterceptor
;
1078 pTmpInter
->generateFeatureStateEvent();
1083 void DocumentHolder::setContainerName(const rtl::OUString
& aContainerName
)
1085 m_aContainerName
= aContainerName
;
1089 void DocumentHolder::hide()
1091 if(m_xFrame
.is()) m_xFrame
->deactivate();
1094 // after hiding the window it is always allowed to InPlaceActivate it
1095 m_bAllowInPlace
= true;
1098 IDispatch
* DocumentHolder::GetIDispatch()
1100 if ( !m_pIDispatch
&& m_xDocument
.is() )
1102 const ::rtl::OUString
aServiceName (
1103 RTL_CONSTASCII_USTRINGPARAM (
1104 "com.sun.star.bridge.OleBridgeSupplier2" ) );
1105 uno::Reference
< bridge::XBridgeSupplier2
> xSupplier(
1106 m_xFactory
->createInstance( aServiceName
), uno::UNO_QUERY
);
1108 if ( xSupplier
.is() )
1110 uno::Sequence
< sal_Int8
> aProcId( 16 );
1111 rtl_getGlobalProcessId( (sal_uInt8
*)aProcId
.getArray() );
1114 uno::Any anyResult
= xSupplier
->createBridge(
1115 uno::makeAny( m_xDocument
),
1117 bridge::ModelDependent::UNO
,
1118 bridge::ModelDependent::OLE
);
1120 if ( anyResult
.getValueTypeClass() ==
1121 getCppuType((sal_uInt32
*) 0).getTypeClass() )
1123 VARIANT
* pVariant
= *(VARIANT
**)anyResult
.getValue();
1124 if ( pVariant
->vt
== VT_DISPATCH
)
1125 m_pIDispatch
= pVariant
->pdispVal
;
1127 VariantClear( pVariant
);
1128 CoTaskMemFree( pVariant
);
1131 catch ( const uno::Exception
& )
1136 return m_pIDispatch
;
1139 HRESULT
DocumentHolder::GetDocumentBorder( RECT
*pRect
)
1141 if ( pRect
&& m_xDocument
.is() )
1143 uno::Sequence
< beans::PropertyValue
> aArgs
= m_xDocument
->getArgs();
1144 for ( sal_Int32 nInd
= 0; nInd
< aArgs
.getLength(); nInd
++ )
1145 if ( aArgs
[nInd
].Name
== "DocumentBorder" )
1147 uno::Sequence
< sal_Int32
> aRect
;
1148 if ( ( aArgs
[nInd
].Value
>>= aRect
) && aRect
.getLength() == 4 )
1150 pRect
->left
= aRect
[0];
1151 pRect
->top
= aRect
[1];
1152 pRect
->right
= aRect
[2];
1153 pRect
->bottom
= aRect
[3];
1165 HRESULT
DocumentHolder::SetExtent( const SIZEL
*pSize
)
1169 uno::Reference
< embed::XVisualObject
> xVisObj( m_xDocument
, uno::UNO_QUERY
);
1174 awt::Size
aNewSize( pSize
->cx
, pSize
->cy
);
1176 sal_Int32 aMapMode
= xVisObj
->getMapUnit( DVASPECT_CONTENT
);
1178 // TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1179 if ( aMapMode
== embed::EmbedMapUnits::TWIP
)
1181 // convertion from ONE_100TH_MM
1182 aNewSize
.Width
= aNewSize
.Width
* 144 / 254;
1183 aNewSize
.Height
= aNewSize
.Height
* 144 / 254;
1187 xVisObj
->setVisualAreaSize( DVASPECT_CONTENT
, aNewSize
);
1191 catch( const uno::Exception
& )
1199 HRESULT
DocumentHolder::GetExtent( SIZEL
*pSize
)
1203 uno::Reference
< embed::XVisualObject
> xVisObj( m_xDocument
, uno::UNO_QUERY
);
1208 awt::Size aDocSize
= xVisObj
->getVisualAreaSize( DVASPECT_CONTENT
);
1210 sal_Int32 aMapMode
= xVisObj
->getMapUnit( DVASPECT_CONTENT
);
1212 // TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1213 if ( aMapMode
== embed::EmbedMapUnits::TWIP
)
1215 // convertion to ONE_100TH_MM
1216 aDocSize
.Width
= aDocSize
.Width
* 254 / 144;
1217 aDocSize
.Height
= aDocSize
.Height
* 254 / 144;
1220 pSize
->cx
= aDocSize
.Width
;
1221 pSize
->cy
= aDocSize
.Height
;
1225 catch( const uno::Exception
& )
1234 HRESULT
DocumentHolder::SetContRects(LPCRECT aRect
)
1236 if(m_xContainerWindow
.is()) {
1238 memset(&wi
,0,sizeof(wi
));
1239 if(m_pIOleIPFrame
) {
1240 m_pIOleIPFrame
->GetBorder((LPRECT
)&wi
);
1241 m_xContainerWindow
->setPosSize(
1245 awt::PosSize::POSSIZE
);
1248 m_xContainerWindow
->setPosSize(
1250 aRect
->right
- aRect
->left
,
1251 aRect
->bottom
- aRect
->top
,
1252 awt::PosSize::POSSIZE
);
1261 HRESULT
DocumentHolder::SetObjectRects(LPCRECT aRect
, LPCRECT aClip
)
1263 ((LPRECT
)aRect
)->left
-= m_aBorder
.left
;
1264 ((LPRECT
)aRect
)->right
+= m_aBorder
.right
;
1265 ((LPRECT
)aRect
)->top
-= m_aBorder
.top
;
1266 ((LPRECT
)aRect
)->bottom
+= m_aBorder
.bottom
;
1267 ((LPRECT
)aClip
)->left
-= m_aBorder
.left
;
1268 ((LPRECT
)aClip
)->right
+= m_aBorder
.right
;
1269 ((LPRECT
)aClip
)->top
-= m_aBorder
.top
;
1270 ((LPRECT
)aClip
)->bottom
+= m_aBorder
.bottom
;
1273 m_pCHatchWin
->RectsSet((LPRECT
)aRect
, (LPRECT
)aClip
);
1274 if(m_xEditWindow
.is()) {
1275 m_xEditWindow
->setVisible(false);
1276 m_xEditWindow
->setPosSize(
1277 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
1278 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
1279 aRect
->right
- aRect
->left
,
1280 aRect
->bottom
- aRect
->top
,
1281 awt::PosSize::POSSIZE
);
1282 m_xEditWindow
->setVisible(true);
1288 ::com::sun::star::uno::Reference
<
1289 ::com::sun::star::awt::XWindow
> SAL_CALL
1290 DocumentHolder::getContainerWindow(
1293 ::com::sun::star::uno::RuntimeException
1296 if(m_xContainerWindow
.is())
1297 return m_xContainerWindow
;
1299 uno::Reference
<awt::XWindow
> xWin(0);
1301 uno::Reference
<awt::XToolkit2
> xToolkit
= awt::Toolkit::create( comphelper::getComponentContext(m_xFactory
) );
1303 if(m_pIOleIPFrame
) {
1305 m_pIOleIPFrame
->GetWindow(&hWnd
);
1307 uno::Sequence
<sal_Int8
> aProcessIdent(16);
1308 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
1311 aAny
<<= sal_Int32(hWnd
);
1312 xWin
= uno::Reference
<awt::XWindow
>(
1313 xToolkit
->createSystemChild(
1316 lang::SystemDependent::SYSTEM_WIN32
),
1320 memset(&wi
,0,sizeof(wi
));
1321 if(xWin
.is() && m_pIOleIPFrame
->GetBorder((LPRECT
)&wi
) == NOERROR
) {
1322 xWin
->setVisible(true);
1327 awt::PosSize::POSSIZE
);
1329 uno::Reference
<awt::XSystemDependentWindowPeer
> xSysWin(
1330 xWin
,uno::UNO_QUERY
);
1332 aAny
= xSysWin
->getWindowHandle(
1333 aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
1336 SetContainerWindowHandle((HWND
) tmp
);
1341 m_xContainerWindow
= xWin
;
1348 DocumentHolder::requestDockingAreaSpace(
1349 const ::com::sun::star::awt::Rectangle
& RequestedSpace
1352 ::com::sun::star::uno::RuntimeException
1359 SetRect((LPRECT
)&bw
,
1360 RequestedSpace
.X
,RequestedSpace
.Y
,
1361 RequestedSpace
.Width
,RequestedSpace
.Height
);
1362 if( m_pIOleIPFrame
)
1363 return m_pIOleIPFrame
->RequestBorderSpace(&bw
) == NOERROR
;
1365 return sal_Bool(false);
1370 DocumentHolder::setDockingAreaSpace(
1371 const ::com::sun::star::awt::Rectangle
& BorderSpace
1374 ::com::sun::star::uno::RuntimeException
1381 SetRect((LPRECT
)&bw
,
1382 BorderSpace
.X
,BorderSpace
.Y
,
1383 BorderSpace
.Width
,BorderSpace
.Height
);
1384 if( m_pIOleIPFrame
) {
1386 GetClientRect(m_hWndxWinCont
,&aRect
);
1387 HRGN hrgn1
= CreateRectRgn(
1389 aRect
.right
,BorderSpace
.Y
);
1390 HRGN hrgn2
= CreateRectRgn(aRect
.right
-BorderSpace
.Width
,0,aRect
.right
,aRect
.bottom
);
1391 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1392 DeleteObject(hrgn2
);
1393 hrgn2
= CreateRectRgn(0,aRect
.bottom
-BorderSpace
.Height
,aRect
.right
,aRect
.bottom
);
1394 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1395 DeleteObject(hrgn2
);
1396 hrgn2
= CreateRectRgn(0,0,BorderSpace
.X
,aRect
.bottom
);
1397 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1398 DeleteObject(hrgn2
);
1400 SetWindowRgn(m_hWndxWinCont
,hrgn1
,true);
1401 // not:: DeleteObject(hrgn1);
1402 m_pIOleIPFrame
->SetBorderSpace(&bw
);
1408 DocumentHolder::disposing(
1409 const com::sun::star::lang::EventObject
& aSource
1411 throw( uno::RuntimeException
)
1413 if ( m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1415 m_pIDispatch
= NULL
;
1416 m_xDocument
= uno::Reference
< frame::XModel
>();
1419 if( m_xFrame
.is() && m_xFrame
== aSource
.Source
)
1420 m_xFrame
= uno::Reference
< frame::XFrame
>();
1425 DocumentHolder::queryClosing(
1426 const lang::EventObject
& aSource
,
1427 sal_Bool
/*bGetsOwnership*/
1430 util::CloseVetoException
1434 && ( m_xDocument
.is() && m_xDocument
== aSource
.Source
|| m_xFrame
.is() && m_xFrame
== aSource
.Source
) )
1435 throw util::CloseVetoException();
1440 DocumentHolder::notifyClosing(
1441 const lang::EventObject
& aSource
)
1442 throw( uno::RuntimeException
)
1446 uno::Reference
< util::XCloseBroadcaster
> xEventBroadcaster(
1447 aSource
.Source
, uno::UNO_QUERY_THROW
);
1448 xEventBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
1450 catch( const uno::Exception
& )
1453 if ( m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1455 // can happen only in case of links
1456 m_pIDispatch
= NULL
;
1457 m_xDocument
= uno::Reference
< frame::XModel
>();
1458 m_xFrame
= uno::Reference
< frame::XFrame
>();
1460 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
1461 if ( aDocLock
.GetEmbedDocument() )
1462 aDocLock
.GetEmbedDocument()->OLENotifyClosing();
1464 else if( m_xFrame
.is() && m_xFrame
== aSource
.Source
)
1465 m_xFrame
= uno::Reference
< frame::XFrame
>();
1469 DocumentHolder::queryTermination(
1470 const lang::EventObject
& /*aSource*/
1473 frame::TerminationVetoException
1476 if ( m_xDocument
.is() )
1477 throw frame::TerminationVetoException();
1481 DocumentHolder::notifyTermination(
1482 const lang::EventObject
& aSource
1484 throw( uno::RuntimeException
)
1486 OSL_ENSURE( !m_xDocument
.is(), "Just a disaster..." );
1487 uno::Reference
< frame::XDesktop
> xDesktop(
1488 aSource
.Source
, uno::UNO_QUERY
);
1490 if ( xDesktop
.is() )
1491 xDesktop
->removeTerminateListener( (frame::XTerminateListener
*)this );
1496 void SAL_CALL
DocumentHolder::modified( const lang::EventObject
& /*aEvent*/ )
1497 throw (uno::RuntimeException
)
1499 if ( m_xOleAccess
.is() )
1501 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
1502 if ( aDocLock
.GetEmbedDocument() )
1503 aDocLock
.GetEmbedDocument()->notify();
1507 // Fix strange warnings about some
1508 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
1509 // warning C4505: 'xxx' : unreferenced local function has been removed
1511 #pragma warning(disable: 4505)
1514 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */