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) );
118 uno::Sequence
<beans::PropertyValue
> aSeq( nLen
);
120 aSeq
[0] = beans::PropertyValue(
123 uno::Any(uno::Reference
<uno::XInterface
>(m_xDocument
, uno::UNO_QUERY
)),
124 beans::PropertyState_DIRECT_VALUE
);
126 aSeq
[1] = beans::PropertyValue(
127 OUString("ReadOnly"),
130 beans::PropertyState_DIRECT_VALUE
);
132 aSeq
[2] = beans::PropertyValue(
133 OUString("NoAutoSave"),
136 beans::PropertyState_DIRECT_VALUE
);
140 aSeq
.realloc( ++nLen
);
141 aSeq
[nLen
-1] = beans::PropertyValue(
142 OUString("PluginMode"),
144 uno::Any((sal_Int16
) 3),
145 beans::PropertyState_DIRECT_VALUE
);
148 aSeq
.realloc( nLen
+=2 );
149 aSeq
[nLen
-2] = beans::PropertyValue(
150 OUString("InteractionHandler"),
153 beans::PropertyState_DIRECT_VALUE
);
155 aSeq
[nLen
-1] = beans::PropertyValue(
156 OUString("MacroExecutionMode"),
158 uno::Any(m_nMacroExecMode
),
159 beans::PropertyState_DIRECT_VALUE
);
161 xComponentLoader
->loadComponentFromURL(
162 OUString("private:object"),
167 uno::Sequence
< beans::PropertyValue
> aResArgs
= m_xDocument
->getArgs();
168 for ( int nInd
= 0; nInd
< aResArgs
.getLength(); nInd
++ )
169 if ( aResArgs
[nInd
].Name
== "MacroExecutionMode" )
171 aResArgs
[nInd
].Value
>>= m_nMacroExecMode
;
177 void DocumentHolder::OnPosRectChanged(LPRECT lpRect
) const
179 lpRect
->left
+= m_aBorder
.left
;
180 lpRect
->right
-= m_aBorder
.right
;
181 lpRect
->top
+= m_aBorder
.top
;
182 lpRect
->bottom
-= m_aBorder
.bottom
;
184 m_pIOleIPSite
->OnPosRectChange(lpRect
);
188 void DocumentHolder::DisableInplaceActivation(BOOL b
)
190 m_bAllowInPlace
= ! b
;
193 BOOL
DocumentHolder::isActive() const
195 return m_pIOleIPSite
!= 0;
198 HRESULT
DocumentHolder::InPlaceActivate(
199 LPOLECLIENTSITE pActiveSite
,
202 m_bOnDeactivate
= false;
211 OLEINPLACEFRAMEINFO frameInfo
;
213 if (NULL
==pActiveSite
)
214 return ResultFromScode(E_INVALIDARG
);
216 if (NULL
!=m_pIOleIPSite
)
224 if ( !m_xDocument
.is() )
227 //1. Initialization, obtaining interfaces, OnInPlaceActivate.
228 hr
=pActiveSite
->QueryInterface(
230 (void**) &m_pIOleIPSite
);
235 hr
=m_pIOleIPSite
->CanInPlaceActivate();
239 m_pIOleIPSite
->Release(), m_pIOleIPSite
=NULL
;
240 return ResultFromScode(E_FAIL
);
243 m_pIOleIPSite
->OnInPlaceActivate();
245 //2. Get the site window
246 //3. and determine container frame and
247 // document window for tools and menus, as well
248 // as frameInfo for accelerators
249 m_pIOleIPSite
->GetWindow(&hWndSite
);
251 frameInfo
.cb
=sizeof(OLEINPLACEFRAMEINFO
);
252 m_pIOleIPSite
->GetWindowContext(
253 &m_pIOleIPFrame
,&m_pIOleIPUIWindow
,&rcPos
,&rcClip
,&frameInfo
);
255 // initialize the office as, with hwnd as parentwindow
257 uno::Sequence
<sal_Int8
> aProcessIdent(16);
258 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
262 if(!m_xEditWindow
.is())
263 { // determine XWindow and window handle of parent
264 HWND
hWndxWinParent(0);
265 uno::Reference
<awt::XWindow
> xWin
;
267 uno::Reference
<awt::XToolkit2
> xToolkit
=
268 awt::Toolkit::create(comphelper::getComponentContext(m_xFactory
));
270 // create system window wrapper for hwnd
272 m_pCHatchWin
= new winwrap::CHatchWin(
275 if(m_pCHatchWin
->Init(hWndSite
,/*ID_HATCHWINDOW*/2000, NULL
)) {
276 m_pCHatchWin
->RectsSet(&rcPos
,&rcClip
); //set visible area
277 hWndxWinParent
= m_pCHatchWin
->Window();
278 ShowWindow(hWndxWinParent
,SW_SHOW
); //Make visible.
281 // no success initializing hatch window
282 delete m_pCHatchWin
, m_pCHatchWin
= 0;
283 hWndxWinParent
= hWndSite
;
287 xToolkit
->createSystemChild(
288 uno::Any(sal_Int32(hWndxWinParent
)),
290 lang::SystemDependent::SYSTEM_WIN32
),
295 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
296 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
297 rcPos
.right
-rcPos
.left
,
298 rcPos
.bottom
- rcPos
.top
,
299 awt::PosSize::POSSIZE
);
300 xWin
->setVisible(sal_True
);
302 m_xEditWindow
= xWin
;
303 m_hWndxWinParent
= hWndxWinParent
;
309 if(m_hWndxWinParent
) {
310 SetParent(m_hWndxWinParent
,hWndSite
);
311 ShowWindow(m_hWndxWinParent
,SW_SHOW
); //Make visible.
314 if ( !m_xFrame
.is() )
315 // initially set size to "empty", this guarantees that the final resize
316 // is always executed (will be done by "SetObjectRects" after getting internal border)
317 m_xEditWindow
->setPosSize(
322 awt::PosSize::POSSIZE
);
323 m_xEditWindow
->setVisible(sal_True
);
326 if(m_xContainerWindow
.is()) {
330 m_pIOleIPFrame
->GetWindow(&hWndCont
);
331 SetParent(m_hWndxWinCont
,hWndCont
);
332 ShowWindow(m_hWndxWinCont
,SW_SHOW
);
335 m_xContainerWindow
->setVisible(true);
339 m_xFrame
->activate();
341 // create frame and initialize it with the created window
342 m_xFrame
= frame::Frame::create( comphelper::getComponentContext(m_xFactory
) );
343 m_xFrame
->initialize(m_xEditWindow
);
345 m_xFrame
->registerDispatchProviderInterceptor( CreateNewInterceptor() );
347 m_xLayoutManager
.set( m_xFrame
->getLayoutManager(), uno::UNO_QUERY
);
349 if(m_xLayoutManager
.is())
350 m_xLayoutManager
->setDockingAreaAcceptor(this);
352 // load the model into the frame
353 LoadDocInFrame( sal_True
);
355 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
356 xDesktop
->getFrames()->append(m_xFrame
);
358 // determine the menuhandle to get menuitems.
359 if(m_xLayoutManager
.is()) {
360 uno::Reference
< css::ui::XUIElement
> xUIEl(
361 m_xLayoutManager
->getElement(
363 "private:resource/menubar/menubar")));
364 OSL_ENSURE(xUIEl
.is(),"no menubar");
365 uno::Reference
<awt::XSystemDependentMenuPeer
> xSDMP(
366 xUIEl
->getRealInterface(),
368 aAny
= xSDMP
->getMenuHandle(
369 aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
372 m_nMenuHandle
= HMENU(tmp
);
373 m_xLayoutManager
->hideElement(
375 "private:resource/menubar/menubar" ));
379 // TODO/cd: Workaround for status indicator bug. It always makes the
380 // document window visible, when someone tries to use the status
381 // indicator. As we save our document when we get the deactivation
382 // from OLE this conflict to hide floating windows.
383 if(m_xLayoutManager
.is())
384 m_xLayoutManager
->setVisible(true);
386 // get document border and resize rects according to border
387 GetDocumentBorder( &m_aBorder
);
388 SetObjectRects( &rcPos
, &rcClip
);
390 if ( m_xOleAccess
.is() )
392 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
393 if ( aDocLock
.GetEmbedDocument() )
394 aDocLock
.GetEmbedDocument()->ShowObject();
397 // setTitle(m_aDocumentNamePart);
401 m_pIOleIPSite
->DiscardUndoState();
403 catch( const uno::Exception
& )
412 void DocumentHolder::InPlaceDeactivate()
414 m_bOnDeactivate
= true;
417 if(m_xFrame
.is()) m_xFrame
->deactivate();
419 if(m_xEditWindow
.is()) {
420 m_xEditWindow
->setVisible(false);
421 ShowWindow(m_hWndxWinParent
,SW_HIDE
);
422 SetParent(m_hWndxWinParent
,0);
425 if(m_xContainerWindow
.is()) {
426 m_xContainerWindow
->setVisible(false);
427 ShowWindow(m_hWndxWinCont
,SW_HIDE
);
428 SetParent(m_hWndxWinCont
,0);
431 // TODO/cd: Workaround for status indicator bug. It always makes the
432 // document window visible, when someone tries to use the status
433 // indicator. As we save our document when we get the deactivation
434 // from OLE this conflict to hide floating windows.
435 if (m_xLayoutManager
.is())
436 m_xLayoutManager
->setVisible(false);
438 if (NULL
!=m_pIOleIPSite
)
439 m_pIOleIPSite
->OnInPlaceDeactivate();
441 if(m_pIOleIPFrame
) m_pIOleIPFrame
->Release(); m_pIOleIPFrame
= 0;
442 if(m_pIOleIPUIWindow
) m_pIOleIPUIWindow
->Release(); m_pIOleIPUIWindow
= 0;
443 if(m_pIOleIPSite
) m_pIOleIPSite
->Release(); m_pIOleIPSite
= 0;
445 if ( m_xOleAccess
.is() )
447 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
448 if ( aDocLock
.GetEmbedDocument() )
450 aDocLock
.GetEmbedDocument()->SaveObject();
458 HRESULT
DocumentHolder::UIActivate()
460 // 1. Call IOleInPlaceSite::UIActivate
461 if (NULL
!=m_pIOleIPSite
)
462 m_pIOleIPSite
->OnUIActivate();
464 //2. Critical for accelerators to work initially.
465 SetFocus(m_pCHatchWin
->Window());
466 // if(m_xEditWindow.is()) m_xEditWindow->setFocus();
468 //3. Set the active object
470 OLECHAR starOffice
[] = {'S','t','a','r','O','f','f','i','c','e',0};
471 CComPtr
< IOleInPlaceActiveObject
> pObj
= new CIIAObj( this );
473 if (NULL
!=m_pIOleIPFrame
)
474 m_pIOleIPFrame
->SetActiveObject(
477 if (NULL
!=m_pIOleIPUIWindow
)
478 m_pIOleIPUIWindow
->SetActiveObject(
481 //4. Create the shared menu.
487 void DocumentHolder::UIDeactivate()
489 //1. Remove the shared menu.
490 InPlaceMenuDestroy();
492 if (NULL
!=m_pIOleIPFrame
)
493 m_pIOleIPFrame
->SetActiveObject(NULL
, NULL
);
495 if (NULL
!=m_pIOleIPUIWindow
)
496 m_pIOleIPUIWindow
->SetActiveObject(NULL
, NULL
);
498 //3. Call IOleInPlaceSite::OnUIDeactivate
499 if (NULL
!=m_pIOleIPSite
)
500 m_pIOleIPSite
->OnUIDeactivate(FALSE
);
505 void CopyToOLEMenu(HMENU hOrig
,WORD origPos
,HMENU hDest
,WORD destPos
)
508 UINT uTemp
= MF_BYPOSITION
| MF_POPUP
;
511 subMenu
= GetSubMenu(hOrig
,origPos
);
512 GetMenuString(hOrig
,origPos
,buffer
,256,MF_BYPOSITION
);
513 InsertMenu(hDest
,destPos
,uTemp
,
514 reinterpret_cast<UINT_PTR
>(subMenu
),LPCTSTR(buffer
));
517 memset(&mi
,0,sizeof(mi
));
518 mi
.cbSize
= sizeof(mi
);
519 mi
.fMask
= MIIM_DATA
;
520 if(GetMenuItemInfoW(hOrig
,origPos
,TRUE
,&mi
))
521 SetMenuItemInfoW(hDest
,(WORD
)destPos
,TRUE
,&mi
);
524 BOOL
DocumentHolder::InPlaceMenuCreate()
527 OLEMENUGROUPWIDTHS mgw
;
529 for (UINT i
=0; i
<6; i
++)
532 //We already have popup menu handles in m_pFR->m_phMenu[]
534 //Create the new shared menu and let container do its thing
536 m_pIOleIPFrame
->InsertMenus(hMenu
,&mgw
);
538 int count
= GetMenuItemCount(m_nMenuHandle
);
541 // start with 1, because we don't include "File"
542 WORD pos
= (WORD
)mgw
.width
[0];
543 CopyToOLEMenu(m_nMenuHandle
,1,hMenu
,pos
);
546 // insert object menu here
547 pos
= ((WORD
)(mgw
.width
[0] + mgw
.width
[1] + mgw
.width
[2]));
548 for(WORD i
= 2; i
< help
-1; ++i
,++pos
)
549 CopyToOLEMenu(m_nMenuHandle
,i
,hMenu
,pos
);
550 mgw
.width
[3] = help
- 3;
553 pos
= (WORD
)(mgw
.width
[0] + mgw
.width
[1] + mgw
.width
[2] +
554 mgw
.width
[3] + mgw
.width
[4]);
555 CopyToOLEMenu(m_nMenuHandle
,WORD(help
),hMenu
,pos
);
558 m_nMenuShared
= hMenu
;
559 m_nOLEMenu
= OleCreateMenuDescriptor(m_nMenuShared
,&mgw
);
561 uno::Reference
<awt::XSystemDependentWindowPeer
> xSysDepWin(m_xContainerWindow
,uno::UNO_QUERY
);
562 if(xSysDepWin
.is()) {
563 uno::Sequence
<sal_Int8
> aProcessIdent(16);
564 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
565 uno::Any aAny
= xSysDepWin
->getWindowHandle(aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
568 HWND aHwnd
= (HWND
) tmp
;
569 m_pIOleIPFrame
->SetMenu(
570 m_nMenuShared
,m_nOLEMenu
,aHwnd
);
573 m_pIOleIPFrame
->SetMenu(
574 m_nMenuShared
,m_nOLEMenu
,::GetWindow(m_hWndxWinParent
,GW_CHILD
));
578 BOOL
DocumentHolder::InPlaceMenuDestroy()
580 if( NULL
== m_nMenuShared
)
583 m_pIOleIPFrame
->SetMenu(NULL
,NULL
,NULL
);
585 OleDestroyMenuDescriptor(m_nOLEMenu
),m_nOLEMenu
= NULL
;
589 void DocumentHolder::OpenIntoWindow()
594 BOOL
DocumentHolder::Undo()
601 void DocumentHolder::FreeOffice()
603 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
604 xDesktop
->removeTerminateListener(
605 (frame::XTerminateListener
*)this );
608 void DocumentHolder::DisconnectFrameDocument( sal_Bool bComplete
)
612 uno::Reference
< util::XModifyBroadcaster
> xModifiable( m_xDocument
, uno::UNO_QUERY_THROW
);
613 xModifiable
->removeModifyListener( (util::XModifyListener
*)this );
615 catch( const uno::Exception
& )
620 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
621 m_xDocument
, uno::UNO_QUERY_THROW
);
622 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
624 catch( const uno::Exception
& )
629 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
630 m_xFrame
, uno::UNO_QUERY_THROW
);
631 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
633 catch( const uno::Exception
& )
644 void DocumentHolder::CloseDocument()
646 DisconnectFrameDocument();
648 uno::Reference
< util::XCloseable
> xCloseable(
649 m_xDocument
, uno::UNO_QUERY
);
651 if ( xCloseable
.is() )
655 xCloseable
->close( sal_True
);
657 catch( const uno::Exception
& )
666 void DocumentHolder::CloseFrame()
670 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
671 m_xFrame
, uno::UNO_QUERY_THROW
);
672 xBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
674 catch( const uno::Exception
& )
677 uno::Reference
<util::XCloseable
> xCloseable(
678 m_xFrame
,uno::UNO_QUERY
);
681 xCloseable
->close(sal_True
);
683 catch( const uno::Exception
& ) {
686 uno::Reference
<lang::XComponent
> xComp(m_xFrame
, uno::UNO_QUERY
);
694 void DocumentHolder::SetDocument( const uno::Reference
< frame::XModel
>& xDoc
, sal_Bool bLink
)
696 if ( m_xDocument
.is() )
702 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
703 m_xDocument
, uno::UNO_QUERY
);
705 if ( xBroadcaster
.is() )
706 xBroadcaster
->addCloseListener( (util::XCloseListener
*)this );
708 if ( m_xDocument
.is() && !m_bLink
)
710 // set the document mode to embedded
711 uno::Sequence
< beans::PropertyValue
> aSeq(1);
712 aSeq
[0].Name
= "SetEmbedded";
713 aSeq
[0].Value
<<= sal_True
;
714 m_xDocument
->attachResource(OUString(),aSeq
);
718 sal_Bool
DocumentHolder::ExecuteSuspendCloseFrame()
720 if ( m_xFrame
.is() && m_xFactory
.is() )
724 uno::Reference
< frame::XController
> xController
= m_xFrame
->getController();
725 if ( xController
.is() )
727 if ( !xController
->suspend( sal_True
) )
733 uno::Reference
<util::XCloseable
> xCloseable( m_xFrame
, uno::UNO_QUERY
);
734 if ( xCloseable
.is() )
735 xCloseable
->close(sal_True
);
741 catch( const util::CloseVetoException
& )
743 // should be called if the frame could not be closed
744 xController
->suspend( sal_False
);
748 catch( uno::Exception
& )
758 uno::Reference
< frame::XFrame2
> DocumentHolder::DocumentFrame()
762 uno::Reference
<frame::XDesktop2
> xDesktop
= frame::Desktop::create(comphelper::getComponentContext(m_xFactory
));
764 uno::Reference
<frame::XFrame
> xFrame(xDesktop
,uno::UNO_QUERY
);
766 // the frame will be registered on desktop here, later when the document
767 // is loaded into the frame in ::show() method the terminate listener will be removed
768 // this is so only for outplace activation
770 m_xFrame
.set( xFrame
->findFrame( OUString("_blank"), 0 ), uno::UNO_QUERY
);
772 uno::Reference
< util::XCloseBroadcaster
> xBroadcaster(
773 m_xFrame
, uno::UNO_QUERY
);
775 if ( xBroadcaster
.is() )
777 xBroadcaster
->addCloseListener( (util::XCloseListener
*)this );
778 FreeOffice(); // the frame is part of the desktop
785 m_xFrame
->registerDispatchProviderInterceptor( CreateNewInterceptor() );
792 uno::Reference
< frame::XDispatchProviderInterceptor
> DocumentHolder::CreateNewInterceptor()
794 ::osl::MutexGuard
aGuard( m_aMutex
);
796 ClearInterceptorInternally();
798 uno::Reference
< frame::XDispatchProviderInterceptor
> xInterceptor( m_pInterceptor
= new Interceptor( m_xOleAccess
, this, m_bLink
) );
799 m_xInterceptorLocker
= xInterceptor
;
803 void DocumentHolder::ClearInterceptorInternally()
805 ::osl::MutexGuard
aGuard( m_aMutex
);
806 uno::Reference
< frame::XDispatchProviderInterceptor
> xInterceptor( m_xInterceptorLocker
);
807 if ( xInterceptor
.is() && m_pInterceptor
)
808 m_pInterceptor
->DisconnectDocHolder();
810 m_xInterceptorLocker
.clear();
814 void DocumentHolder::ClearInterceptor()
816 ::osl::MutexGuard
aGuard( m_aMutex
);
817 m_xInterceptorLocker
.clear();
822 void DocumentHolder::show()
828 m_xFrame
->activate();
829 uno::Reference
<awt::XTopWindow
> xTopWindow(
830 m_xFrame
->getContainerWindow(),uno::UNO_QUERY
);
832 xTopWindow
->toFront();
834 else if( DocumentFrame().is() )
836 LoadDocInFrame( sal_False
);
838 // get rid of second closer if it is there
839 uno::Reference
< beans::XPropertySet
> xLMProps( m_xFrame
->getLayoutManager(), uno::UNO_QUERY
);
842 xLMProps
->setPropertyValue("MenuBarCloser",
843 uno::makeAny( uno::Reference
< frame::XStatusListener
>() ) );
850 uno::Reference
< util::XModifyBroadcaster
> xModifiable( m_xDocument
, uno::UNO_QUERY_THROW
);
851 xModifiable
->addModifyListener( (util::XModifyListener
*)this );
853 catch( const uno::Exception
& )
858 setTitle(m_aDocumentNamePart
);
861 catch( const uno::Exception
& )
863 OSL_FAIL( "Can not show the frame!\n" );
868 void DocumentHolder::resizeWin( const SIZEL
& rNewSize
)
870 LockedEmbedDocument_Impl aDocLock
;
872 if ( m_xOleAccess
.is() )
873 aDocLock
= m_xOleAccess
->GetEmbedDocument();
875 if ( m_xFrame
.is() && aDocLock
.GetEmbedDocument() )
877 uno::Reference
< awt::XWindow
> xWindow(
878 m_xFrame
->getContainerWindow(), uno::UNO_QUERY
);
879 uno::Reference
< awt::XView
> xView( xWindow
, uno::UNO_QUERY
);
881 if ( xWindow
.is() && xView
.is() )
884 xView
->setZoom( fScale
, fScale
);
887 GetExtent( &aOldSize
);
889 if ( aOldSize
.cx
!= rNewSize
.cx
|| aOldSize
.cy
!= rNewSize
.cy
)
891 HDC hdc
= GetDC( NULL
);
892 SetMapMode( hdc
, MM_HIMETRIC
);
895 aOldOffset
.x
= aOldSize
.cx
;
896 aOldOffset
.y
= aOldSize
.cy
;
897 BOOL bIsOk
= LPtoDP( hdc
, &aOldOffset
, 1 );
900 aNewOffset
.x
= rNewSize
.cx
;
901 aNewOffset
.y
= rNewSize
.cy
;
902 bIsOk
= LPtoDP( hdc
, &aNewOffset
, 1 );
904 ReleaseDC( NULL
, hdc
);
906 awt::Rectangle aWinRect
= xWindow
->getPosSize();
908 sal_Int32 aWidthDelta
= aWinRect
.Width
- aOldOffset
.x
;
909 sal_Int32 aHeightDelta
= aWinRect
.Height
- aOldOffset
.y
;
911 if ( aWidthDelta
> 0 && aHeightDelta
> 0 )
912 xWindow
->setPosSize(0,
914 aNewOffset
.x
+ aWidthDelta
,
915 aNewOffset
.y
+ aHeightDelta
,
916 awt::PosSize::SIZE
);
922 void DocumentHolder::setTitle(const OUString
& aDocumentName
)
926 if(m_aFilterName
.getLength() == 0)
928 OUString aFilterName
;
929 uno::Sequence
<beans::PropertyValue
> aSeq
;
933 m_xDocument
->getArgs();
934 for(sal_Int32 j
= 0; j
< aSeq
.getLength(); ++j
)
936 if(aSeq
[j
].Name
== "FilterName")
938 aSeq
[j
].Value
>>= aFilterName
;
944 if(aFilterName
.getLength())
946 uno::Reference
<container::XNameAccess
> xNameAccess(
947 m_xFactory
->createInstance("com.sun.star.document.FilterFactory"),
950 if(xNameAccess
.is() &&
951 (xNameAccess
->getByName(aFilterName
) >>= aSeq
))
953 for(sal_Int32 j
= 0; j
< aSeq
.getLength(); ++j
)
957 aSeq
[j
].Value
>>= m_aFilterName
;
962 catch(const uno::Exception
& ) {
963 // nothing better to do here
964 m_aFilterName
= aFilterName
;
969 static const sal_Unicode u
[] = { ' ','(',0 };
970 static const sal_Unicode c
[] = { ')',0 };
971 rtl::OUString
aTotalName(m_aFilterName
);
972 aTotalName
+= rtl::OUString(u
);
973 aTotalName
+= aDocumentName
;
974 aTotalName
+= rtl::OUString(c
);
976 m_xFrame
->setTitle( aTotalName
);
978 catch( const uno::Exception
& ) {
982 m_aDocumentNamePart
= aDocumentName
;
986 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
988 Interceptor
* pTmpInter
= NULL
;
989 uno::Reference
< frame::XDispatchProviderInterceptor
> xLock( m_xInterceptorLocker
);
990 if ( xLock
.is() && m_pInterceptor
)
991 pTmpInter
= m_pInterceptor
;
996 pTmpInter
->generateFeatureStateEvent();
1001 void DocumentHolder::setContainerName(const OUString
& aContainerName
)
1003 m_aContainerName
= aContainerName
;
1007 void DocumentHolder::hide()
1009 if(m_xFrame
.is()) m_xFrame
->deactivate();
1012 // after hiding the window it is always allowed to InPlaceActivate it
1013 m_bAllowInPlace
= true;
1016 IDispatch
* DocumentHolder::GetIDispatch()
1018 if ( !m_pIDispatch
&& m_xDocument
.is() )
1020 const OUString
aServiceName (
1021 "com.sun.star.bridge.OleBridgeSupplier2" );
1022 uno::Reference
< bridge::XBridgeSupplier2
> xSupplier(
1023 m_xFactory
->createInstance( aServiceName
), uno::UNO_QUERY
);
1025 if ( xSupplier
.is() )
1027 uno::Sequence
< sal_Int8
> aProcId( 16 );
1028 rtl_getGlobalProcessId( (sal_uInt8
*)aProcId
.getArray() );
1031 uno::Any anyResult
= xSupplier
->createBridge(
1032 uno::makeAny( m_xDocument
),
1034 bridge::ModelDependent::UNO
,
1035 bridge::ModelDependent::OLE
);
1037 if ( anyResult
.getValueTypeClass() ==
1038 cppu::UnoType
<sal_uIntPtr
>::get().getTypeClass() )
1040 VARIANT
* pVariant
= *(VARIANT
**)anyResult
.getValue();
1041 if ( pVariant
->vt
== VT_DISPATCH
)
1042 m_pIDispatch
= pVariant
->pdispVal
;
1044 VariantClear( pVariant
);
1045 CoTaskMemFree( pVariant
);
1048 catch ( const uno::Exception
& )
1053 return m_pIDispatch
;
1056 HRESULT
DocumentHolder::GetDocumentBorder( RECT
*pRect
)
1058 if ( pRect
&& m_xDocument
.is() )
1060 uno::Sequence
< beans::PropertyValue
> aArgs
= m_xDocument
->getArgs();
1061 for ( sal_Int32 nInd
= 0; nInd
< aArgs
.getLength(); nInd
++ )
1062 if ( aArgs
[nInd
].Name
== "DocumentBorder" )
1064 uno::Sequence
< sal_Int32
> aRect
;
1065 if ( ( aArgs
[nInd
].Value
>>= aRect
) && aRect
.getLength() == 4 )
1067 pRect
->left
= aRect
[0];
1068 pRect
->top
= aRect
[1];
1069 pRect
->right
= aRect
[2];
1070 pRect
->bottom
= aRect
[3];
1082 HRESULT
DocumentHolder::SetExtent( const SIZEL
*pSize
)
1086 uno::Reference
< embed::XVisualObject
> xVisObj( m_xDocument
, uno::UNO_QUERY
);
1091 awt::Size
aNewSize( pSize
->cx
, pSize
->cy
);
1093 sal_Int32 aMapMode
= xVisObj
->getMapUnit( DVASPECT_CONTENT
);
1095 // TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1096 if ( aMapMode
== embed::EmbedMapUnits::TWIP
)
1098 // conversion from ONE_100TH_MM
1099 aNewSize
.Width
= aNewSize
.Width
* 144 / 254;
1100 aNewSize
.Height
= aNewSize
.Height
* 144 / 254;
1104 xVisObj
->setVisualAreaSize( DVASPECT_CONTENT
, aNewSize
);
1108 catch( const uno::Exception
& )
1116 HRESULT
DocumentHolder::GetExtent( SIZEL
*pSize
)
1120 uno::Reference
< embed::XVisualObject
> xVisObj( m_xDocument
, uno::UNO_QUERY
);
1125 awt::Size aDocSize
= xVisObj
->getVisualAreaSize( DVASPECT_CONTENT
);
1127 sal_Int32 aMapMode
= xVisObj
->getMapUnit( DVASPECT_CONTENT
);
1129 // TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1130 if ( aMapMode
== embed::EmbedMapUnits::TWIP
)
1132 // conversion to ONE_100TH_MM
1133 aDocSize
.Width
= aDocSize
.Width
* 254 / 144;
1134 aDocSize
.Height
= aDocSize
.Height
* 254 / 144;
1137 pSize
->cx
= aDocSize
.Width
;
1138 pSize
->cy
= aDocSize
.Height
;
1142 catch( const uno::Exception
& )
1151 HRESULT
DocumentHolder::SetContRects(LPCRECT aRect
)
1153 if(m_xContainerWindow
.is()) {
1155 memset(&wi
,0,sizeof(wi
));
1156 if(m_pIOleIPFrame
) {
1157 m_pIOleIPFrame
->GetBorder((LPRECT
)&wi
);
1158 m_xContainerWindow
->setPosSize(
1162 awt::PosSize::POSSIZE
);
1165 m_xContainerWindow
->setPosSize(
1167 aRect
->right
- aRect
->left
,
1168 aRect
->bottom
- aRect
->top
,
1169 awt::PosSize::POSSIZE
);
1178 HRESULT
DocumentHolder::SetObjectRects(LPCRECT aRect
, LPCRECT aClip
)
1180 ((LPRECT
)aRect
)->left
-= m_aBorder
.left
;
1181 ((LPRECT
)aRect
)->right
+= m_aBorder
.right
;
1182 ((LPRECT
)aRect
)->top
-= m_aBorder
.top
;
1183 ((LPRECT
)aRect
)->bottom
+= m_aBorder
.bottom
;
1184 ((LPRECT
)aClip
)->left
-= m_aBorder
.left
;
1185 ((LPRECT
)aClip
)->right
+= m_aBorder
.right
;
1186 ((LPRECT
)aClip
)->top
-= m_aBorder
.top
;
1187 ((LPRECT
)aClip
)->bottom
+= m_aBorder
.bottom
;
1190 m_pCHatchWin
->RectsSet((LPRECT
)aRect
, (LPRECT
)aClip
);
1191 if(m_xEditWindow
.is()) {
1192 m_xEditWindow
->setVisible(false);
1193 m_xEditWindow
->setPosSize(
1194 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
1195 m_pCHatchWin
? HATCHWIN_BORDERWIDTHDEFAULT
: 0,
1196 aRect
->right
- aRect
->left
,
1197 aRect
->bottom
- aRect
->top
,
1198 awt::PosSize::POSSIZE
);
1199 m_xEditWindow
->setVisible(true);
1205 css::uno::Reference
< css::awt::XWindow
> SAL_CALL
DocumentHolder::getContainerWindow()
1207 css::uno::RuntimeException
1210 if(m_xContainerWindow
.is())
1211 return m_xContainerWindow
;
1213 uno::Reference
<awt::XWindow
> xWin(0);
1215 uno::Reference
<awt::XToolkit2
> xToolkit
= awt::Toolkit::create( comphelper::getComponentContext(m_xFactory
) );
1217 if(m_pIOleIPFrame
) {
1219 m_pIOleIPFrame
->GetWindow(&hWnd
);
1221 uno::Sequence
<sal_Int8
> aProcessIdent(16);
1222 rtl_getGlobalProcessId((sal_uInt8
*)aProcessIdent
.getArray());
1225 xToolkit
->createSystemChild(
1226 uno::Any(sal_Int32(hWnd
)),
1228 lang::SystemDependent::SYSTEM_WIN32
),
1232 memset(&wi
,0,sizeof(wi
));
1233 if(xWin
.is() && m_pIOleIPFrame
->GetBorder((LPRECT
)&wi
) == NOERROR
) {
1234 xWin
->setVisible(true);
1239 awt::PosSize::POSSIZE
);
1241 uno::Reference
<awt::XSystemDependentWindowPeer
> xSysWin(
1242 xWin
,uno::UNO_QUERY
);
1244 uno::Any aAny
= xSysWin
->getWindowHandle(
1245 aProcessIdent
,lang::SystemDependent::SYSTEM_WIN32
);
1248 SetContainerWindowHandle((HWND
) tmp
);
1253 m_xContainerWindow
= xWin
;
1258 sal_Bool SAL_CALL
DocumentHolder::requestDockingAreaSpace( const css::awt::Rectangle
& RequestedSpace
)
1260 css::uno::RuntimeException
1267 SetRect((LPRECT
)&bw
,
1268 RequestedSpace
.X
,RequestedSpace
.Y
,
1269 RequestedSpace
.Width
,RequestedSpace
.Height
);
1270 if( m_pIOleIPFrame
)
1271 return m_pIOleIPFrame
->RequestBorderSpace(&bw
) == NOERROR
;
1273 return sal_Bool(false);
1277 void SAL_CALL
DocumentHolder::setDockingAreaSpace( const css::awt::Rectangle
& BorderSpace
)
1279 css::uno::RuntimeException
1286 SetRect((LPRECT
)&bw
,
1287 BorderSpace
.X
,BorderSpace
.Y
,
1288 BorderSpace
.Width
,BorderSpace
.Height
);
1289 if( m_pIOleIPFrame
) {
1291 GetClientRect(m_hWndxWinCont
,&aRect
);
1292 HRGN hrgn1
= CreateRectRgn(
1294 aRect
.right
,BorderSpace
.Y
);
1295 HRGN hrgn2
= CreateRectRgn(aRect
.right
-BorderSpace
.Width
,0,aRect
.right
,aRect
.bottom
);
1296 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1297 DeleteObject(hrgn2
);
1298 hrgn2
= CreateRectRgn(0,aRect
.bottom
-BorderSpace
.Height
,aRect
.right
,aRect
.bottom
);
1299 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1300 DeleteObject(hrgn2
);
1301 hrgn2
= CreateRectRgn(0,0,BorderSpace
.X
,aRect
.bottom
);
1302 CombineRgn(hrgn1
,hrgn1
,hrgn2
,RGN_OR
);
1303 DeleteObject(hrgn2
);
1305 SetWindowRgn(m_hWndxWinCont
,hrgn1
,true);
1306 // not:: DeleteObject(hrgn1);
1307 m_pIOleIPFrame
->SetBorderSpace(&bw
);
1312 void SAL_CALL
DocumentHolder::disposing( const css::lang::EventObject
& aSource
)
1313 throw( uno::RuntimeException
)
1315 if ( m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1317 m_pIDispatch
= NULL
;
1318 m_xDocument
.clear();
1321 if( m_xFrame
.is() && m_xFrame
== aSource
.Source
)
1327 DocumentHolder::queryClosing(
1328 const lang::EventObject
& aSource
,
1329 sal_Bool
/*bGetsOwnership*/
1332 util::CloseVetoException
1336 && ((m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1337 || (m_xFrame
.is() && m_xFrame
== aSource
.Source
)))
1338 throw util::CloseVetoException();
1343 DocumentHolder::notifyClosing(
1344 const lang::EventObject
& aSource
)
1345 throw( uno::RuntimeException
)
1349 uno::Reference
< util::XCloseBroadcaster
> xEventBroadcaster(
1350 aSource
.Source
, uno::UNO_QUERY_THROW
);
1351 xEventBroadcaster
->removeCloseListener( (util::XCloseListener
*)this );
1353 catch( const uno::Exception
& )
1356 if ( m_xDocument
.is() && m_xDocument
== aSource
.Source
)
1358 // can happen only in case of links
1359 m_pIDispatch
= NULL
;
1360 m_xDocument
.clear();
1363 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
1364 if ( aDocLock
.GetEmbedDocument() )
1365 aDocLock
.GetEmbedDocument()->OLENotifyClosing();
1367 else if( m_xFrame
.is() && m_xFrame
== aSource
.Source
)
1372 DocumentHolder::queryTermination(
1373 const lang::EventObject
& /*aSource*/
1376 frame::TerminationVetoException
1379 if ( m_xDocument
.is() )
1380 throw frame::TerminationVetoException();
1384 DocumentHolder::notifyTermination(
1385 const lang::EventObject
& aSource
1387 throw( uno::RuntimeException
)
1389 OSL_ENSURE( !m_xDocument
.is(), "Just a disaster..." );
1390 uno::Reference
< frame::XDesktop
> xDesktop(
1391 aSource
.Source
, uno::UNO_QUERY
);
1393 if ( xDesktop
.is() )
1394 xDesktop
->removeTerminateListener( (frame::XTerminateListener
*)this );
1398 void SAL_CALL
DocumentHolder::modified( const lang::EventObject
& /*aEvent*/ )
1399 throw (uno::RuntimeException
)
1401 if ( m_xOleAccess
.is() )
1403 LockedEmbedDocument_Impl aDocLock
= m_xOleAccess
->GetEmbedDocument();
1404 if ( aDocLock
.GetEmbedDocument() )
1405 aDocLock
.GetEmbedDocument()->notify();
1409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */