xref: /AOO41X/main/embedserv/source/embed/docholder.cxx (revision f78e906fe6611930dd4144841172bc2d210ddf78)
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 allways 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                     // convertion 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                     // convertion 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