1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #if defined(_MSC_VER) && (_MSC_VER > 1310)
24 #pragma warning(disable : 4917 4555)
25 #endif
26 
27 
28 #include "xwin.hxx"
29 #include "docholder.hxx"
30 #include "embeddoc.hxx"
31 #include "intercept.hxx"
32 #include "syswinwrapper.hxx"
33 #include "iipaobj.hxx"
34 
35 #include "common.h"
36 #include <Windows.h>
37 #include <com/sun/star/lang/SystemDependent.hpp>
38 #include <com/sun/star/awt/XSystemChildFactory.hpp>
39 #ifndef _COM_SUN_STAR_AWT_XSYSTEMDEPENDENTWINDOWPERR_HPP_
40 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
41 #endif
42 #include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
43 #include <com/sun/star/ui/XUIElement.hpp>
44 #include <com/sun/star/awt/WindowAttribute.hpp>
45 #include <com/sun/star/awt/XWindow.hpp>
46 #include <com/sun/star/frame/XComponentLoader.hpp>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/util/XCloseBroadcaster.hpp>
49 #include <com/sun/star/util/XCloseAble.hpp>
50 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACESS_HPP_
51 #include <com/sun/star/container/XNameAccess.hpp>
52 #endif
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include <com/sun/star/frame/XModel.hpp>
55 #include <com/sun/star/frame/XDesktop.hpp>
56 #include <com/sun/star/frame/XFramesSupplier.hpp>
57 #include <com/sun/star/frame/FrameSearchFlag.hpp>
58 #include <com/sun/star/frame/XStatusListener.hpp>
59 #include <com/sun/star/util/XModifyBroadcaster.hpp>
60 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
61 #include <com/sun/star/awt/XTopWindow.hpp>
62 #include <com/sun/star/awt/PosSize.hpp>
63 #include <com/sun/star/awt/XView.hpp>
64 #include <com/sun/star/bridge/XBridgeSupplier2.hpp>
65 #include <com/sun/star/bridge/ModelDependent.hpp>
66 #include <com/sun/star/embed/EmbedMapUnits.hpp>
67 #include <com/sun/star/embed/XVisualObject.hpp>
68 #include <com/sun/star/document/MacroExecMode.hpp>
69 #include <com/sun/star/task/XInteractionHandler.hpp>
70 #include <osl/diagnose.h>
71 #include <rtl/process.h>
72 
73 using namespace ::com::sun::star;
74 
75 extern ::rtl::OUString	getFilterNameFromGUID_Impl( GUID* );
76 
77 // add mutex locking ???
78 
DocumentHolder(const uno::Reference<lang::XMultiServiceFactory> & xFactory,const::rtl::Reference<EmbeddedDocumentInstanceAccess_Impl> & xOleAccess)79 DocumentHolder::DocumentHolder(
80 	const uno::Reference<lang::XMultiServiceFactory >& xFactory,
81 	const ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl >& xOleAccess )
82 	:
83 	m_bAllowInPlace(true),
84 	m_pIOleIPSite(0),
85 	m_pIOleIPFrame(0),
86 	m_pIOleIPUIWindow(0),
87 	m_pCHatchWin(0),
88 	m_xOleAccess( xOleAccess ),
89 	m_pInterceptor(0),
90 	m_xFactory( xFactory ),
91     m_bOnDeactivate(false),
92     m_hWndxWinParent(NULL),
93     m_hWndxWinCont(NULL),
94     m_nMenuHandle(NULL),
95     m_nMenuShared(NULL),
96     m_nOLEMenu(NULL),
97     m_nMacroExecMode( document::MacroExecMode::USE_CONFIG ),
98 	m_bLink( sal_False )
99 {
100 	static const ::rtl::OUString aServiceName (
101 		RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
102 	uno::Reference< frame::XDesktop > xDesktop(
103 		m_xFactory->createInstance( aServiceName ),
104 		uno::UNO_QUERY );
105 	if ( xDesktop.is() )
106 		xDesktop->addTerminateListener( (frame::XTerminateListener*)this );
107 }
108 
109 
~DocumentHolder()110 DocumentHolder::~DocumentHolder()
111 {
112 	delete m_pCHatchWin;
113 
114 	ClearInterceptorInternally();
115 }
116 
117 
LoadDocInFrame(sal_Bool bPluginMode)118 void DocumentHolder::LoadDocInFrame( sal_Bool bPluginMode )
119 {
120     uno::Reference<frame::XComponentLoader> xComponentLoader(
121         m_xFrame,uno::UNO_QUERY);
122     if( xComponentLoader.is() && m_xDocument.is() )
123     {
124         uno::Reference< task::XInteractionHandler > xHandler(
125             m_xFactory->createInstance(
126                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ),
127             uno::UNO_QUERY );
128 
129         uno::Any aAny;
130         sal_Int32 nLen = 3;
131         uno::Sequence<beans::PropertyValue> aSeq( nLen );
132 
133         aAny <<= uno::Reference<uno::XInterface>(
134             m_xDocument, uno::UNO_QUERY);
135         aSeq[0] = beans::PropertyValue(
136             rtl::OUString(
137                 RTL_CONSTASCII_USTRINGPARAM("Model")),
138             -1,
139             aAny,
140             beans::PropertyState_DIRECT_VALUE);
141 
142         aAny <<= sal_False;
143         aSeq[1] = beans::PropertyValue(
144             rtl::OUString(
145                 RTL_CONSTASCII_USTRINGPARAM("ReadOnly")),
146             -1,
147             aAny,
148             beans::PropertyState_DIRECT_VALUE);
149 
150         aAny <<= (sal_Bool) sal_True;
151         aSeq[2] = beans::PropertyValue(
152             rtl::OUString(
153                 RTL_CONSTASCII_USTRINGPARAM("NoAutoSave")),
154             -1,
155             aAny,
156             beans::PropertyState_DIRECT_VALUE);
157 
158         if ( bPluginMode )
159         {
160             aSeq.realloc( ++nLen );
161             aAny <<= (sal_Int16) 3;
162             aSeq[nLen-1] = beans::PropertyValue(
163                 rtl::OUString(
164                     RTL_CONSTASCII_USTRINGPARAM("PluginMode")),
165                 -1,
166                 aAny,
167                 beans::PropertyState_DIRECT_VALUE);
168         }
169 
170         if ( xHandler.is() )
171         {
172             aSeq.realloc( nLen+=2 );
173             aAny <<= xHandler;
174             aSeq[nLen-2] = beans::PropertyValue(
175                 rtl::OUString(
176                     RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")),
177                 -1,
178                 aAny,
179                 beans::PropertyState_DIRECT_VALUE);
180 
181             aAny <<= m_nMacroExecMode;
182             aSeq[nLen-1] = beans::PropertyValue(
183                 rtl::OUString(
184                     RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode")),
185                 -1,
186                 aAny,
187                 beans::PropertyState_DIRECT_VALUE);
188         }
189 
190         xComponentLoader->loadComponentFromURL(
191             rtl::OUString(
192                 RTL_CONSTASCII_USTRINGPARAM("private:object")),
193             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")),
194             0,
195             aSeq);
196 
197         uno::Sequence< beans::PropertyValue > aResArgs = m_xDocument->getArgs();
198         for ( int nInd = 0; nInd < aResArgs.getLength(); nInd++ )
199             if ( aResArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MacroExecutionMode" ) ) ) )
200             {
201                 aResArgs[nInd].Value >>= m_nMacroExecMode;
202                 break;
203             }
204     }
205 }
206 
OnPosRectChanged(LPRECT lpRect) const207 void DocumentHolder::OnPosRectChanged(LPRECT lpRect) const
208 {
209     lpRect->left += m_aBorder.left;
210     lpRect->right -= m_aBorder.right;
211     lpRect->top += m_aBorder.top;
212     lpRect->bottom -= m_aBorder.bottom;
213     if(m_pIOleIPSite)
214         m_pIOleIPSite->OnPosRectChange(lpRect);
215 }
216 
217 
218 
DisableInplaceActivation(BOOL b)219 void DocumentHolder::DisableInplaceActivation(BOOL b)
220 {
221 	m_bAllowInPlace = ! b;
222 }
223 
isActive() const224 BOOL DocumentHolder::isActive() const
225 {
226 	return m_pIOleIPSite != 0;
227 }
228 
InPlaceActivate(LPOLECLIENTSITE pActiveSite,BOOL fIncludeUI)229 HRESULT DocumentHolder::InPlaceActivate(
230 	LPOLECLIENTSITE pActiveSite,
231 	BOOL fIncludeUI)
232 {
233 	m_bOnDeactivate = false;
234 
235 	if(!m_bAllowInPlace)
236 		return ERROR;
237 
238     HRESULT                 hr;
239     HWND                    hWndSite;
240     RECT                    rcPos;
241     RECT                    rcClip;
242     OLEINPLACEFRAMEINFO     frameInfo;
243 
244     if (NULL==pActiveSite)
245         return ResultFromScode(E_INVALIDARG);
246 
247     if (NULL!=m_pIOleIPSite)
248 	{
249         if (fIncludeUI)
250             UIActivate();
251 
252         return NOERROR;
253 	}
254 
255     if ( !m_xDocument.is() )
256         return ERROR;
257 
258     //1.  Initialization, obtaining interfaces, OnInPlaceActivate.
259     hr=pActiveSite->QueryInterface(
260 		IID_IOleInPlaceSite,
261 		(void**) &m_pIOleIPSite);
262 
263     if (FAILED(hr))
264         return hr;
265 
266     hr=m_pIOleIPSite->CanInPlaceActivate();
267 
268     if (NOERROR!=hr)
269 	{
270         m_pIOleIPSite->Release(), m_pIOleIPSite=NULL;
271         return ResultFromScode(E_FAIL);
272 	}
273 
274     m_pIOleIPSite->OnInPlaceActivate();
275 
276     //2. Get the site window
277     //3. and determine container frame and
278     //   document window for tools and menus, as well
279     //   as frameInfo for accelerators
280     m_pIOleIPSite->GetWindow(&hWndSite);
281 
282     frameInfo.cb=sizeof(OLEINPLACEFRAMEINFO);
283     m_pIOleIPSite->GetWindowContext(
284 		&m_pIOleIPFrame,&m_pIOleIPUIWindow,&rcPos,&rcClip,&frameInfo);
285 
286 	// initialize the office as, with hwnd as parentwindow
287     uno::Any                      aAny;
288     uno::Sequence<sal_Int8> aProcessIdent(16);
289     rtl_getGlobalProcessId((sal_uInt8*)aProcessIdent.getArray());
290 
291     try
292     {
293         if(!m_xEditWindow.is())
294         {   // determine XWindow and window handle of parent
295             HWND                          hWndxWinParent(0);
296             uno::Reference<awt::XWindow>  xWin;
297 
298             static const ::rtl::OUString aToolkitServiceName(
299                 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.awt.Toolkit" ) );
300             uno::Reference<awt::XSystemChildFactory> xToolkit(
301                 m_xFactory->createInstance(aToolkitServiceName ),uno::UNO_QUERY);
302 
303             if(xToolkit.is()) {
304                 // create system window wrapper for hwnd
305                 if( !m_pCHatchWin )
306                     m_pCHatchWin = new winwrap::CHatchWin(
307                         m_hInstance,this);
308 
309                 if(m_pCHatchWin->Init(hWndSite,/*ID_HATCHWINDOW*/2000, NULL)) {
310                     m_pCHatchWin->RectsSet(&rcPos,&rcClip); //set visible area
311                     hWndxWinParent = m_pCHatchWin->Window();
312                     ShowWindow(hWndxWinParent,SW_SHOW);  //Make visible.
313                 }
314                 else {
315                     // no success initializing hatch window
316                     delete m_pCHatchWin, m_pCHatchWin = 0;
317                     hWndxWinParent = hWndSite;
318                 }
319 
320                 aAny <<= sal_Int32(hWndxWinParent);
321                 xWin = uno::Reference<awt::XWindow>(
322                     xToolkit->createSystemChild(
323                         aAny,
324                         aProcessIdent,
325                         lang::SystemDependent::SYSTEM_WIN32),
326                     uno::UNO_QUERY);
327             }
328 
329             if(xWin.is()) {
330                 xWin->setPosSize(
331                     m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0,
332                     m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0,
333                     rcPos.right-rcPos.left,
334                     rcPos.bottom - rcPos.top,
335                     awt::PosSize::POSSIZE);
336                 xWin->setVisible(sal_True);
337 
338                 m_xEditWindow = xWin;
339                 m_hWndxWinParent = hWndxWinParent;
340             }
341             else
342                 return ERROR;
343         }
344         else {
345             if(m_hWndxWinParent) {
346                 SetParent(m_hWndxWinParent,hWndSite);
347                 ShowWindow(m_hWndxWinParent,SW_SHOW);  //Make visible.
348             }
349 
350             if ( !m_xFrame.is() )
351                 // initially set size to "empty", this guarantees that the final resize
352                 // is always executed (will be done by "SetObjectRects" after getting internal border)
353                 m_xEditWindow->setPosSize(
354                     0,
355                     0,
356                     0,
357                     0,
358                     awt::PosSize::POSSIZE);
359             m_xEditWindow->setVisible(sal_True);
360         }
361 
362         if(m_xContainerWindow.is()) {
363             if(m_hWndxWinCont) {
364                 if(m_pIOleIPFrame) {
365                     HWND  hWndCont;
366                     m_pIOleIPFrame->GetWindow(&hWndCont);
367                     SetParent(m_hWndxWinCont,hWndCont);
368                     ShowWindow(m_hWndxWinCont,SW_SHOW);
369                 }
370             }
371             m_xContainerWindow->setVisible(true);
372         }
373 
374         if(m_xFrame.is())
375             m_xFrame->activate();
376         else {
377             // create frame and initialize it with with the created window
378             static const ::rtl::OUString aFrameServiceName(
379                 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Frame" ) );
380             m_xFrame = uno::Reference<frame::XFrame>(
381                 m_xFactory->createInstance(aFrameServiceName),
382                 uno::UNO_QUERY);
383 
384             if(!m_xFrame.is())
385                 return ERROR;
386 
387             m_xFrame->initialize(m_xEditWindow);
388 
389             uno::Reference<frame::XDispatchProviderInterception>
390                 xDPI(m_xFrame,uno::UNO_QUERY);
391             if(xDPI.is())
392                 xDPI->registerDispatchProviderInterceptor( CreateNewInterceptor() );
393 
394             uno::Reference<beans::XPropertySet> xPS(m_xFrame,uno::UNO_QUERY);
395             if( xPS.is() )
396             {
397                 aAny = xPS->getPropertyValue(
398                     rtl::OUString::createFromAscii("LayoutManager"));
399                 aAny >>= m_xLayoutManager;
400             }
401 
402             if(m_xLayoutManager.is())
403                 m_xLayoutManager->setDockingAreaAcceptor(this);
404 
405             // load the model into the frame
406             LoadDocInFrame( sal_True );
407 
408             static const ::rtl::OUString aDesktopServiceName (
409                 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
410             uno::Reference< frame::XFramesSupplier > xDesktop(
411                 m_xFactory->createInstance( aDesktopServiceName ),
412                 uno::UNO_QUERY );
413             if(xDesktop.is())
414                 xDesktop->getFrames()->append(m_xFrame);
415 
416             // determine the menuhandle to get menutitems.
417             if(m_xLayoutManager.is()) {
418                 uno::Reference< ::com::sun::star::ui::XUIElement > xUIEl(
419                     m_xLayoutManager->getElement(
420                         rtl::OUString::createFromAscii(
421                             "private:resource/menubar/menubar")));
422                 OSL_ENSURE(xUIEl.is(),"no menubar");
423                 uno::Reference<awt::XSystemDependentMenuPeer> xSDMP(
424                     xUIEl->getRealInterface(),
425                     uno::UNO_QUERY);
426                 aAny = xSDMP->getMenuHandle(
427                     aProcessIdent,lang::SystemDependent::SYSTEM_WIN32);
428                 sal_Int32 tmp;
429                 if( aAny >>= tmp )
430                     m_nMenuHandle = HMENU(tmp);
431                 m_xLayoutManager->hideElement(
432                     rtl::OUString(
433                         RTL_CONSTASCII_USTRINGPARAM(
434                             "private:resource/menubar/menubar" )));
435             }
436         }
437 
438         // TODO/cd: Workaround for status indicator bug. It always makes the
439         // document window visible, when someone tries to use the status
440         // indicator. As we save our document when we get the deactivation
441         // from OLE this conflict to hide floating windows.
442         if(m_xLayoutManager.is())
443             m_xLayoutManager->setVisible(true);
444 
445         // get document border and resize rects according to border
446         GetDocumentBorder( &m_aBorder );
447         SetObjectRects( &rcPos, &rcClip );
448 
449         if ( m_xOleAccess.is() )
450         {
451             LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument();
452             if ( aDocLock.GetEmbedDocument() )
453                 aDocLock.GetEmbedDocument()->ShowObject();
454         }
455 
456         // setTitle(m_aDocumentNamePart);
457         if (fIncludeUI)
458             hr=UIActivate();
459 
460         m_pIOleIPSite->DiscardUndoState();
461     }
462     catch( uno::Exception& )
463     {
464         hr = ERROR;
465     }
466 
467     return hr;
468 }
469 
470 
InPlaceDeactivate(void)471 void DocumentHolder::InPlaceDeactivate(void)
472 {
473     m_bOnDeactivate = true;
474 
475 	UIDeactivate();
476 	if(m_xFrame.is()) m_xFrame->deactivate();
477 
478     if(m_xEditWindow.is()) {
479         m_xEditWindow->setVisible(false);
480         ShowWindow(m_hWndxWinParent,SW_HIDE);
481         SetParent(m_hWndxWinParent,0);
482     }
483 
484     if(m_xContainerWindow.is()) {
485         m_xContainerWindow->setVisible(false);
486         ShowWindow(m_hWndxWinCont,SW_HIDE);
487         SetParent(m_hWndxWinCont,0);
488     }
489 
490     // TODO/cd: Workaround for status indicator bug. It always makes the
491     // document window visible, when someone tries to use the status
492     // indicator. As we save our document when we get the deactivation
493     // from OLE this conflict to hide floating windows.
494     if (m_xLayoutManager.is())
495         m_xLayoutManager->setVisible(false);
496 
497     if (NULL!=m_pIOleIPSite)
498     {
499         // The following workaround should let the object be stored in case of inplace editing
500 //        CComPtr< IOleClientSite > pClientSite;
501 //
502 //        m_pIOleIPSite->QueryInterface(
503 //		        IID_IOleClientSite, (void**)&pClientSite );
504 //        if ( pClientSite )
505 //            pClientSite->SaveObject();
506 
507         m_pIOleIPSite->OnInPlaceDeactivate();
508     }
509 
510     if(m_pIOleIPFrame) m_pIOleIPFrame->Release(); m_pIOleIPFrame = 0;
511     if(m_pIOleIPUIWindow) m_pIOleIPUIWindow->Release(); m_pIOleIPUIWindow = 0;
512 	if(m_pIOleIPSite) m_pIOleIPSite->Release(); m_pIOleIPSite = 0;
513 
514 	if ( m_xOleAccess.is() )
515 	{
516 		LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument();
517 		if ( aDocLock.GetEmbedDocument() )
518         {
519             aDocLock.GetEmbedDocument()->SaveObject();
520         }
521 	}
522 
523     return;
524 }
525 
526 
UIActivate()527 HRESULT DocumentHolder::UIActivate()
528 {
529     // 1.  Call IOleInPlaceSite::UIActivate
530     if (NULL!=m_pIOleIPSite)
531         m_pIOleIPSite->OnUIActivate();
532 
533     //2.  Critical for accelerators to work initially.
534     SetFocus(m_pCHatchWin->Window());
535 	// if(m_xEditWindow.is()) m_xEditWindow->setFocus();
536 
537     //3.  Set the active object
538 
539     OLECHAR starOffice[] = {'S','t','a','r','O','f','f','i','c','e',0};
540 	CComPtr< IOleInPlaceActiveObject > pObj = new CIIAObj( this );
541 
542     if (NULL!=m_pIOleIPFrame)
543         m_pIOleIPFrame->SetActiveObject(
544 			pObj, starOffice );
545 
546     if (NULL!=m_pIOleIPUIWindow)
547 		m_pIOleIPUIWindow->SetActiveObject(
548 			pObj, starOffice );
549 
550     //4.  Create the shared menu.
551     InPlaceMenuCreate();
552 
553 	return NOERROR;
554 }
555 
UIDeactivate()556 void DocumentHolder::UIDeactivate()
557 {
558     //1.  Remove the shared menu.
559     InPlaceMenuDestroy();
560 
561     if (NULL!=m_pIOleIPFrame)
562         m_pIOleIPFrame->SetActiveObject(NULL, NULL);
563 
564     if (NULL!=m_pIOleIPUIWindow)
565         m_pIOleIPUIWindow->SetActiveObject(NULL, NULL);
566 
567     //3.  Call IOleInPlaceSite::OnUIDeactivate
568     if (NULL!=m_pIOleIPSite)
569         m_pIOleIPSite->OnUIDeactivate(FALSE);
570 
571     return;
572 }
573 
CopyToOLEMenu(HMENU hOrig,WORD origPos,HMENU hDest,WORD destPos)574 void CopyToOLEMenu(HMENU hOrig,WORD origPos,HMENU hDest,WORD destPos)
575 {
576     HMENU subMenu(NULL);
577     UINT uTemp = MF_BYPOSITION | MF_POPUP;
578     char buffer[256];
579 
580     subMenu = GetSubMenu(hOrig,origPos);
581     GetMenuString(hOrig,origPos,buffer,256,MF_BYPOSITION);
582     InsertMenu(hDest,destPos,uTemp,
583                (UINT)subMenu,LPCTSTR(buffer));
584 
585     MENUITEMINFOW mi;
586     memset(&mi,0,sizeof(mi));
587     mi.cbSize = sizeof(mi);
588     mi.fMask = MIIM_DATA;
589     if(GetMenuItemInfoW(hOrig,origPos,TRUE,&mi))
590         SetMenuItemInfoW(hDest,(WORD)destPos,TRUE,&mi);
591 }
592 
InPlaceMenuCreate(void)593 BOOL DocumentHolder::InPlaceMenuCreate(void)
594 {
595     HMENU               hMenu;
596     UINT                i;
597     OLEMENUGROUPWIDTHS  mgw;
598 
599     for (i=0; i<6; i++)
600         mgw.width[i]=0;
601 
602     //We already have popup menu handles in m_pFR->m_phMenu[]
603 
604     //Create the new shared menu and let container do its thing
605     hMenu=CreateMenu();
606     m_pIOleIPFrame->InsertMenus(hMenu,&mgw);
607 
608     int count = GetMenuItemCount(m_nMenuHandle);
609     int help = count-1;
610 
611     // start with 1, because we don't include "File"
612     WORD pos = (WORD)mgw.width[0];
613     CopyToOLEMenu(m_nMenuHandle,1,hMenu,pos);
614     mgw.width[1] = 1;
615 
616     // insert object menu here
617     pos = ((WORD)(mgw.width[0] + mgw.width[1] + mgw.width[2]));
618     for(WORD i = 2; i < help-1; ++i,++pos)
619         CopyToOLEMenu(m_nMenuHandle,i,hMenu,pos);
620     mgw.width[3] = help - 3;
621 
622     // insert help menu
623     pos = (WORD)(mgw.width[0] + mgw.width[1] + mgw.width[2] +
624                  mgw.width[3] + mgw.width[4]);
625     CopyToOLEMenu(m_nMenuHandle,WORD(help),hMenu,pos);
626     mgw.width[5] = 1;
627 
628     m_nMenuShared = hMenu;
629     m_nOLEMenu = OleCreateMenuDescriptor(m_nMenuShared,&mgw);
630 
631     uno::Reference<awt::XSystemDependentWindowPeer> xSysDepWin(m_xContainerWindow,uno::UNO_QUERY);
632     if(xSysDepWin.is()) {
633         uno::Sequence<sal_Int8> aProcessIdent(16);
634         rtl_getGlobalProcessId((sal_uInt8*)aProcessIdent.getArray());
635         uno::Any aAny = xSysDepWin->getWindowHandle(aProcessIdent,lang::SystemDependent::SYSTEM_WIN32);
636         sal_Int32 tmp;
637         aAny >>= tmp;
638         HWND aHwnd = (HWND) tmp;
639         m_pIOleIPFrame->SetMenu(
640             m_nMenuShared,m_nOLEMenu,aHwnd);
641     }
642     else
643         m_pIOleIPFrame->SetMenu(
644             m_nMenuShared,m_nOLEMenu,::GetWindow(m_hWndxWinParent,GW_CHILD));
645     return TRUE;
646 }
647 
InPlaceMenuDestroy(void)648 BOOL DocumentHolder::InPlaceMenuDestroy(void)
649 {
650     if( NULL == m_nMenuShared )
651         return TRUE;
652 
653     m_pIOleIPFrame->SetMenu(NULL,NULL,NULL);
654 
655     OleDestroyMenuDescriptor(m_nOLEMenu),m_nOLEMenu = NULL;
656 	return TRUE;
657 }
658 
OpenIntoWindow(void)659 void DocumentHolder::OpenIntoWindow(void)
660 {
661 	// not implemented
662 }
663 
Undo(void)664 BOOL DocumentHolder::Undo(void)
665 {
666 	// not implemented
667 	return false;
668 }
669 
670 
FreeOffice()671 void DocumentHolder::FreeOffice()
672 {
673 	const ::rtl::OUString aServiceName(
674 		RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
675 	uno::Reference< frame::XDesktop > xDesktop(
676 		m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY );
677 	if ( xDesktop.is() )
678 	{
679 		xDesktop->removeTerminateListener(
680 			(frame::XTerminateListener*)this );
681 	}
682 }
683 
DisconnectFrameDocument(sal_Bool bComplete)684 void DocumentHolder::DisconnectFrameDocument( sal_Bool bComplete )
685 {
686 	try
687 	{
688 		uno::Reference< util::XModifyBroadcaster > xModifiable( m_xDocument, uno::UNO_QUERY_THROW );
689 		xModifiable->removeModifyListener( (util::XModifyListener*)this );
690 	}
691 	catch( uno::Exception& )
692 	{}
693 
694 	try
695 	{
696 		uno::Reference< util::XCloseBroadcaster > xBroadcaster(
697 			m_xDocument, uno::UNO_QUERY_THROW );
698 		xBroadcaster->removeCloseListener( (util::XCloseListener*)this );
699 	}
700 	catch( uno::Exception& )
701 	{}
702 
703 	try
704 	{
705 		uno::Reference< util::XCloseBroadcaster > xBroadcaster(
706 			m_xFrame, uno::UNO_QUERY_THROW );
707 		xBroadcaster->removeCloseListener( (util::XCloseListener*)this );
708 	}
709 	catch( uno::Exception& )
710 	{}
711 
712     if ( bComplete )
713     {
714         m_xFrame = uno::Reference< frame::XFrame>();
715 	    m_pIDispatch = NULL;
716 	    m_xDocument = uno::Reference< frame::XModel >();
717     }
718 }
719 
CloseDocument()720 void DocumentHolder::CloseDocument()
721 {
722 	DisconnectFrameDocument();
723 
724 	uno::Reference< util::XCloseable > xCloseable(
725 			m_xDocument, uno::UNO_QUERY );
726 
727 	if ( xCloseable.is() )
728 	{
729 		try
730 		{
731 			xCloseable->close( sal_True );
732 		}
733 		catch( uno::Exception& )
734 		{}
735 	}
736 
737 	m_pIDispatch = NULL;
738 	m_xDocument = uno::Reference< frame::XModel >();
739 }
740 
741 
CloseFrame()742 void DocumentHolder::CloseFrame()
743 {
744 	try
745 	{
746 		uno::Reference< util::XCloseBroadcaster > xBroadcaster(
747 			m_xFrame, uno::UNO_QUERY_THROW );
748 		xBroadcaster->removeCloseListener( (util::XCloseListener*)this );
749 	}
750 	catch( uno::Exception& )
751 	{}
752 
753 	uno::Reference<util::XCloseable> xCloseable(
754 		m_xFrame,uno::UNO_QUERY);
755 	if(xCloseable.is())
756 		try {
757 			xCloseable->close(sal_True);
758 		}
759 		catch( const uno::Exception& ) {
760 		}
761 	else {
762 		uno::Reference<lang::XComponent> xComp(m_xFrame,uno::UNO_QUERY);
763 		if(xComp.is())
764 			xComp->dispose();
765 	}
766 
767 	m_xFrame = uno::Reference< frame::XFrame >();
768 }
769 
SetDocument(const uno::Reference<frame::XModel> & xDoc,sal_Bool bLink)770 void DocumentHolder::SetDocument( const uno::Reference< frame::XModel >& xDoc, sal_Bool bLink )
771 {
772 	if ( m_xDocument.is() )
773 		CloseDocument();
774 
775 	m_xDocument = xDoc;
776 	m_bLink = bLink;
777 
778 	uno::Reference< util::XCloseBroadcaster > xBroadcaster(
779 		m_xDocument, uno::UNO_QUERY );
780 
781 	if ( xBroadcaster.is() )
782 		xBroadcaster->addCloseListener( (util::XCloseListener*)this );
783 
784 	if ( m_xDocument.is() && !m_bLink )
785 	{
786 		// set the document mode to embedded
787 		uno::Sequence< beans::PropertyValue > aSeq(1);
788 		aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" );
789 		aSeq[0].Value <<= sal_True;
790 		m_xDocument->attachResource(::rtl::OUString(),aSeq);
791 	}
792 }
793 
ExecuteSuspendCloseFrame()794 sal_Bool DocumentHolder::ExecuteSuspendCloseFrame()
795 {
796 	if ( m_xFrame.is() && m_xFactory.is() )
797 	{
798 		try
799 		{
800 			uno::Reference< frame::XController > xController = m_xFrame->getController();
801 			if ( xController.is() )
802 			{
803 				if ( !xController->suspend( sal_True ) )
804 					return sal_False;
805 
806 				FreeOffice();
807 				try
808 				{
809 					uno::Reference<util::XCloseable> xCloseable( m_xFrame, uno::UNO_QUERY );
810 					if ( xCloseable.is() )
811 						xCloseable->close(sal_True);
812 					else
813 					{
814 						uno::Reference<lang::XComponent> xComp( m_xFrame, uno::UNO_QUERY_THROW );
815 						if( xComp.is() )
816 							xComp->dispose();
817 					}
818 				}
819 				catch( const util::CloseVetoException& )
820 				{
821 					// should be called if the frame could not be closed
822 					xController->suspend( sal_False );
823 				}
824 			}
825 		}
826 		catch( uno::Exception& )
827 		{
828 		}
829 
830 		m_xFrame = uno::Reference< frame::XFrame >();
831 	}
832 
833 	return sal_True;
834 }
835 
DocumentFrame()836 uno::Reference< frame::XFrame > DocumentHolder::DocumentFrame()
837 {
838 	if(! m_xFrame.is() )
839 	{
840 		rtl::OUString aDesktopSrvNm(
841 			RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"));
842 
843 		uno::Reference<frame::XDesktop> xDesktop(
844 			m_xFactory->createInstance(aDesktopSrvNm),
845 			uno::UNO_QUERY);
846 
847 		uno::Reference<frame::XFrame> xFrame(
848 			xDesktop,uno::UNO_QUERY);
849 
850 		// the frame will be registered on desktop here, later when the document
851 		// is loaded into the frame in ::show() method the terminate listener will be removed
852 		// this is so only for outplace activation
853 		if( xFrame.is() )
854 			m_xFrame = xFrame->findFrame(
855 				rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")),0);
856 
857 		uno::Reference< util::XCloseBroadcaster > xBroadcaster(
858 			m_xFrame, uno::UNO_QUERY );
859 
860 		if ( xBroadcaster.is() )
861 		{
862 			xBroadcaster->addCloseListener( (util::XCloseListener*)this );
863 			FreeOffice(); // the frame is part of the desktop
864 		}
865 	}
866 
867 	if( m_xFrame.is() )
868 	{
869 		// intercept
870 		uno::Reference<frame::XDispatchProviderInterception>
871 			xDPI(m_xFrame,uno::UNO_QUERY);
872 		if(xDPI.is())
873 			xDPI->registerDispatchProviderInterceptor( CreateNewInterceptor() );
874 	}
875 
876 	return m_xFrame;
877 }
878 
879 
CreateNewInterceptor()880 uno::Reference< frame::XDispatchProviderInterceptor > DocumentHolder::CreateNewInterceptor()
881 {
882 	::osl::MutexGuard aGuard( m_aMutex );
883 
884 	ClearInterceptorInternally();
885 
886 	uno::Reference< frame::XDispatchProviderInterceptor > xInterceptor( m_pInterceptor = new Interceptor( m_xOleAccess, this, m_bLink ) );
887 	m_xInterceptorLocker = xInterceptor;
888 	return xInterceptor;
889 }
890 
ClearInterceptorInternally()891 void DocumentHolder::ClearInterceptorInternally()
892 {
893 	::osl::MutexGuard aGuard( m_aMutex );
894 	uno::Reference< frame::XDispatchProviderInterceptor > xInterceptor( m_xInterceptorLocker );
895 	if ( xInterceptor.is() && m_pInterceptor )
896 		m_pInterceptor->DisconnectDocHolder();
897 
898 	m_xInterceptorLocker = uno::Reference< frame::XDispatchProviderInterceptor >();
899 	m_pInterceptor = 0;
900 }
901 
ClearInterceptor()902 void DocumentHolder::ClearInterceptor()
903 {
904 	::osl::MutexGuard aGuard( m_aMutex );
905 	m_xInterceptorLocker = uno::Reference< frame::XDispatchProviderInterceptor >();
906 	m_pInterceptor = 0;
907 }
908 
909 
show()910 void DocumentHolder::show()
911 {
912     try
913     {
914         if(m_xFrame.is())
915         {
916             m_xFrame->activate();
917             uno::Reference<awt::XTopWindow> xTopWindow(
918                 m_xFrame->getContainerWindow(),uno::UNO_QUERY);
919             if(xTopWindow.is())
920                 xTopWindow->toFront();
921         }
922         else if( DocumentFrame().is() )
923         {
924             LoadDocInFrame( sal_False );
925 
926             // get rid of second closer if it is there
927             uno::Reference< beans::XPropertySet > xProps( m_xFrame, uno::UNO_QUERY );
928             if ( xProps.is() )
929             {
930                 uno::Reference< frame::XLayoutManager > xLayoutManager;
931                 xProps->getPropertyValue( rtl::OUString::createFromAscii( "LayoutManager" ) ) >>= xLayoutManager;
932                 uno::Reference< beans::XPropertySet > xLMProps( xLayoutManager, uno::UNO_QUERY );
933                 if ( xLMProps.is() )
934                 {
935                     xLMProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MenuBarCloser" ),
936                                                 uno::makeAny( uno::Reference< frame::XStatusListener >() ) );
937                 }
938             }
939 
940             if ( !m_bLink )
941             {
942                 try
943                 {
944                     uno::Reference< util::XModifyBroadcaster > xModifiable( m_xDocument, uno::UNO_QUERY_THROW );
945                     xModifiable->addModifyListener( (util::XModifyListener*)this );
946                 }
947                 catch( uno::Exception& )
948                 {}
949             }
950 
951             if ( !m_bLink )
952                 setTitle(m_aDocumentNamePart);
953         }
954 	}
955     catch( uno::Exception& )
956     {
957         OSL_ENSURE( sal_False, "Can not show the frame!\n" );
958     }
959 
960 }
961 
resizeWin(const SIZEL & rNewSize)962 void DocumentHolder::resizeWin( const SIZEL& rNewSize )
963 {
964 	LockedEmbedDocument_Impl aDocLock;
965 
966 	if ( m_xOleAccess.is() )
967 		aDocLock = m_xOleAccess->GetEmbedDocument();
968 
969 	if ( m_xFrame.is() && aDocLock.GetEmbedDocument() )
970 	{
971 		uno::Reference< awt::XWindow > xWindow(
972 			m_xFrame->getContainerWindow(), uno::UNO_QUERY );
973 		uno::Reference< awt::XView > xView( xWindow, uno::UNO_QUERY );
974 
975 		if ( xWindow.is() && xView.is() )
976 		{
977 			float fScale = 1;
978 			xView->setZoom( fScale, fScale );
979 
980 			SIZEL aOldSize;
981 			GetExtent( &aOldSize );
982 
983 			if ( aOldSize.cx != rNewSize.cx || aOldSize.cy != rNewSize.cy )
984 			{
985 				HDC hdc = GetDC( NULL );
986 				SetMapMode( hdc, MM_HIMETRIC );
987 
988 				POINT aOldOffset;
989 				aOldOffset.x = aOldSize.cx;
990 				aOldOffset.y = aOldSize.cy;
991 				BOOL bIsOk = LPtoDP( hdc, &aOldOffset, 1 );
992 
993 				POINT aNewOffset;
994 				aNewOffset.x = rNewSize.cx;
995 				aNewOffset.y = rNewSize.cy;
996 				bIsOk = LPtoDP( hdc, &aNewOffset, 1 );
997 
998 				ReleaseDC( NULL, hdc );
999 
1000 				awt::Rectangle aWinRect = xWindow->getPosSize();
1001 
1002 				sal_Int32 aWidthDelta = aWinRect.Width - aOldOffset.x;
1003 				sal_Int32 aHeightDelta = aWinRect.Height - aOldOffset.y;
1004 
1005 				if ( aWidthDelta > 0 && aHeightDelta > 0 )
1006 					xWindow->setPosSize(0,
1007 										0,
1008 										aNewOffset.x + aWidthDelta,
1009 										aNewOffset.y + aHeightDelta,
1010 										awt::PosSize::SIZE );
1011 			}
1012 		}
1013 	}
1014 }
1015 
setTitle(const rtl::OUString & aDocumentName)1016 void DocumentHolder::setTitle(const rtl::OUString& aDocumentName)
1017 {
1018 	if(m_xFrame.is())
1019 	{
1020 		if(m_aFilterName.getLength() == 0)
1021 		{
1022 			rtl::OUString aFilterName;
1023 			uno::Sequence<beans::PropertyValue> aSeq;
1024 			if(m_xDocument.is())
1025 			{
1026 				aSeq =
1027 					m_xDocument->getArgs();
1028 				for(sal_Int32 j = 0; j < aSeq.getLength(); ++j)
1029 				{
1030 					if(aSeq[j].Name ==
1031 					   rtl::OUString(
1032 						   RTL_CONSTASCII_USTRINGPARAM("FilterName")))
1033 					{
1034 						aSeq[j].Value >>= aFilterName;
1035 						break;
1036 					}
1037 				}
1038 			}
1039 
1040 			if(aFilterName.getLength())
1041 			{
1042 				uno::Reference<container::XNameAccess> xNameAccess(
1043 					m_xFactory->createInstance(
1044 						rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1045 							"com.sun.star.document.FilterFactory"))),
1046 					uno::UNO_QUERY);
1047 				try {
1048 					if(xNameAccess.is() &&
1049 					   (xNameAccess->getByName(aFilterName) >>= aSeq))
1050 					{
1051 						for(sal_Int32 j = 0; j < aSeq.getLength(); ++j)
1052 							if(aSeq[j].Name ==
1053 							   rtl::OUString(
1054 								   RTL_CONSTASCII_USTRINGPARAM("UIName")))
1055 							{
1056 								aSeq[j].Value >>= m_aFilterName;
1057 								break;
1058 							}
1059 					}
1060 				}
1061 				catch(const uno::Exception& ) {
1062 					// nothing better to do here
1063 					m_aFilterName = aFilterName;
1064 				}
1065 			}
1066 		}
1067 		// set the title
1068 		uno::Reference<beans::XPropertySet> xPropSet(
1069 			m_xFrame,uno::UNO_QUERY);
1070 		if(xPropSet.is()) {
1071 			uno::Any aAny;
1072 			static const sal_Unicode u[] = { ' ','(',0 };
1073 			static const sal_Unicode c[] = { ')',0 };
1074 			rtl::OUString aTotalName(m_aFilterName);
1075 			aTotalName += rtl::OUString(u);
1076 			aTotalName += aDocumentName;
1077 			aTotalName += rtl::OUString(c);
1078 			aAny <<= aTotalName;
1079 			try {
1080 				xPropSet->setPropertyValue(
1081 					rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")),
1082 					aAny);
1083 			}
1084 			catch( const uno::Exception& ) {
1085 			}
1086 		}
1087 	}
1088 
1089 	m_aDocumentNamePart = aDocumentName;
1090 
1091 	if(m_pInterceptor)
1092 	{
1093 		::osl::ClearableMutexGuard aGuard( m_aMutex );
1094 
1095 		Interceptor* pTmpInter = NULL;
1096 		uno::Reference< frame::XDispatchProviderInterceptor > xLock( m_xInterceptorLocker );
1097 		if ( xLock.is() && m_pInterceptor )
1098 			pTmpInter = m_pInterceptor;
1099 
1100 		aGuard.clear();
1101 
1102 		if ( pTmpInter )
1103 			pTmpInter->generateFeatureStateEvent();
1104 	}
1105 }
1106 
1107 
setContainerName(const rtl::OUString & aContainerName)1108 void DocumentHolder::setContainerName(const rtl::OUString& aContainerName)
1109 {
1110 	m_aContainerName = aContainerName;
1111 }
1112 
1113 
hide()1114 void DocumentHolder::hide()
1115 {
1116 	if(m_xFrame.is()) m_xFrame->deactivate();
1117 
1118 	//todo: sendadvise
1119 	// after hiding the window it is always allowed to InPlaceActivate it
1120 	m_bAllowInPlace = true;
1121 }
1122 
GetIDispatch()1123 IDispatch* DocumentHolder::GetIDispatch()
1124 {
1125 	if ( !m_pIDispatch && m_xDocument.is() )
1126 	{
1127 		const ::rtl::OUString aServiceName (
1128 			RTL_CONSTASCII_USTRINGPARAM (
1129 				"com.sun.star.bridge.OleBridgeSupplier2" ) );
1130 		uno::Reference< bridge::XBridgeSupplier2 > xSupplier(
1131 			m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY );
1132 
1133 		if ( xSupplier.is() )
1134 		{
1135 			uno::Sequence< sal_Int8 > aProcId( 16 );
1136 			rtl_getGlobalProcessId( (sal_uInt8*)aProcId.getArray() );
1137 
1138 			try {
1139 				uno::Any anyResult = xSupplier->createBridge(
1140 					uno::makeAny( m_xDocument ),
1141 					aProcId,
1142 					bridge::ModelDependent::UNO,
1143 					bridge::ModelDependent::OLE );
1144 
1145 				if ( anyResult.getValueTypeClass() ==
1146 					 getCppuType((sal_uInt32*) 0).getTypeClass() )
1147 				{
1148 					VARIANT* pVariant = *(VARIANT**)anyResult.getValue();
1149 					if ( pVariant->vt == VT_DISPATCH )
1150 						m_pIDispatch = pVariant->pdispVal;
1151 
1152 					VariantClear( pVariant );
1153 					CoTaskMemFree( pVariant );
1154 				}
1155 			}
1156 			catch ( uno::Exception& )
1157 			{}
1158 		}
1159 	}
1160 
1161 	return m_pIDispatch;
1162 }
1163 
1164 #if 0
1165 HRESULT DocumentHolder::SetVisArea( const RECTL *pRect )
1166 {
1167 	if ( pRect && m_xDocument.is() )
1168 	{
1169 		uno::Sequence< beans::PropertyValue > aArgs = m_xDocument->getArgs();
1170 		for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
1171 			if ( aArgs[nInd].Name.equalsAscii( "WinExtent" ) )
1172 			{
1173 				// should always be there
1174 				uno::Sequence< sal_Int32 > aRect(4);
1175 
1176 				aRect[0] = pRect->left;
1177 				aRect[1] = pRect->top;
1178 				aRect[2] = pRect->right;
1179 				aRect[3] = pRect->bottom;
1180 
1181 				aArgs[nInd].Value <<= aRect;
1182 
1183 				m_xDocument->attachResource( m_xDocument->getURL(), aArgs );
1184 				return S_OK;
1185 			}
1186 
1187 		OSL_ENSURE( sal_False, "WinExtent seems not to be implemented!\n" );
1188 	}
1189 
1190 	return E_FAIL;
1191 }
1192 
1193 HRESULT DocumentHolder::GetVisArea( RECTL *pRect )
1194 {
1195 	if ( pRect && m_xDocument.is() )
1196 	{
1197 		uno::Sequence< beans::PropertyValue > aArgs = m_xDocument->getArgs();
1198 		for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
1199 			if ( aArgs[nInd].Name.equalsAscii( "WinExtent" ) )
1200 			{
1201 				uno::Sequence< sal_Int32 > aRect;
1202 				if ( ( aArgs[nInd].Value >>= aRect ) && aRect.getLength() == 4 )
1203 				{
1204 					pRect->left   = aRect[0];
1205 					pRect->top    = aRect[1];
1206 					pRect->right  = aRect[2];
1207 					pRect->bottom = aRect[3];
1208 
1209 					return S_OK;
1210 				}
1211 
1212 				break;
1213 			}
1214 	}
1215 
1216 	return E_FAIL;
1217 }
1218 #endif
1219 
GetDocumentBorder(RECT * pRect)1220 HRESULT DocumentHolder::GetDocumentBorder( RECT *pRect )
1221 {
1222 	if ( pRect && m_xDocument.is() )
1223 	{
1224 		uno::Sequence< beans::PropertyValue > aArgs = m_xDocument->getArgs();
1225 		for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
1226             if ( aArgs[nInd].Name.equalsAscii( "DocumentBorder" ) )
1227 			{
1228 				uno::Sequence< sal_Int32 > aRect;
1229 				if ( ( aArgs[nInd].Value >>= aRect ) && aRect.getLength() == 4 )
1230 				{
1231 					pRect->left   = aRect[0];
1232 					pRect->top    = aRect[1];
1233 					pRect->right  = aRect[2];
1234 					pRect->bottom = aRect[3];
1235 
1236 					return S_OK;
1237 				}
1238 
1239 				break;
1240 			}
1241 	}
1242 
1243 	return E_FAIL;
1244 }
1245 
SetExtent(const SIZEL * pSize)1246 HRESULT DocumentHolder::SetExtent( const SIZEL *pSize )
1247 {
1248 	if ( pSize )
1249 	{
1250 		uno::Reference< embed::XVisualObject > xVisObj( m_xDocument, uno::UNO_QUERY );
1251 		if ( xVisObj.is() )
1252 		{
1253 			try
1254 			{
1255 				awt::Size aNewSize( pSize->cx, pSize->cy );
1256 
1257 				sal_Int32 aMapMode = xVisObj->getMapUnit( DVASPECT_CONTENT );
1258 
1259 				// TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1260 				if ( aMapMode == embed::EmbedMapUnits::TWIP )
1261 				{
1262 					// conversion from ONE_100TH_MM
1263 					aNewSize.Width = aNewSize.Width * 144 / 254;
1264 					aNewSize.Height = aNewSize.Height * 144 / 254;
1265 				}
1266 
1267 
1268 				xVisObj->setVisualAreaSize( DVASPECT_CONTENT, aNewSize );
1269 
1270 				return S_OK;
1271 			}
1272 			catch( uno::Exception& )
1273 			{}
1274 		}
1275 	}
1276 
1277 	return E_FAIL;
1278 }
1279 
GetExtent(SIZEL * pSize)1280 HRESULT DocumentHolder::GetExtent( SIZEL *pSize )
1281 {
1282 	if ( pSize )
1283 	{
1284 		uno::Reference< embed::XVisualObject > xVisObj( m_xDocument, uno::UNO_QUERY );
1285 		if ( xVisObj.is() )
1286 		{
1287 			try
1288 			{
1289 				awt::Size aDocSize = xVisObj->getVisualAreaSize( DVASPECT_CONTENT );
1290 
1291 				sal_Int32 aMapMode = xVisObj->getMapUnit( DVASPECT_CONTENT );
1292 
1293 				// TODO/LATER: in future UNO API should be used for the conversion, currently there is no
1294 				if ( aMapMode == embed::EmbedMapUnits::TWIP )
1295 				{
1296 					// conversion to ONE_100TH_MM
1297 					aDocSize.Width = aDocSize.Width * 254 / 144;
1298 					aDocSize.Height = aDocSize.Height * 254 / 144;
1299 				}
1300 
1301 				pSize->cx = aDocSize.Width;
1302 				pSize->cy = aDocSize.Height;
1303 
1304 				return S_OK;
1305 			}
1306 			catch( uno::Exception& )
1307 			{}
1308 		}
1309 	}
1310 
1311 	return E_FAIL;
1312 }
1313 
1314 
SetContRects(LPCRECT aRect)1315 HRESULT DocumentHolder::SetContRects(LPCRECT aRect)
1316 {
1317 	if(m_xContainerWindow.is()) {
1318 		RECT wi;
1319         memset(&wi,0,sizeof(wi));
1320 		if(m_pIOleIPFrame) {
1321 			m_pIOleIPFrame->GetBorder((LPRECT)&wi);
1322 			m_xContainerWindow->setPosSize(
1323 				0,0,
1324 				wi.right - wi.left,
1325 				wi.bottom - wi.top,
1326 				awt::PosSize::POSSIZE);
1327 		}
1328 		else
1329 	       m_xContainerWindow->setPosSize(
1330 			0,0,
1331             aRect->right - aRect->left,
1332             aRect->bottom - aRect->top,
1333             awt::PosSize::POSSIZE);
1334         return NOERROR;
1335     }
1336     else {
1337         return ERROR;
1338     }
1339 }
1340 
1341 
SetObjectRects(LPCRECT aRect,LPCRECT aClip)1342 HRESULT DocumentHolder::SetObjectRects(LPCRECT aRect, LPCRECT aClip)
1343 {
1344     ((LPRECT)aRect)->left -= m_aBorder.left;
1345     ((LPRECT)aRect)->right += m_aBorder.right;
1346     ((LPRECT)aRect)->top -= m_aBorder.top;
1347     ((LPRECT)aRect)->bottom += m_aBorder.bottom;
1348     ((LPRECT)aClip)->left -= m_aBorder.left;
1349     ((LPRECT)aClip)->right += m_aBorder.right;
1350     ((LPRECT)aClip)->top -= m_aBorder.top;
1351     ((LPRECT)aClip)->bottom += m_aBorder.bottom;
1352 
1353 	if(m_pCHatchWin)
1354 		m_pCHatchWin->RectsSet((LPRECT)aRect, (LPRECT)aClip);
1355 	if(m_xEditWindow.is()) {
1356         m_xEditWindow->setVisible(false);
1357         m_xEditWindow->setPosSize(
1358             m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0,
1359             m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0,
1360             aRect->right - aRect->left,
1361             aRect->bottom - aRect->top,
1362             awt::PosSize::POSSIZE);
1363         m_xEditWindow->setVisible(true);
1364     }
1365 	return NOERROR;
1366 }
1367 
1368 
1369 ::com::sun::star::uno::Reference<
1370     ::com::sun::star::awt::XWindow> SAL_CALL
getContainerWindow()1371 DocumentHolder::getContainerWindow(
1372 )
1373     throw (
1374         ::com::sun::star::uno::RuntimeException
1375     )
1376 {
1377     if(m_xContainerWindow.is())
1378         return m_xContainerWindow;
1379 
1380     uno::Reference<awt::XWindow> xWin(0);
1381 
1382     static const ::rtl::OUString aToolkitServiceName(
1383         RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.awt.Toolkit" ) );
1384     uno::Reference<awt::XSystemChildFactory> xToolkit(
1385         m_xFactory->createInstance(aToolkitServiceName ),uno::UNO_QUERY);
1386 
1387     if(xToolkit.is() && m_pIOleIPFrame) {
1388         HWND hWnd;
1389         m_pIOleIPFrame->GetWindow(&hWnd);
1390 
1391         uno::Sequence<sal_Int8> aProcessIdent(16);
1392         rtl_getGlobalProcessId((sal_uInt8*)aProcessIdent.getArray());
1393 
1394         uno::Any aAny;
1395         aAny <<= sal_Int32(hWnd);
1396         xWin = uno::Reference<awt::XWindow>(
1397             xToolkit->createSystemChild(
1398                 aAny,
1399                 aProcessIdent,
1400                 lang::SystemDependent::SYSTEM_WIN32),
1401             uno::UNO_QUERY);
1402 
1403         RECT wi;
1404         memset(&wi,0,sizeof(wi));
1405 		if(xWin.is() && m_pIOleIPFrame->GetBorder((LPRECT)&wi) == NOERROR) {
1406             xWin->setVisible(true);
1407             xWin->setPosSize(
1408                 0,0,
1409                 wi.right-wi.left,
1410                 wi.bottom - wi.top,
1411                 awt::PosSize::POSSIZE);
1412 
1413             uno::Reference<awt::XSystemDependentWindowPeer> xSysWin(
1414                 xWin,uno::UNO_QUERY);
1415             if(xSysWin.is()) {
1416                 aAny = xSysWin->getWindowHandle(
1417                     aProcessIdent,lang::SystemDependent::SYSTEM_WIN32);
1418                 sal_Int32 tmp;
1419                 if( aAny >>= tmp )
1420                     SetContainerWindowHandle((HWND) tmp);
1421             }
1422         }
1423     }
1424 
1425     m_xContainerWindow= xWin;
1426     return xWin;
1427 }
1428 
1429 
1430 
1431 sal_Bool SAL_CALL
requestDockingAreaSpace(const::com::sun::star::awt::Rectangle & RequestedSpace)1432 DocumentHolder::requestDockingAreaSpace(
1433     const ::com::sun::star::awt::Rectangle& RequestedSpace
1434 )
1435     throw(
1436         ::com::sun::star::uno::RuntimeException
1437     )
1438 {
1439     if(m_bOnDeactivate)
1440         return sal_True;
1441 
1442     BORDERWIDTHS bw;
1443     SetRect((LPRECT)&bw,
1444             RequestedSpace.X,RequestedSpace.Y,
1445             RequestedSpace.Width,RequestedSpace.Height);
1446     if( m_pIOleIPFrame )
1447         return m_pIOleIPFrame->RequestBorderSpace(&bw) == NOERROR ;
1448     else
1449         return sal_Bool(false);
1450 }
1451 
1452 
1453 void SAL_CALL
setDockingAreaSpace(const::com::sun::star::awt::Rectangle & BorderSpace)1454 DocumentHolder::setDockingAreaSpace(
1455     const ::com::sun::star::awt::Rectangle& BorderSpace
1456 )
1457     throw (
1458         ::com::sun::star::uno::RuntimeException
1459     )
1460 {
1461     if(m_bOnDeactivate)
1462         return;
1463 
1464     BORDERWIDTHS bw;
1465     SetRect((LPRECT)&bw,
1466             BorderSpace.X,BorderSpace.Y,
1467             BorderSpace.Width,BorderSpace.Height);
1468     if( m_pIOleIPFrame ) {
1469         RECT aRect;
1470         GetClientRect(m_hWndxWinCont,&aRect);
1471         HRGN hrgn1 = CreateRectRgn(
1472             0,0,
1473             aRect.right,BorderSpace.Y);
1474         HRGN hrgn2 = CreateRectRgn(aRect.right-BorderSpace.Width,0,aRect.right,aRect.bottom);
1475         CombineRgn(hrgn1,hrgn1,hrgn2,RGN_OR);
1476         DeleteObject(hrgn2);
1477         hrgn2 = CreateRectRgn(0,aRect.bottom-BorderSpace.Height,aRect.right,aRect.bottom);
1478         CombineRgn(hrgn1,hrgn1,hrgn2,RGN_OR);
1479         DeleteObject(hrgn2);
1480         hrgn2 = CreateRectRgn(0,0,BorderSpace.X,aRect.bottom);
1481         CombineRgn(hrgn1,hrgn1,hrgn2,RGN_OR);
1482         DeleteObject(hrgn2);
1483 
1484         SetWindowRgn(m_hWndxWinCont,hrgn1,true);
1485         // not:: DeleteObject(hrgn1);
1486         m_pIOleIPFrame->SetBorderSpace(&bw);
1487     }
1488 }
1489 
1490 
1491 void SAL_CALL
disposing(const com::sun::star::lang::EventObject & aSource)1492 DocumentHolder::disposing(
1493 	const com::sun::star::lang::EventObject& aSource
1494 )
1495 		throw( uno::RuntimeException )
1496 {
1497 	if ( m_xDocument.is() && m_xDocument == aSource.Source )
1498 	{
1499 		m_pIDispatch = NULL;
1500 		m_xDocument = uno::Reference< frame::XModel >();
1501 	}
1502 
1503 	if( m_xFrame.is() && m_xFrame == aSource.Source )
1504 		m_xFrame = uno::Reference< frame::XFrame >();
1505 }
1506 
1507 
1508 void SAL_CALL
queryClosing(const lang::EventObject & aSource,sal_Bool)1509 DocumentHolder::queryClosing(
1510 	const lang::EventObject& aSource,
1511 	sal_Bool /*bGetsOwnership*/
1512 )
1513 	throw(
1514 		util::CloseVetoException
1515 	)
1516 {
1517 	if ( !m_bLink
1518 	  && ( m_xDocument.is() && m_xDocument == aSource.Source || m_xFrame.is() && m_xFrame == aSource.Source ) )
1519 		throw util::CloseVetoException();
1520 }
1521 
1522 
1523 void SAL_CALL
notifyClosing(const lang::EventObject & aSource)1524 DocumentHolder::notifyClosing(
1525 	const lang::EventObject& aSource )
1526 		throw( uno::RuntimeException )
1527 {
1528 	try
1529 	{
1530 		uno::Reference< util::XCloseBroadcaster > xEventBroadcaster(
1531 			aSource.Source, uno::UNO_QUERY_THROW );
1532 		xEventBroadcaster->removeCloseListener( (util::XCloseListener*)this );
1533 	}
1534 	catch( uno::Exception& )
1535 	{}
1536 
1537 	if ( m_xDocument.is() && m_xDocument == aSource.Source )
1538 	{
1539 		// can happen only in case of links
1540 		m_pIDispatch = NULL;
1541 		m_xDocument = uno::Reference< frame::XModel >();
1542 		m_xFrame = uno::Reference< frame::XFrame >();
1543 
1544 		LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument();
1545 		if ( aDocLock.GetEmbedDocument() )
1546             aDocLock.GetEmbedDocument()->OLENotifyClosing();
1547 	}
1548 	else if( m_xFrame.is() && m_xFrame == aSource.Source )
1549 		m_xFrame = uno::Reference< frame::XFrame >();
1550 }
1551 
1552 void SAL_CALL
queryTermination(const lang::EventObject &)1553 DocumentHolder::queryTermination(
1554     const lang::EventObject& /*aSource*/
1555 )
1556 	throw(
1557 		frame::TerminationVetoException
1558 	)
1559 {
1560 	if ( m_xDocument.is() )
1561 		throw frame::TerminationVetoException();
1562 }
1563 
1564 void SAL_CALL
notifyTermination(const lang::EventObject & aSource)1565 DocumentHolder::notifyTermination(
1566 	const lang::EventObject& aSource
1567 )
1568 		throw( uno::RuntimeException )
1569 {
1570 	OSL_ENSURE( !m_xDocument.is(), "Just a disaster..." );
1571 	uno::Reference< frame::XDesktop > xDesktop(
1572         aSource.Source, uno::UNO_QUERY );
1573 
1574 	if ( xDesktop.is() )
1575 		xDesktop->removeTerminateListener( (frame::XTerminateListener*)this );
1576 }
1577 
1578 
1579 
modified(const lang::EventObject &)1580 void SAL_CALL DocumentHolder::modified( const lang::EventObject& /*aEvent*/ )
1581 	throw (uno::RuntimeException)
1582 {
1583 	if ( m_xOleAccess.is() )
1584 	{
1585 		LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument();
1586 		if ( aDocLock.GetEmbedDocument() )
1587             aDocLock.GetEmbedDocument()->notify();
1588 	}
1589 }
1590 
1591 
1592 
1593 //     if(m_pOLEInterface->GetGUID() == OID_WriterTextServer) {
1594 //         // edit group
1595 //         CopyToOLEMenu(m_nMenuHandle,1,hMenu,(WORD)mgw.width[0]);
1596 //         CopyToOLEMenu(m_nMenuHandle,2,hMenu,1+(WORD)mgw.width[0]);
1597 //         CopyToOLEMenu(m_nMenuHandle,3,hMenu,2+(WORD)mgw.width[0]);
1598 //         CopyToOLEMenu(m_nMenuHandle,4,hMenu,3+(WORD)mgw.width[0]);
1599 //         mgw.width[1]=4;
1600 
1601 //         // object group
1602 //         CopyToOLEMenu(
1603 //             m_nMenuHandle,5,
1604 //             hMenu,4+(WORD)mgw.width[0]+(WORD)mgw.width[2]);
1605 //         mgw.width[3]=1;
1606 
1607 //         // help group
1608 //         CopyToOLEMenu(
1609 //             m_nMenuHandle,7,
1610 //             hMenu,5+(WORD)mgw.width[0]+(WORD)mgw.width[2]+(WORD)mgw.width[4]);
1611 //         mgw.width[5]=1;
1612 //     }
1613 //     else if(m_pOLEInterface->GetGUID() == OID_CalcServer) {
1614 //         // edit group
1615 //         CopyToOLEMenu(m_nMenuHandle,1,hMenu,(WORD)mgw.width[0]);
1616 //         CopyToOLEMenu(m_nMenuHandle,2,hMenu,1+(WORD)mgw.width[0]);
1617 //         CopyToOLEMenu(m_nMenuHandle,3,hMenu,2+(WORD)mgw.width[0]);
1618 //         CopyToOLEMenu(m_nMenuHandle,4,hMenu,3+(WORD)mgw.width[0]);
1619 //         mgw.width[1]=4;
1620 
1621 //         // object group
1622 //         CopyToOLEMenu(
1623 //             m_nMenuHandle,5,
1624 //             hMenu,4+(WORD)mgw.width[0]+(WORD)mgw.width[2]);
1625 //         CopyToOLEMenu(
1626 //             m_nMenuHandle,6,
1627 //             hMenu,5+(WORD)mgw.width[0]+(WORD)mgw.width[2]);
1628 //         mgw.width[3]=2;
1629 
1630 //         // help group
1631 //         CopyToOLEMenu(
1632 //             m_nMenuHandle,8,
1633 //             hMenu,6+(WORD)mgw.width[0]+(WORD)mgw.width[2]+(WORD)mgw.width[4]);
1634 //         mgw.width[5]=1;
1635 //     }
1636 
1637 // Fix strange warnings about some
1638 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
1639 // warning C4505: 'xxx' : unreferenced local function has been removed
1640 #if defined(_MSC_VER)
1641 #pragma warning(disable: 4505)
1642 #endif
1643