diff options
Diffstat (limited to 'embedserv/source')
35 files changed, 11648 insertions, 0 deletions
diff --git a/embedserv/source/embed/docholder.cxx b/embedserv/source/embed/docholder.cxx new file mode 100644 index 000000000000..2e214a9c8a79 --- /dev/null +++ b/embedserv/source/embed/docholder.cxx @@ -0,0 +1,1649 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: docholder.cxx,v $ + * $Revision: 1.31.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + + +#include "xwin.hxx" +#include "docholder.hxx" +#include "embeddoc.hxx" +#include "intercept.hxx" +#include "syswinwrapper.hxx" +#include "iipaobj.hxx" + +#include "common.h" +#include <Windows.h> +#include <com/sun/star/lang/SystemDependent.hpp> +#include <com/sun/star/awt/XSystemChildFactory.hpp> +#ifndef _COM_SUN_STAR_AWT_XSYSTEMDEPENDENTWINDOWPERR_HPP_ +#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> +#endif +#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp> +#include <com/sun/star/ui/XUIElement.hpp> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/util/XCloseBroadcaster.hpp> +#include <com/sun/star/util/XCloseAble.hpp> +#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACESS_HPP_ +#include <com/sun/star/container/XNameAccess.hpp> +#endif +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/frame/XStatusListener.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> +#include <com/sun/star/frame/XDispatchProviderInterception.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XView.hpp> +#include <com/sun/star/bridge/XBridgeSupplier2.hpp> +#include <com/sun/star/bridge/ModelDependent.hpp> +#include <com/sun/star/embed/EmbedMapUnits.hpp> +#include <com/sun/star/embed/XVisualObject.hpp> +#include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <osl/diagnose.h> +#include <rtl/process.h> + +using namespace ::com::sun::star; + +extern ::rtl::OUString getFilterNameFromGUID_Impl( GUID* ); + +// add mutex locking ??? + +DocumentHolder::DocumentHolder( + const uno::Reference<lang::XMultiServiceFactory >& xFactory, + const ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl >& xOleAccess ) + : + m_bAllowInPlace(true), + m_pIOleIPSite(0), + m_pIOleIPFrame(0), + m_pIOleIPUIWindow(0), + m_pCHatchWin(0), + m_xOleAccess( xOleAccess ), + m_pInterceptor(0), + m_xFactory( xFactory ), + m_bOnDeactivate(false), + m_hWndxWinParent(NULL), + m_hWndxWinCont(NULL), + m_nMenuHandle(NULL), + m_nMenuShared(NULL), + m_nOLEMenu(NULL), + m_nMacroExecMode( document::MacroExecMode::USE_CONFIG ), + m_bLink( sal_False ) +{ + static const ::rtl::OUString aServiceName ( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); + uno::Reference< frame::XDesktop > xDesktop( + m_xFactory->createInstance( aServiceName ), + uno::UNO_QUERY ); + if ( xDesktop.is() ) + xDesktop->addTerminateListener( (frame::XTerminateListener*)this ); +} + + +DocumentHolder::~DocumentHolder() +{ + delete m_pCHatchWin; + + ClearInterceptorInternally(); +} + + +void DocumentHolder::LoadDocInFrame( sal_Bool bPluginMode ) +{ + uno::Reference<frame::XComponentLoader> xComponentLoader( + m_xFrame,uno::UNO_QUERY); + if( xComponentLoader.is() && m_xDocument.is() ) + { + uno::Reference< task::XInteractionHandler > xHandler( + m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), + uno::UNO_QUERY ); + + uno::Any aAny; + sal_Int32 nLen = 3; + uno::Sequence<beans::PropertyValue> aSeq( nLen ); + + aAny <<= uno::Reference<uno::XInterface>( + m_xDocument, uno::UNO_QUERY); + aSeq[0] = beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Model")), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE); + + aAny <<= sal_False; + aSeq[1] = beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("ReadOnly")), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE); + + aAny <<= (sal_Bool) sal_True; + aSeq[2] = beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("NoAutoSave")), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE); + + if ( bPluginMode ) + { + aSeq.realloc( ++nLen ); + aAny <<= (sal_Int16) 3; + aSeq[nLen-1] = beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("PluginMode")), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE); + } + + if ( xHandler.is() ) + { + aSeq.realloc( nLen+=2 ); + aAny <<= xHandler; + aSeq[nLen-2] = beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE); + + aAny <<= m_nMacroExecMode; + aSeq[nLen-1] = beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode")), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE); + } + + xComponentLoader->loadComponentFromURL( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("private:object")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")), + 0, + aSeq); + + uno::Sequence< beans::PropertyValue > aResArgs = m_xDocument->getArgs(); + for ( int nInd = 0; nInd < aResArgs.getLength(); nInd++ ) + if ( aResArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MacroExecutionMode" ) ) ) ) + { + aResArgs[nInd].Value >>= m_nMacroExecMode; + break; + } + } +} + +void DocumentHolder::OnPosRectChanged(LPRECT lpRect) const +{ + lpRect->left += m_aBorder.left; + lpRect->right -= m_aBorder.right; + lpRect->top += m_aBorder.top; + lpRect->bottom -= m_aBorder.bottom; + if(m_pIOleIPSite) + m_pIOleIPSite->OnPosRectChange(lpRect); +} + + + +void DocumentHolder::DisableInplaceActivation(BOOL b) +{ + m_bAllowInPlace = ! b; +} + +BOOL DocumentHolder::isActive() const +{ + return m_pIOleIPSite != 0; +} + +HRESULT DocumentHolder::InPlaceActivate( + LPOLECLIENTSITE pActiveSite, + BOOL fIncludeUI) +{ + m_bOnDeactivate = false; + + if(!m_bAllowInPlace) + return ERROR; + + HRESULT hr; + HWND hWndSite; + RECT rcPos; + RECT rcClip; + OLEINPLACEFRAMEINFO frameInfo; + + if (NULL==pActiveSite) + return ResultFromScode(E_INVALIDARG); + + if (NULL!=m_pIOleIPSite) + { + if (fIncludeUI) + UIActivate(); + + return NOERROR; + } + + if ( !m_xDocument.is() ) + return ERROR; + + //1. Initialization, obtaining interfaces, OnInPlaceActivate. + hr=pActiveSite->QueryInterface( + IID_IOleInPlaceSite, + (void**) &m_pIOleIPSite); + + if (FAILED(hr)) + return hr; + + hr=m_pIOleIPSite->CanInPlaceActivate(); + + if (NOERROR!=hr) + { + m_pIOleIPSite->Release(), m_pIOleIPSite=NULL; + return ResultFromScode(E_FAIL); + } + + m_pIOleIPSite->OnInPlaceActivate(); + + //2. Get the site window + //3. and determine container frame and + // document window for tools and menus, as well + // as frameInfo for accelerators + m_pIOleIPSite->GetWindow(&hWndSite); + + frameInfo.cb=sizeof(OLEINPLACEFRAMEINFO); + m_pIOleIPSite->GetWindowContext( + &m_pIOleIPFrame,&m_pIOleIPUIWindow,&rcPos,&rcClip,&frameInfo); + + // initialize the office as, with hwnd as parentwindow + uno::Any aAny; + uno::Sequence<sal_Int8> aProcessIdent(16); + rtl_getGlobalProcessId((sal_uInt8*)aProcessIdent.getArray()); + + try + { + if(!m_xEditWindow.is()) + { // determine XWindow and window handle of parent + HWND hWndxWinParent(0); + uno::Reference<awt::XWindow> xWin; + + static const ::rtl::OUString aToolkitServiceName( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.awt.Toolkit" ) ); + uno::Reference<awt::XSystemChildFactory> xToolkit( + m_xFactory->createInstance(aToolkitServiceName ),uno::UNO_QUERY); + + if(xToolkit.is()) { + // create system window wrapper for hwnd + if( !m_pCHatchWin ) + m_pCHatchWin = new winwrap::CHatchWin( + m_hInstance,this); + + if(m_pCHatchWin->Init(hWndSite,/*ID_HATCHWINDOW*/2000, NULL)) { + m_pCHatchWin->RectsSet(&rcPos,&rcClip); //set visible area + hWndxWinParent = m_pCHatchWin->Window(); + ShowWindow(hWndxWinParent,SW_SHOW); //Make visible. + } + else { + // no success initializing hatch window + delete m_pCHatchWin, m_pCHatchWin = 0; + hWndxWinParent = hWndSite; + } + + aAny <<= sal_Int32(hWndxWinParent); + xWin = uno::Reference<awt::XWindow>( + xToolkit->createSystemChild( + aAny, + aProcessIdent, + lang::SystemDependent::SYSTEM_WIN32), + uno::UNO_QUERY); + } + + if(xWin.is()) { + xWin->setPosSize( + m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0, + m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0, + rcPos.right-rcPos.left, + rcPos.bottom - rcPos.top, + awt::PosSize::POSSIZE); + xWin->setVisible(sal_True); + + m_xEditWindow = xWin; + m_hWndxWinParent = hWndxWinParent; + } + else + return ERROR; + } + else { + if(m_hWndxWinParent) { + SetParent(m_hWndxWinParent,hWndSite); + ShowWindow(m_hWndxWinParent,SW_SHOW); //Make visible. + } + + if ( !m_xFrame.is() ) + // initially set size to "empty", this guarantees that the final resize + // is always executed (will be done by "SetObjectRects" after getting internal border) + m_xEditWindow->setPosSize( + 0, + 0, + 0, + 0, + awt::PosSize::POSSIZE); + m_xEditWindow->setVisible(sal_True); + } + + if(m_xContainerWindow.is()) { + if(m_hWndxWinCont) { + if(m_pIOleIPFrame) { + HWND hWndCont; + m_pIOleIPFrame->GetWindow(&hWndCont); + SetParent(m_hWndxWinCont,hWndCont); + ShowWindow(m_hWndxWinCont,SW_SHOW); + } + } + m_xContainerWindow->setVisible(true); + } + + if(m_xFrame.is()) + m_xFrame->activate(); + else { + // create frame and initialize it with with the created window + static const ::rtl::OUString aFrameServiceName( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Frame" ) ); + m_xFrame = uno::Reference<frame::XFrame>( + m_xFactory->createInstance(aFrameServiceName), + uno::UNO_QUERY); + + if(!m_xFrame.is()) + return ERROR; + + m_xFrame->initialize(m_xEditWindow); + + uno::Reference<frame::XDispatchProviderInterception> + xDPI(m_xFrame,uno::UNO_QUERY); + if(xDPI.is()) + xDPI->registerDispatchProviderInterceptor( CreateNewInterceptor() ); + + uno::Reference<beans::XPropertySet> xPS(m_xFrame,uno::UNO_QUERY); + if( xPS.is() ) + { + aAny = xPS->getPropertyValue( + rtl::OUString::createFromAscii("LayoutManager")); + aAny >>= m_xLayoutManager; + } + + if(m_xLayoutManager.is()) + m_xLayoutManager->setDockingAreaAcceptor(this); + + // load the model into the frame + LoadDocInFrame( sal_True ); + + static const ::rtl::OUString aDesktopServiceName ( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); + uno::Reference< frame::XFramesSupplier > xDesktop( + m_xFactory->createInstance( aDesktopServiceName ), + uno::UNO_QUERY ); + if(xDesktop.is()) + xDesktop->getFrames()->append(m_xFrame); + + // determine the menuhandle to get menutitems. + if(m_xLayoutManager.is()) { + uno::Reference< ::com::sun::star::ui::XUIElement > xUIEl( + m_xLayoutManager->getElement( + rtl::OUString::createFromAscii( + "private:resource/menubar/menubar"))); + OSL_ENSURE(xUIEl.is(),"no menubar"); + uno::Reference<awt::XSystemDependentMenuPeer> xSDMP( + xUIEl->getRealInterface(), + uno::UNO_QUERY); + aAny = xSDMP->getMenuHandle( + aProcessIdent,lang::SystemDependent::SYSTEM_WIN32); + sal_Int32 tmp; + if( aAny >>= tmp ) + m_nMenuHandle = HMENU(tmp); + m_xLayoutManager->hideElement( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "private:resource/menubar/menubar" ))); + } + } + + // TODO/cd: Workaround for status indicator bug. It always makes the + // document window visible, when someone tries to use the status + // indicator. As we save our document when we get the deactivation + // from OLE this conflict to hide floating windows. + if(m_xLayoutManager.is()) + m_xLayoutManager->setVisible(true); + + // get document border and resize rects according to border + GetDocumentBorder( &m_aBorder ); + SetObjectRects( &rcPos, &rcClip ); + + if ( m_xOleAccess.is() ) + { + LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument(); + if ( aDocLock.GetEmbedDocument() ) + aDocLock.GetEmbedDocument()->ShowObject(); + } + + // setTitle(m_aDocumentNamePart); + if (fIncludeUI) + hr=UIActivate(); + + m_pIOleIPSite->DiscardUndoState(); + } + catch( uno::Exception& ) + { + hr = ERROR; + } + + return hr; +} + + +void DocumentHolder::InPlaceDeactivate(void) +{ + m_bOnDeactivate = true; + + UIDeactivate(); + if(m_xFrame.is()) m_xFrame->deactivate(); + + if(m_xEditWindow.is()) { + m_xEditWindow->setVisible(false); + ShowWindow(m_hWndxWinParent,SW_HIDE); + SetParent(m_hWndxWinParent,0); + } + + if(m_xContainerWindow.is()) { + m_xContainerWindow->setVisible(false); + ShowWindow(m_hWndxWinCont,SW_HIDE); + SetParent(m_hWndxWinCont,0); + } + + // TODO/cd: Workaround for status indicator bug. It always makes the + // document window visible, when someone tries to use the status + // indicator. As we save our document when we get the deactivation + // from OLE this conflict to hide floating windows. + if (m_xLayoutManager.is()) + m_xLayoutManager->setVisible(false); + + if (NULL!=m_pIOleIPSite) + { + // The following workaround should let the object be stored in case of inplace editing +// CComPtr< IOleClientSite > pClientSite; +// +// m_pIOleIPSite->QueryInterface( +// IID_IOleClientSite, (void**)&pClientSite ); +// if ( pClientSite ) +// pClientSite->SaveObject(); + + m_pIOleIPSite->OnInPlaceDeactivate(); + } + + if(m_pIOleIPFrame) m_pIOleIPFrame->Release(); m_pIOleIPFrame = 0; + if(m_pIOleIPUIWindow) m_pIOleIPUIWindow->Release(); m_pIOleIPUIWindow = 0; + if(m_pIOleIPSite) m_pIOleIPSite->Release(); m_pIOleIPSite = 0; + + if ( m_xOleAccess.is() ) + { + LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument(); + if ( aDocLock.GetEmbedDocument() ) + { + aDocLock.GetEmbedDocument()->SaveObject(); + } + } + + return; +} + + +HRESULT DocumentHolder::UIActivate() +{ + // 1. Call IOleInPlaceSite::UIActivate + if (NULL!=m_pIOleIPSite) + m_pIOleIPSite->OnUIActivate(); + + //2. Critical for accelerators to work initially. + SetFocus(m_pCHatchWin->Window()); + // if(m_xEditWindow.is()) m_xEditWindow->setFocus(); + + //3. Set the active object + + OLECHAR starOffice[] = {'S','t','a','r','O','f','f','i','c','e',0}; + CComPtr< IOleInPlaceActiveObject > pObj = new CIIAObj( this ); + + if (NULL!=m_pIOleIPFrame) + m_pIOleIPFrame->SetActiveObject( + pObj, starOffice ); + + if (NULL!=m_pIOleIPUIWindow) + m_pIOleIPUIWindow->SetActiveObject( + pObj, starOffice ); + + //4. Create the shared menu. + InPlaceMenuCreate(); + + return NOERROR; +} + +void DocumentHolder::UIDeactivate() +{ + //1. Remove the shared menu. + InPlaceMenuDestroy(); + + if (NULL!=m_pIOleIPFrame) + m_pIOleIPFrame->SetActiveObject(NULL, NULL); + + if (NULL!=m_pIOleIPUIWindow) + m_pIOleIPUIWindow->SetActiveObject(NULL, NULL); + + //3. Call IOleInPlaceSite::OnUIDeactivate + if (NULL!=m_pIOleIPSite) + m_pIOleIPSite->OnUIDeactivate(FALSE); + + return; +} + +void CopyToOLEMenu(HMENU hOrig,WORD origPos,HMENU hDest,WORD destPos) +{ + HMENU subMenu(NULL); + UINT uTemp = MF_BYPOSITION | MF_POPUP; + char buffer[256]; + + subMenu = GetSubMenu(hOrig,origPos); + GetMenuString(hOrig,origPos,buffer,256,MF_BYPOSITION); + InsertMenu(hDest,destPos,uTemp, + (UINT)subMenu,LPCTSTR(buffer)); + + MENUITEMINFOW mi; + memset(&mi,0,sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.fMask = MIIM_DATA; + if(GetMenuItemInfoW(hOrig,origPos,TRUE,&mi)) + SetMenuItemInfoW(hDest,(WORD)destPos,TRUE,&mi); +} + +BOOL DocumentHolder::InPlaceMenuCreate(void) +{ + HMENU hMenu; + UINT i; + OLEMENUGROUPWIDTHS mgw; + + for (i=0; i<6; i++) + mgw.width[i]=0; + + //We already have popup menu handles in m_pFR->m_phMenu[] + + //Create the new shared menu and let container do its thing + hMenu=CreateMenu(); + m_pIOleIPFrame->InsertMenus(hMenu,&mgw); + + int count = GetMenuItemCount(m_nMenuHandle); + int help = count-1; + + // start with 1, because we don't include "File" + WORD pos = (WORD)mgw.width[0]; + CopyToOLEMenu(m_nMenuHandle,1,hMenu,pos); + mgw.width[1] = 1; + + // insert object menu here + pos = ((WORD)(mgw.width[0] + mgw.width[1] + mgw.width[2])); + for(WORD i = 2; i < help-1; ++i,++pos) + CopyToOLEMenu(m_nMenuHandle,i,hMenu,pos); + mgw.width[3] = help - 3; + + // insert help menu + pos = (WORD)(mgw.width[0] + mgw.width[1] + mgw.width[2] + + mgw.width[3] + mgw.width[4]); + CopyToOLEMenu(m_nMenuHandle,WORD(help),hMenu,pos); + mgw.width[5] = 1; + + m_nMenuShared = hMenu; + m_nOLEMenu = OleCreateMenuDescriptor(m_nMenuShared,&mgw); + + uno::Reference<awt::XSystemDependentWindowPeer> xSysDepWin(m_xContainerWindow,uno::UNO_QUERY); + if(xSysDepWin.is()) { + uno::Sequence<sal_Int8> aProcessIdent(16); + rtl_getGlobalProcessId((sal_uInt8*)aProcessIdent.getArray()); + uno::Any aAny = xSysDepWin->getWindowHandle(aProcessIdent,lang::SystemDependent::SYSTEM_WIN32); + sal_Int32 tmp; + aAny >>= tmp; + HWND aHwnd = (HWND) tmp; + m_pIOleIPFrame->SetMenu( + m_nMenuShared,m_nOLEMenu,aHwnd); + } + else + m_pIOleIPFrame->SetMenu( + m_nMenuShared,m_nOLEMenu,::GetWindow(m_hWndxWinParent,GW_CHILD)); + return TRUE; +} + +BOOL DocumentHolder::InPlaceMenuDestroy(void) +{ + if( NULL == m_nMenuShared ) + return TRUE; + + m_pIOleIPFrame->SetMenu(NULL,NULL,NULL); + + OleDestroyMenuDescriptor(m_nOLEMenu),m_nOLEMenu = NULL; + return TRUE; +} + +void DocumentHolder::OpenIntoWindow(void) +{ + // not implemented +} + +BOOL DocumentHolder::Undo(void) +{ + // not implemented + return false; +} + + +void DocumentHolder::FreeOffice() +{ + const ::rtl::OUString aServiceName( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ); + uno::Reference< frame::XDesktop > xDesktop( + m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); + if ( xDesktop.is() ) + { + xDesktop->removeTerminateListener( + (frame::XTerminateListener*)this ); + } +} + +void DocumentHolder::DisconnectFrameDocument( sal_Bool bComplete ) +{ + try + { + uno::Reference< util::XModifyBroadcaster > xModifiable( m_xDocument, uno::UNO_QUERY_THROW ); + xModifiable->removeModifyListener( (util::XModifyListener*)this ); + } + catch( uno::Exception& ) + {} + + try + { + uno::Reference< util::XCloseBroadcaster > xBroadcaster( + m_xDocument, uno::UNO_QUERY_THROW ); + xBroadcaster->removeCloseListener( (util::XCloseListener*)this ); + } + catch( uno::Exception& ) + {} + + try + { + uno::Reference< util::XCloseBroadcaster > xBroadcaster( + m_xFrame, uno::UNO_QUERY_THROW ); + xBroadcaster->removeCloseListener( (util::XCloseListener*)this ); + } + catch( uno::Exception& ) + {} + + if ( bComplete ) + { + m_xFrame = uno::Reference< frame::XFrame>(); + m_pIDispatch = NULL; + m_xDocument = uno::Reference< frame::XModel >(); + } +} + +void DocumentHolder::CloseDocument() +{ + DisconnectFrameDocument(); + + uno::Reference< util::XCloseable > xCloseable( + m_xDocument, uno::UNO_QUERY ); + + if ( xCloseable.is() ) + { + try + { + xCloseable->close( sal_True ); + } + catch( uno::Exception& ) + {} + } + + m_pIDispatch = NULL; + m_xDocument = uno::Reference< frame::XModel >(); +} + + +void DocumentHolder::CloseFrame() +{ + try + { + uno::Reference< util::XCloseBroadcaster > xBroadcaster( + m_xFrame, uno::UNO_QUERY_THROW ); + xBroadcaster->removeCloseListener( (util::XCloseListener*)this ); + } + catch( uno::Exception& ) + {} + + uno::Reference<util::XCloseable> xCloseable( + m_xFrame,uno::UNO_QUERY); + if(xCloseable.is()) + try { + xCloseable->close(sal_True); + } + catch( const uno::Exception& ) { + } + else { + uno::Reference<lang::XComponent> xComp(m_xFrame,uno::UNO_QUERY); + if(xComp.is()) + xComp->dispose(); + } + + m_xFrame = uno::Reference< frame::XFrame >(); +} + +void DocumentHolder::SetDocument( const uno::Reference< frame::XModel >& xDoc, sal_Bool bLink ) +{ + if ( m_xDocument.is() ) + CloseDocument(); + + m_xDocument = xDoc; + m_bLink = bLink; + + uno::Reference< util::XCloseBroadcaster > xBroadcaster( + m_xDocument, uno::UNO_QUERY ); + + if ( xBroadcaster.is() ) + xBroadcaster->addCloseListener( (util::XCloseListener*)this ); + + if ( m_xDocument.is() && !m_bLink ) + { + // set the document mode to embedded + uno::Sequence< beans::PropertyValue > aSeq(1); + aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" ); + aSeq[0].Value <<= sal_True; + m_xDocument->attachResource(::rtl::OUString(),aSeq); + } +} + +sal_Bool DocumentHolder::ExecuteSuspendCloseFrame() +{ + if ( m_xFrame.is() && m_xFactory.is() ) + { + try + { + uno::Reference< frame::XController > xController = m_xFrame->getController(); + if ( xController.is() ) + { + if ( !xController->suspend( sal_True ) ) + return sal_False; + + FreeOffice(); + try + { + uno::Reference<util::XCloseable> xCloseable( m_xFrame, uno::UNO_QUERY ); + if ( xCloseable.is() ) + xCloseable->close(sal_True); + else + { + uno::Reference<lang::XComponent> xComp( m_xFrame, uno::UNO_QUERY_THROW ); + if( xComp.is() ) + xComp->dispose(); + } + } + catch( const util::CloseVetoException& ) + { + // should be called if the frame could not be closed + xController->suspend( sal_False ); + } + } + } + catch( uno::Exception& ) + { + } + + m_xFrame = uno::Reference< frame::XFrame >(); + } + + return sal_True; +} + +uno::Reference< frame::XFrame > DocumentHolder::DocumentFrame() +{ + if(! m_xFrame.is() ) + { + rtl::OUString aDesktopSrvNm( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")); + + uno::Reference<frame::XDesktop> xDesktop( + m_xFactory->createInstance(aDesktopSrvNm), + uno::UNO_QUERY); + + uno::Reference<frame::XFrame> xFrame( + xDesktop,uno::UNO_QUERY); + + // the frame will be registered on desktop here, later when the document + // is loaded into the frame in ::show() method the terminate listener will be removed + // this is so only for outplace activation + if( xFrame.is() ) + m_xFrame = xFrame->findFrame( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")),0); + + uno::Reference< util::XCloseBroadcaster > xBroadcaster( + m_xFrame, uno::UNO_QUERY ); + + if ( xBroadcaster.is() ) + { + xBroadcaster->addCloseListener( (util::XCloseListener*)this ); + FreeOffice(); // the frame is part of the desktop + } + } + + if( m_xFrame.is() ) + { + // intercept + uno::Reference<frame::XDispatchProviderInterception> + xDPI(m_xFrame,uno::UNO_QUERY); + if(xDPI.is()) + xDPI->registerDispatchProviderInterceptor( CreateNewInterceptor() ); + } + + return m_xFrame; +} + + +uno::Reference< frame::XDispatchProviderInterceptor > DocumentHolder::CreateNewInterceptor() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ClearInterceptorInternally(); + + uno::Reference< frame::XDispatchProviderInterceptor > xInterceptor( m_pInterceptor = new Interceptor( m_xOleAccess, this, m_bLink ) ); + m_xInterceptorLocker = xInterceptor; + return xInterceptor; +} + +void DocumentHolder::ClearInterceptorInternally() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + uno::Reference< frame::XDispatchProviderInterceptor > xInterceptor( m_xInterceptorLocker ); + if ( xInterceptor.is() && m_pInterceptor ) + m_pInterceptor->DisconnectDocHolder(); + + m_xInterceptorLocker = uno::Reference< frame::XDispatchProviderInterceptor >(); + m_pInterceptor = 0; +} + +void DocumentHolder::ClearInterceptor() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_xInterceptorLocker = uno::Reference< frame::XDispatchProviderInterceptor >(); + m_pInterceptor = 0; +} + + +void DocumentHolder::show() +{ + try + { + if(m_xFrame.is()) + { + m_xFrame->activate(); + uno::Reference<awt::XTopWindow> xTopWindow( + m_xFrame->getContainerWindow(),uno::UNO_QUERY); + if(xTopWindow.is()) + xTopWindow->toFront(); + } + else if( DocumentFrame().is() ) + { + LoadDocInFrame( sal_False ); + + // get rid of second closer if it is there + uno::Reference< beans::XPropertySet > xProps( m_xFrame, uno::UNO_QUERY ); + if ( xProps.is() ) + { + uno::Reference< frame::XLayoutManager > xLayoutManager; + xProps->getPropertyValue( rtl::OUString::createFromAscii( "LayoutManager" ) ) >>= xLayoutManager; + uno::Reference< beans::XPropertySet > xLMProps( xLayoutManager, uno::UNO_QUERY ); + if ( xLMProps.is() ) + { + xLMProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MenuBarCloser" ), + uno::makeAny( uno::Reference< frame::XStatusListener >() ) ); + } + } + + if ( !m_bLink ) + { + try + { + uno::Reference< util::XModifyBroadcaster > xModifiable( m_xDocument, uno::UNO_QUERY_THROW ); + xModifiable->addModifyListener( (util::XModifyListener*)this ); + } + catch( uno::Exception& ) + {} + } + + if ( !m_bLink ) + setTitle(m_aDocumentNamePart); + } + } + catch( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Can not show the frame!\n" ); + } + +} + +void DocumentHolder::resizeWin( const SIZEL& rNewSize ) +{ + LockedEmbedDocument_Impl aDocLock; + + if ( m_xOleAccess.is() ) + aDocLock = m_xOleAccess->GetEmbedDocument(); + + if ( m_xFrame.is() && aDocLock.GetEmbedDocument() ) + { + uno::Reference< awt::XWindow > xWindow( + m_xFrame->getContainerWindow(), uno::UNO_QUERY ); + uno::Reference< awt::XView > xView( xWindow, uno::UNO_QUERY ); + + if ( xWindow.is() && xView.is() ) + { + float fScale = 1; + xView->setZoom( fScale, fScale ); + + SIZEL aOldSize; + GetExtent( &aOldSize ); + + if ( aOldSize.cx != rNewSize.cx || aOldSize.cy != rNewSize.cy ) + { + HDC hdc = GetDC( NULL ); + SetMapMode( hdc, MM_HIMETRIC ); + + POINT aOldOffset; + aOldOffset.x = aOldSize.cx; + aOldOffset.y = aOldSize.cy; + BOOL bIsOk = LPtoDP( hdc, &aOldOffset, 1 ); + + POINT aNewOffset; + aNewOffset.x = rNewSize.cx; + aNewOffset.y = rNewSize.cy; + bIsOk = LPtoDP( hdc, &aNewOffset, 1 ); + + ReleaseDC( NULL, hdc ); + + awt::Rectangle aWinRect = xWindow->getPosSize(); + + sal_Int32 aWidthDelta = aWinRect.Width - aOldOffset.x; + sal_Int32 aHeightDelta = aWinRect.Height - aOldOffset.y; + + if ( aWidthDelta > 0 && aHeightDelta > 0 ) + xWindow->setPosSize(0, + 0, + aNewOffset.x + aWidthDelta, + aNewOffset.y + aHeightDelta, + awt::PosSize::SIZE ); + } + } + } +} + +void DocumentHolder::setTitle(const rtl::OUString& aDocumentName) +{ + if(m_xFrame.is()) + { + if(m_aFilterName.getLength() == 0) + { + rtl::OUString aFilterName; + uno::Sequence<beans::PropertyValue> aSeq; + if(m_xDocument.is()) + { + aSeq = + m_xDocument->getArgs(); + for(sal_Int32 j = 0; j < aSeq.getLength(); ++j) + { + if(aSeq[j].Name == + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("FilterName"))) + { + aSeq[j].Value >>= aFilterName; + break; + } + } + } + + if(aFilterName.getLength()) + { + uno::Reference<container::XNameAccess> xNameAccess( + m_xFactory->createInstance( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.document.FilterFactory"))), + uno::UNO_QUERY); + try { + if(xNameAccess.is() && + (xNameAccess->getByName(aFilterName) >>= aSeq)) + { + for(sal_Int32 j = 0; j < aSeq.getLength(); ++j) + if(aSeq[j].Name == + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("UIName"))) + { + aSeq[j].Value >>= m_aFilterName; + break; + } + } + } + catch(const uno::Exception& ) { + // nothing better to do here + m_aFilterName = aFilterName; + } + } + } + // set the title + uno::Reference<beans::XPropertySet> xPropSet( + m_xFrame,uno::UNO_QUERY); + if(xPropSet.is()) { + uno::Any aAny; + static const sal_Unicode u[] = { ' ','(',0 }; + static const sal_Unicode c[] = { ')',0 }; + rtl::OUString aTotalName(m_aFilterName); + aTotalName += rtl::OUString(u); + aTotalName += aDocumentName; + aTotalName += rtl::OUString(c); + aAny <<= aTotalName; + try { + xPropSet->setPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")), + aAny); + } + catch( const uno::Exception& ) { + } + } + } + + m_aDocumentNamePart = aDocumentName; + + if(m_pInterceptor) + { + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + Interceptor* pTmpInter = NULL; + uno::Reference< frame::XDispatchProviderInterceptor > xLock( m_xInterceptorLocker ); + if ( xLock.is() && m_pInterceptor ) + pTmpInter = m_pInterceptor; + + aGuard.clear(); + + if ( pTmpInter ) + pTmpInter->generateFeatureStateEvent(); + } +} + + +void DocumentHolder::setContainerName(const rtl::OUString& aContainerName) +{ + m_aContainerName = aContainerName; +} + + +void DocumentHolder::hide() +{ + if(m_xFrame.is()) m_xFrame->deactivate(); + + //todo: sendadvise + // after hiding the window it is always allowed to InPlaceActivate it + m_bAllowInPlace = true; +} + +IDispatch* DocumentHolder::GetIDispatch() +{ + if ( !m_pIDispatch && m_xDocument.is() ) + { + const ::rtl::OUString aServiceName ( + RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.bridge.OleBridgeSupplier2" ) ); + uno::Reference< bridge::XBridgeSupplier2 > xSupplier( + m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); + + if ( xSupplier.is() ) + { + uno::Sequence< sal_Int8 > aProcId( 16 ); + rtl_getGlobalProcessId( (sal_uInt8*)aProcId.getArray() ); + + try { + uno::Any anyResult = xSupplier->createBridge( + uno::makeAny( m_xDocument ), + aProcId, + bridge::ModelDependent::UNO, + bridge::ModelDependent::OLE ); + + if ( anyResult.getValueTypeClass() == + getCppuType((sal_uInt32*) 0).getTypeClass() ) + { + VARIANT* pVariant = *(VARIANT**)anyResult.getValue(); + if ( pVariant->vt == VT_DISPATCH ) + m_pIDispatch = pVariant->pdispVal; + + VariantClear( pVariant ); + CoTaskMemFree( pVariant ); + } + } + catch ( uno::Exception& ) + {} + } + } + + return m_pIDispatch; +} + +#if 0 +HRESULT DocumentHolder::SetVisArea( const RECTL *pRect ) +{ + if ( pRect && m_xDocument.is() ) + { + uno::Sequence< beans::PropertyValue > aArgs = m_xDocument->getArgs(); + for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ ) + if ( aArgs[nInd].Name.equalsAscii( "WinExtent" ) ) + { + // should allways be there + uno::Sequence< sal_Int32 > aRect(4); + + aRect[0] = pRect->left; + aRect[1] = pRect->top; + aRect[2] = pRect->right; + aRect[3] = pRect->bottom; + + aArgs[nInd].Value <<= aRect; + + m_xDocument->attachResource( m_xDocument->getURL(), aArgs ); + return S_OK; + } + + OSL_ENSURE( sal_False, "WinExtent seems not to be implemented!\n" ); + } + + return E_FAIL; +} + +HRESULT DocumentHolder::GetVisArea( RECTL *pRect ) +{ + if ( pRect && m_xDocument.is() ) + { + uno::Sequence< beans::PropertyValue > aArgs = m_xDocument->getArgs(); + for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ ) + if ( aArgs[nInd].Name.equalsAscii( "WinExtent" ) ) + { + uno::Sequence< sal_Int32 > aRect; + if ( ( aArgs[nInd].Value >>= aRect ) && aRect.getLength() == 4 ) + { + pRect->left = aRect[0]; + pRect->top = aRect[1]; + pRect->right = aRect[2]; + pRect->bottom = aRect[3]; + + return S_OK; + } + + break; + } + } + + return E_FAIL; +} +#endif + +HRESULT DocumentHolder::GetDocumentBorder( RECT *pRect ) +{ + if ( pRect && m_xDocument.is() ) + { + uno::Sequence< beans::PropertyValue > aArgs = m_xDocument->getArgs(); + for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ ) + if ( aArgs[nInd].Name.equalsAscii( "DocumentBorder" ) ) + { + uno::Sequence< sal_Int32 > aRect; + if ( ( aArgs[nInd].Value >>= aRect ) && aRect.getLength() == 4 ) + { + pRect->left = aRect[0]; + pRect->top = aRect[1]; + pRect->right = aRect[2]; + pRect->bottom = aRect[3]; + + return S_OK; + } + + break; + } + } + + return E_FAIL; +} + +HRESULT DocumentHolder::SetExtent( const SIZEL *pSize ) +{ + if ( pSize ) + { + uno::Reference< embed::XVisualObject > xVisObj( m_xDocument, uno::UNO_QUERY ); + if ( xVisObj.is() ) + { + try + { + awt::Size aNewSize( pSize->cx, pSize->cy ); + + sal_Int32 aMapMode = xVisObj->getMapUnit( DVASPECT_CONTENT ); + + // TODO/LATER: in future UNO API should be used for the conversion, currently there is no + if ( aMapMode == embed::EmbedMapUnits::TWIP ) + { + // convertion from ONE_100TH_MM + aNewSize.Width = aNewSize.Width * 144 / 254; + aNewSize.Height = aNewSize.Height * 144 / 254; + } + + + xVisObj->setVisualAreaSize( DVASPECT_CONTENT, aNewSize ); + + return S_OK; + } + catch( uno::Exception& ) + {} + } + } + + return E_FAIL; +} + +HRESULT DocumentHolder::GetExtent( SIZEL *pSize ) +{ + if ( pSize ) + { + uno::Reference< embed::XVisualObject > xVisObj( m_xDocument, uno::UNO_QUERY ); + if ( xVisObj.is() ) + { + try + { + awt::Size aDocSize = xVisObj->getVisualAreaSize( DVASPECT_CONTENT ); + + sal_Int32 aMapMode = xVisObj->getMapUnit( DVASPECT_CONTENT ); + + // TODO/LATER: in future UNO API should be used for the conversion, currently there is no + if ( aMapMode == embed::EmbedMapUnits::TWIP ) + { + // convertion to ONE_100TH_MM + aDocSize.Width = aDocSize.Width * 254 / 144; + aDocSize.Height = aDocSize.Height * 254 / 144; + } + + pSize->cx = aDocSize.Width; + pSize->cy = aDocSize.Height; + + return S_OK; + } + catch( uno::Exception& ) + {} + } + } + + return E_FAIL; +} + + +HRESULT DocumentHolder::SetContRects(LPCRECT aRect) +{ + if(m_xContainerWindow.is()) { + RECT wi; + memset(&wi,0,sizeof(wi)); + if(m_pIOleIPFrame) { + m_pIOleIPFrame->GetBorder((LPRECT)&wi); + m_xContainerWindow->setPosSize( + 0,0, + wi.right - wi.left, + wi.bottom - wi.top, + awt::PosSize::POSSIZE); + } + else + m_xContainerWindow->setPosSize( + 0,0, + aRect->right - aRect->left, + aRect->bottom - aRect->top, + awt::PosSize::POSSIZE); + return NOERROR; + } + else { + return ERROR; + } +} + + +HRESULT DocumentHolder::SetObjectRects(LPCRECT aRect, LPCRECT aClip) +{ + ((LPRECT)aRect)->left -= m_aBorder.left; + ((LPRECT)aRect)->right += m_aBorder.right; + ((LPRECT)aRect)->top -= m_aBorder.top; + ((LPRECT)aRect)->bottom += m_aBorder.bottom; + ((LPRECT)aClip)->left -= m_aBorder.left; + ((LPRECT)aClip)->right += m_aBorder.right; + ((LPRECT)aClip)->top -= m_aBorder.top; + ((LPRECT)aClip)->bottom += m_aBorder.bottom; + + if(m_pCHatchWin) + m_pCHatchWin->RectsSet((LPRECT)aRect, (LPRECT)aClip); + if(m_xEditWindow.is()) { + m_xEditWindow->setVisible(false); + m_xEditWindow->setPosSize( + m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0, + m_pCHatchWin ? HATCHWIN_BORDERWIDTHDEFAULT : 0, + aRect->right - aRect->left, + aRect->bottom - aRect->top, + awt::PosSize::POSSIZE); + m_xEditWindow->setVisible(true); + } + return NOERROR; +} + + +::com::sun::star::uno::Reference< + ::com::sun::star::awt::XWindow> SAL_CALL +DocumentHolder::getContainerWindow( +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + if(m_xContainerWindow.is()) + return m_xContainerWindow; + + uno::Reference<awt::XWindow> xWin(0); + + static const ::rtl::OUString aToolkitServiceName( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.awt.Toolkit" ) ); + uno::Reference<awt::XSystemChildFactory> xToolkit( + m_xFactory->createInstance(aToolkitServiceName ),uno::UNO_QUERY); + + if(xToolkit.is() && m_pIOleIPFrame) { + HWND hWnd; + m_pIOleIPFrame->GetWindow(&hWnd); + + uno::Sequence<sal_Int8> aProcessIdent(16); + rtl_getGlobalProcessId((sal_uInt8*)aProcessIdent.getArray()); + + uno::Any aAny; + aAny <<= sal_Int32(hWnd); + xWin = uno::Reference<awt::XWindow>( + xToolkit->createSystemChild( + aAny, + aProcessIdent, + lang::SystemDependent::SYSTEM_WIN32), + uno::UNO_QUERY); + + RECT wi; + memset(&wi,0,sizeof(wi)); + if(xWin.is() && m_pIOleIPFrame->GetBorder((LPRECT)&wi) == NOERROR) { + xWin->setVisible(true); + xWin->setPosSize( + 0,0, + wi.right-wi.left, + wi.bottom - wi.top, + awt::PosSize::POSSIZE); + + uno::Reference<awt::XSystemDependentWindowPeer> xSysWin( + xWin,uno::UNO_QUERY); + if(xSysWin.is()) { + aAny = xSysWin->getWindowHandle( + aProcessIdent,lang::SystemDependent::SYSTEM_WIN32); + sal_Int32 tmp; + if( aAny >>= tmp ) + SetContainerWindowHandle((HWND) tmp); + } + } + } + + m_xContainerWindow= xWin; + return xWin; +} + + + +sal_Bool SAL_CALL +DocumentHolder::requestDockingAreaSpace( + const ::com::sun::star::awt::Rectangle& RequestedSpace +) + throw( + ::com::sun::star::uno::RuntimeException + ) +{ + if(m_bOnDeactivate) + return sal_True; + + BORDERWIDTHS bw; + SetRect((LPRECT)&bw, + RequestedSpace.X,RequestedSpace.Y, + RequestedSpace.Width,RequestedSpace.Height); + if( m_pIOleIPFrame ) + return m_pIOleIPFrame->RequestBorderSpace(&bw) == NOERROR ; + else + return sal_Bool(false); +} + + +void SAL_CALL +DocumentHolder::setDockingAreaSpace( + const ::com::sun::star::awt::Rectangle& BorderSpace +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + if(m_bOnDeactivate) + return; + + BORDERWIDTHS bw; + SetRect((LPRECT)&bw, + BorderSpace.X,BorderSpace.Y, + BorderSpace.Width,BorderSpace.Height); + if( m_pIOleIPFrame ) { + RECT aRect; + GetClientRect(m_hWndxWinCont,&aRect); + HRGN hrgn1 = CreateRectRgn( + 0,0, + aRect.right,BorderSpace.Y); + HRGN hrgn2 = CreateRectRgn(aRect.right-BorderSpace.Width,0,aRect.right,aRect.bottom); + CombineRgn(hrgn1,hrgn1,hrgn2,RGN_OR); + DeleteObject(hrgn2); + hrgn2 = CreateRectRgn(0,aRect.bottom-BorderSpace.Height,aRect.right,aRect.bottom); + CombineRgn(hrgn1,hrgn1,hrgn2,RGN_OR); + DeleteObject(hrgn2); + hrgn2 = CreateRectRgn(0,0,BorderSpace.X,aRect.bottom); + CombineRgn(hrgn1,hrgn1,hrgn2,RGN_OR); + DeleteObject(hrgn2); + + SetWindowRgn(m_hWndxWinCont,hrgn1,true); + // not:: DeleteObject(hrgn1); + m_pIOleIPFrame->SetBorderSpace(&bw); + } +} + + +void SAL_CALL +DocumentHolder::disposing( + const com::sun::star::lang::EventObject& aSource +) + throw( uno::RuntimeException ) +{ + if ( m_xDocument.is() && m_xDocument == aSource.Source ) + { + m_pIDispatch = NULL; + m_xDocument = uno::Reference< frame::XModel >(); + } + + if( m_xFrame.is() && m_xFrame == aSource.Source ) + m_xFrame = uno::Reference< frame::XFrame >(); +} + + +void SAL_CALL +DocumentHolder::queryClosing( + const lang::EventObject& aSource, + sal_Bool /*bGetsOwnership*/ +) + throw( + util::CloseVetoException + ) +{ + if ( !m_bLink + && ( m_xDocument.is() && m_xDocument == aSource.Source || m_xFrame.is() && m_xFrame == aSource.Source ) ) + throw util::CloseVetoException(); +} + + +void SAL_CALL +DocumentHolder::notifyClosing( + const lang::EventObject& aSource ) + throw( uno::RuntimeException ) +{ + try + { + uno::Reference< util::XCloseBroadcaster > xEventBroadcaster( + aSource.Source, uno::UNO_QUERY_THROW ); + xEventBroadcaster->removeCloseListener( (util::XCloseListener*)this ); + } + catch( uno::Exception& ) + {} + + if ( m_xDocument.is() && m_xDocument == aSource.Source ) + { + // can happen only in case of links + m_pIDispatch = NULL; + m_xDocument = uno::Reference< frame::XModel >(); + m_xFrame = uno::Reference< frame::XFrame >(); + + LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument(); + if ( aDocLock.GetEmbedDocument() ) + aDocLock.GetEmbedDocument()->OLENotifyClosing(); + } + else if( m_xFrame.is() && m_xFrame == aSource.Source ) + m_xFrame = uno::Reference< frame::XFrame >(); +} + +void SAL_CALL +DocumentHolder::queryTermination( + const lang::EventObject& /*aSource*/ +) + throw( + frame::TerminationVetoException + ) +{ + if ( m_xDocument.is() ) + throw frame::TerminationVetoException(); +} + +void SAL_CALL +DocumentHolder::notifyTermination( + const lang::EventObject& aSource +) + throw( uno::RuntimeException ) +{ + OSL_ENSURE( !m_xDocument.is(), "Just a disaster..." ); + uno::Reference< frame::XDesktop > xDesktop( + aSource.Source, uno::UNO_QUERY ); + + if ( xDesktop.is() ) + xDesktop->removeTerminateListener( (frame::XTerminateListener*)this ); +} + + + +void SAL_CALL DocumentHolder::modified( const lang::EventObject& /*aEvent*/ ) + throw (uno::RuntimeException) +{ + if ( m_xOleAccess.is() ) + { + LockedEmbedDocument_Impl aDocLock = m_xOleAccess->GetEmbedDocument(); + if ( aDocLock.GetEmbedDocument() ) + aDocLock.GetEmbedDocument()->notify(); + } +} + + + +// if(m_pOLEInterface->GetGUID() == OID_WriterTextServer) { +// // edit group +// CopyToOLEMenu(m_nMenuHandle,1,hMenu,(WORD)mgw.width[0]); +// CopyToOLEMenu(m_nMenuHandle,2,hMenu,1+(WORD)mgw.width[0]); +// CopyToOLEMenu(m_nMenuHandle,3,hMenu,2+(WORD)mgw.width[0]); +// CopyToOLEMenu(m_nMenuHandle,4,hMenu,3+(WORD)mgw.width[0]); +// mgw.width[1]=4; + +// // object group +// CopyToOLEMenu( +// m_nMenuHandle,5, +// hMenu,4+(WORD)mgw.width[0]+(WORD)mgw.width[2]); +// mgw.width[3]=1; + +// // help group +// CopyToOLEMenu( +// m_nMenuHandle,7, +// hMenu,5+(WORD)mgw.width[0]+(WORD)mgw.width[2]+(WORD)mgw.width[4]); +// mgw.width[5]=1; +// } +// else if(m_pOLEInterface->GetGUID() == OID_CalcServer) { +// // edit group +// CopyToOLEMenu(m_nMenuHandle,1,hMenu,(WORD)mgw.width[0]); +// CopyToOLEMenu(m_nMenuHandle,2,hMenu,1+(WORD)mgw.width[0]); +// CopyToOLEMenu(m_nMenuHandle,3,hMenu,2+(WORD)mgw.width[0]); +// CopyToOLEMenu(m_nMenuHandle,4,hMenu,3+(WORD)mgw.width[0]); +// mgw.width[1]=4; + +// // object group +// CopyToOLEMenu( +// m_nMenuHandle,5, +// hMenu,4+(WORD)mgw.width[0]+(WORD)mgw.width[2]); +// CopyToOLEMenu( +// m_nMenuHandle,6, +// hMenu,5+(WORD)mgw.width[0]+(WORD)mgw.width[2]); +// mgw.width[3]=2; + +// // help group +// CopyToOLEMenu( +// m_nMenuHandle,8, +// hMenu,6+(WORD)mgw.width[0]+(WORD)mgw.width[2]+(WORD)mgw.width[4]); +// mgw.width[5]=1; +// } + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/ed_idataobj.cxx b/embedserv/source/embed/ed_idataobj.cxx new file mode 100755 index 000000000000..c50e05400208 --- /dev/null +++ b/embedserv/source/embed/ed_idataobj.cxx @@ -0,0 +1,329 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ed_idataobj.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +// actually this workaround should be in presys.h! +//#define UINT64 USE_WIN_UINT64 +//#define INT64 USE_WIN_INT64 +//#define UINT32 USE_WIN_UINT32 +//#define INT32 USE_WIN_INT32 + +//#include <tools/presys.h> +#include "embeddoc.hxx" +//#include <tools/postsys.h> + +//#undef UINT64 +//#undef INT64 +//#undef UINT32 +//#undef INT32 + + +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> + + +#include <osl/thread.h> + +using namespace ::com::sun::star; + +//=============================================================================== +// EmbedDocument_Impl +//=============================================================================== + +sal_uInt64 EmbedDocument_Impl::getMetaFileHandle_Impl( sal_Bool isEnhMeta ) +{ + sal_uInt64 pResult = NULL; + + uno::Reference< datatransfer::XTransferable > xTransferable( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if ( xTransferable.is() ) + { + uno::Sequence< sal_Int8 > aMetaBuffer; + datatransfer::DataFlavor aFlavor; + + if ( isEnhMeta ) + { + aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ); + aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) ); + } + else + { + aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ); + aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows GDIMetaFile" ) ); + } + + aFlavor.DataType = getCppuType( (const sal_uInt64*) 0 ); + + uno::Any aAny = xTransferable->getTransferData( aFlavor ); + aAny >>= pResult; + } + + return pResult; +} + +//------------------------------------------------------------------------------- +// IDataObject + +STDMETHODIMP EmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) +{ + if ( !pFormatetc ) + return DV_E_FORMATETC; + + if ( !pMedium ) + return STG_E_MEDIUMFULL; + + if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL + || pFormatetc->dwAspect == DVASPECT_ICON + || pFormatetc->dwAspect == DVASPECT_DOCPRINT ) + return DV_E_DVASPECT; + + if ( pFormatetc->cfFormat == CF_ENHMETAFILE ) + { + if ( !( pFormatetc->tymed & TYMED_ENHMF ) ) + return DV_E_TYMED; + + HENHMETAFILE hMeta = reinterpret_cast<HENHMETAFILE>( getMetaFileHandle_Impl( sal_True ) ); + + if ( hMeta ) + { + pMedium->tymed = TYMED_ENHMF; + pMedium->hEnhMetaFile = hMeta; + pMedium->pUnkForRelease = NULL; + + return S_OK; + } + + return STG_E_MEDIUMFULL; + } + else if ( pFormatetc->cfFormat == CF_METAFILEPICT ) + { + if ( !( pFormatetc->tymed & TYMED_MFPICT ) ) + return DV_E_TYMED; + + HGLOBAL hMeta = reinterpret_cast<HGLOBAL>( getMetaFileHandle_Impl( sal_False ) ); + + if ( hMeta ) + { + pMedium->tymed = TYMED_MFPICT; + pMedium->hMetaFilePict = hMeta; + pMedium->pUnkForRelease = NULL; + + return S_OK; + } + + return STG_E_MEDIUMFULL; + } + else + { + CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); + CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj ) + { + if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) ) + return DV_E_TYMED; + + CComPtr< IStorage > pNewStg; + HRESULT hr = StgCreateDocfile( NULL, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, 0, &pNewStg ); + if ( FAILED( hr ) || !pNewStg ) return STG_E_MEDIUMFULL; + + hr = SaveTo_Impl( pNewStg ); + if ( FAILED( hr ) ) return STG_E_MEDIUMFULL; + + pMedium->tymed = TYMED_ISTORAGE; + pMedium->pstg = pNewStg; + pMedium->pstg->AddRef(); + pMedium->pUnkForRelease = ( IUnknown* )pNewStg; + + return S_OK; + } + } + + return DV_E_FORMATETC; +} + +STDMETHODIMP EmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) +{ + if ( !pFormatetc ) + return DV_E_FORMATETC; + + if ( !pMedium ) + return STG_E_MEDIUMFULL; + + if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL + || pFormatetc->dwAspect == DVASPECT_ICON + || pFormatetc->dwAspect == DVASPECT_DOCPRINT ) + return DV_E_DVASPECT; + + CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); + CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + + if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj ) + { + if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) ) + return DV_E_TYMED; + + if ( !pMedium->pstg ) return STG_E_MEDIUMFULL; + + HRESULT hr = SaveTo_Impl( pMedium->pstg ); + if ( FAILED( hr ) ) return STG_E_MEDIUMFULL; + + pMedium->tymed = TYMED_ISTORAGE; + pMedium->pUnkForRelease = NULL; + + return S_OK; + } + + return DV_E_FORMATETC; +} + +STDMETHODIMP EmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc ) +{ + if ( pFormatetc ) + { + if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL + || pFormatetc->dwAspect == DVASPECT_ICON + || pFormatetc->dwAspect == DVASPECT_DOCPRINT ) + return DV_E_DVASPECT; + + if ( pFormatetc->cfFormat == CF_ENHMETAFILE ) + { + if ( !( pFormatetc->tymed & TYMED_ENHMF ) ) + return DV_E_TYMED; + + return S_OK; + } + else if ( pFormatetc->cfFormat == CF_METAFILEPICT ) + { + if ( !( pFormatetc->tymed & TYMED_MFPICT ) ) + return DV_E_TYMED; + + return S_OK; + } + else + { + CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); + CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj ) + { + if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) ) + return DV_E_TYMED; + + return S_OK; + } + } + } + + return DV_E_FORMATETC; + +} + +STDMETHODIMP EmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ) +{ + if ( !pFormatetcIn || !pFormatetcOut ) + return DV_E_FORMATETC; + + pFormatetcOut->ptd = NULL; + pFormatetcOut->cfFormat = pFormatetcIn->cfFormat; + pFormatetcOut->dwAspect = DVASPECT_CONTENT; + + if ( pFormatetcIn->cfFormat == CF_ENHMETAFILE ) + { + pFormatetcOut->tymed = TYMED_ENHMF; + return S_OK; + } + else if ( pFormatetcIn->cfFormat == CF_METAFILEPICT ) + { + pFormatetcOut->tymed = TYMED_MFPICT; + return S_OK; + } + else + { + CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); + CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + if ( pFormatetcIn->cfFormat == cf_embSource || pFormatetcIn->cfFormat == cf_embObj ) + { + pFormatetcOut->tymed = TYMED_ISTORAGE; + return S_OK; + } + } + + return DV_E_FORMATETC; +} + +STDMETHODIMP EmbedDocument_Impl::SetData( FORMATETC * /*pFormatetc*/, STGMEDIUM * /*pMedium*/, BOOL /*fRelease*/ ) +{ + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** /*ppFormatetc*/ ) +{ + if ( dwDirection == DATADIR_GET ) + return OLE_S_USEREG; + + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ) +{ + if ( !m_pDAdviseHolder ) + if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder ) + return E_OUTOFMEMORY; + + return m_pDAdviseHolder->Advise( (IDataObject*)this, pFormatetc, advf, pAdvSink, pdwConnection ); +} + +STDMETHODIMP EmbedDocument_Impl::DUnadvise( DWORD dwConnection ) +{ + if ( !m_pDAdviseHolder ) + if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder ) + return E_OUTOFMEMORY; + + return m_pDAdviseHolder->Unadvise( dwConnection ); +} + +STDMETHODIMP EmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise ) +{ + if ( !m_pDAdviseHolder ) + if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder ) + return E_OUTOFMEMORY; + + return m_pDAdviseHolder->EnumAdvise( ppenumAdvise ); +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/ed_iinplace.cxx b/embedserv/source/embed/ed_iinplace.cxx new file mode 100644 index 000000000000..50af60af2202 --- /dev/null +++ b/embedserv/source/embed/ed_iinplace.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ed_iinplace.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "embeddoc.hxx" +#include <osl/diagnose.h> + + +STDMETHODIMP EmbedDocument_Impl::GetWindow(HWND *hWnd) +{ + OSL_ENSURE(m_pDocHolder,"no document for inplace activation"); + + *hWnd = m_pDocHolder->GetTopMostWinHandle(); + if(*hWnd != NULL) + return NOERROR; + else + return ERROR; +} + +STDMETHODIMP EmbedDocument_Impl::ContextSensitiveHelp(BOOL) +{ + return NOERROR; +} + +STDMETHODIMP EmbedDocument_Impl::InPlaceDeactivate(void) +{ + // no locking is used since the OLE must use the same thread always + if ( m_bIsInVerbHandling ) + return E_UNEXPECTED; + + BooleanGuard_Impl aGuard( m_bIsInVerbHandling ); + + m_pDocHolder->InPlaceDeactivate(); + + // the inplace object needs the notification after the storing ( on deactivating ) + // if it happens before the storing the replacement might not be updated + notify(); + + return NOERROR; +} + +STDMETHODIMP EmbedDocument_Impl::UIDeactivate(void) +{ + // no locking is used since the OLE must use the same thread always + if ( m_bIsInVerbHandling ) + return E_UNEXPECTED; + + BooleanGuard_Impl aGuard( m_bIsInVerbHandling ); + + + m_pDocHolder->UIDeactivate(); + + // the inplace object needs the notification after the storing ( on deactivating ) + // if it happens before the storing the replacement might not be updated + notify(); + + return NOERROR; +} + +STDMETHODIMP EmbedDocument_Impl::SetObjectRects(LPCRECT aRect, LPCRECT aClip) +{ + OSL_ENSURE(m_pDocHolder,"no document for inplace activation"); + + return m_pDocHolder->SetObjectRects(aRect,aClip); +} + +STDMETHODIMP EmbedDocument_Impl::ReactivateAndUndo(void) +{ + return E_NOTIMPL; +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/ed_ioleobject.cxx b/embedserv/source/embed/ed_ioleobject.cxx new file mode 100755 index 000000000000..07d172ef7173 --- /dev/null +++ b/embedserv/source/embed/ed_ioleobject.cxx @@ -0,0 +1,507 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ed_ioleobject.cxx,v $ + * $Revision: 1.20.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "embeddoc.hxx" +#include <osl/diagnose.h> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + + +using namespace ::com::sun::star; + + +extern ::rtl::OUString getFilterNameFromGUID_Impl( GUID* ); + +//------------------------------------------------------------------------------- +// IOleObject + + +STDMETHODIMP EmbedDocument_Impl::SetClientSite( IOleClientSite* pSite ) +{ + m_pClientSite = pSite; + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::GetClientSite( IOleClientSite** pSite ) +{ + *pSite = m_pClientSite; + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj ) +{ + // the code should be ignored for links + if ( !m_aFileName.getLength() ) + { + m_pDocHolder->setTitle( + rtl::OUString( + (sal_Unicode*)szContainerObj)); + m_pDocHolder->setContainerName( + rtl::OUString( + (sal_Unicode*)szContainerApp)); + } + + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::Close( DWORD dwSaveOption ) +{ + HRESULT hr = S_OK; + + if ( m_pDocHolder->HasFrame() ) + { + if ( dwSaveOption == 2 && m_aFileName.getLength() ) + { + // ask the user about saving + if ( m_pDocHolder->ExecuteSuspendCloseFrame() ) + { + m_pDocHolder->CloseDocument(); + return S_OK; + } + else + return OLE_E_PROMPTSAVECANCELLED; + } + + if ( dwSaveOption != 1 ) + hr = SaveObject(); // ADVF_DATAONSTOP); + + m_pDocHolder->CloseFrame(); + OLENotifyDeactivation(); + } + + m_pDocHolder->FreeOffice(); + m_pDocHolder->CloseDocument(); + + OLENotifyClosing(); + + return hr; +} + + +HRESULT EmbedDocument_Impl::OLENotifyClosing() +{ + HRESULT hr = S_OK; + + AdviseSinkHashMap aAHM(m_aAdviseHashMap); + + for ( AdviseSinkHashMapIterator iAdvise = aAHM.begin(); + iAdvise != aAHM.end(); iAdvise++ ) + { + if ( iAdvise->second ) + iAdvise->second->OnClose(); + } + + return hr; + +} + +STDMETHODIMP EmbedDocument_Impl::SetMoniker( DWORD /*dwWhichMoniker*/, IMoniker * /*pmk*/ ) +{ + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::GetMoniker( DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker ** /*ppmk*/ ) +{ + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::InitFromData( IDataObject * /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/ ) +{ + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::GetClipboardData( DWORD /*dwReserved*/, IDataObject ** /*ppDataObject*/ ) +{ + return E_NOTIMPL; +} + +/** + * Well, this is a not so very inefficient way to deliver + * + */ + +STDMETHODIMP EmbedDocument_Impl::DoVerb( + LONG iVerb, + LPMSG, + IOleClientSite *pActiveSite, + LONG, + HWND, + LPCRECT ) +{ + // no locking is used since the OLE must use the same thread always + if ( m_bIsInVerbHandling ) + return OLEOBJ_S_CANNOT_DOVERB_NOW; + + // an object can not handle any Verbs in Hands off mode + if ( m_pMasterStorage == NULL || m_pOwnStream == NULL ) + return OLE_E_CANT_BINDTOSOURCE; + + + BooleanGuard_Impl aGuard( m_bIsInVerbHandling ); + + if ( iVerb == OLEIVERB_PRIMARY ) + { + if ( m_aFileName.getLength() ) + { + // that should be a link + iVerb = OLEIVERB_OPEN; + } + else + iVerb = OLEIVERB_SHOW; + } + + try + { + switch(iVerb) { + case OLEIVERB_DISCARDUNDOSTATE: + // free any undostate? + break; + case OLEIVERB_INPLACEACTIVATE: + OSL_ENSURE(m_pDocHolder,"no document for inplace activation"); + + return m_pDocHolder->InPlaceActivate(pActiveSite,FALSE); + break; + case OLEIVERB_UIACTIVATE: + OSL_ENSURE(m_pDocHolder,"no document for inplace activation"); + + return m_pDocHolder->InPlaceActivate(pActiveSite,TRUE); + break; + case OLEIVERB_PRIMARY: + case OLEIVERB_SHOW: + OSL_ENSURE(m_pDocHolder,"no document for inplace activation"); + + if(m_pDocHolder->isActive()) + return NOERROR; //Already active + + if(SUCCEEDED( + m_pDocHolder->InPlaceActivate( + pActiveSite,TRUE))) + return NOERROR; + + // intended fall trough + case OLEIVERB_OPEN: + OSL_ENSURE(m_pDocHolder,"no document to open"); + + // the commented code could be usefull in case + // outer window would be resized depending from inner one + // RECTL aEmbArea; + // m_pDocHolder->GetVisArea( &aEmbArea ); + // m_pDocHolder->show(); + // m_pDocHolder->SetVisArea( &aEmbArea ); + + if(m_pDocHolder->isActive()) + { + m_pDocHolder->InPlaceDeactivate(); + m_pDocHolder->DisableInplaceActivation(true); + } + + SIZEL aEmbSize; + m_pDocHolder->GetExtent( &aEmbSize ); + m_pDocHolder->show(); + m_pDocHolder->resizeWin( aEmbSize ); + + if ( m_pClientSite ) + m_pClientSite->OnShowWindow( TRUE ); + + notify(); + break; + case OLEIVERB_HIDE: + OSL_ENSURE(m_pDocHolder,"no document to hide"); + + if(m_pDocHolder->isActive()) + m_pDocHolder->InPlaceDeactivate(); + else { + m_pDocHolder->hide(); + + if( m_pClientSite ) + m_pClientSite->OnShowWindow(FALSE); + } + break; + default: + break; + } + } + catch( uno::Exception& ) + { + return OLEOBJ_S_CANNOT_DOVERB_NOW; + } + + return NOERROR; +} + + + +STDMETHODIMP EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** /*ppEnumOleVerb*/ ) +{ + return OLE_S_USEREG; +} + +STDMETHODIMP EmbedDocument_Impl::Update() +{ + return S_OK; +// HRESULT hr = CACHE_E_NOCACHE_UPDATED; +// return hr; +} + +STDMETHODIMP EmbedDocument_Impl::IsUpToDate() +{ + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::GetUserClassID( CLSID *pClsid ) +{ + return GetClassID( pClsid ); +} + +STDMETHODIMP EmbedDocument_Impl::GetUserType( DWORD /*dwFormOfTypeUe*/, LPOLESTR * /*pszUserType*/ ) +{ + return OLE_S_USEREG; +} + +STDMETHODIMP EmbedDocument_Impl::SetExtent( DWORD /*dwDrawAspect*/, SIZEL *psizel ) +{ + if ( !psizel ) + return E_FAIL; + + m_pDocHolder->SetExtent( psizel ); + + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::GetExtent( DWORD /*dwDrawAspect*/, SIZEL * psizel ) +{ + if ( !psizel ) + return E_INVALIDARG; + + if ( FAILED( m_pDocHolder->GetExtent( psizel ) ) ) + { + // return default values + psizel->cx = 500; + psizel->cy = 500; + } + + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection ) +{ + if ( m_nAdviseNum == 0xFFFFFFFF ) + return E_OUTOFMEMORY; + + pAdvSink->AddRef(); + m_aAdviseHashMap.insert( ::std::pair< DWORD, IAdviseSink* >( m_nAdviseNum, pAdvSink ) ); + *pdwConnection = m_nAdviseNum++; + + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::Unadvise( DWORD dwConnection ) +{ + AdviseSinkHashMapIterator iAdvise = m_aAdviseHashMap.find( dwConnection ); + if ( iAdvise != m_aAdviseHashMap.end() ) + { + iAdvise->second->Release(); + m_aAdviseHashMap.erase( iAdvise ); + } + else + return OLE_E_NOCONNECTION; + + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ ) +{ + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::GetMiscStatus( DWORD /*dwAspect*/, DWORD * /*pdwStatus*/ ) +{ + return OLE_S_USEREG; +} + +STDMETHODIMP EmbedDocument_Impl::SetColorScheme( LOGPALETTE * /*pLogpal*/ ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------------- +// IDispatch + +STDMETHODIMP EmbedDocument_Impl::GetTypeInfoCount( unsigned int FAR* pctinfo ) +{ + if ( m_pDocHolder->GetIDispatch() ) + return m_pDocHolder->GetIDispatch()->GetTypeInfoCount( pctinfo ); + + return E_NOTIMPL; +} + +STDMETHODIMP EmbedDocument_Impl::GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo ) +{ + if ( m_pDocHolder->GetIDispatch() ) + return m_pDocHolder->GetIDispatch()->GetTypeInfo( iTInfo, lcid, ppTInfo ); + + return DISP_E_BADINDEX; // the only error that can be returned +} + +STDMETHODIMP EmbedDocument_Impl::GetIDsOfNames( REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgDispId ) +{ + if ( m_pDocHolder->GetIDispatch() ) + return m_pDocHolder->GetIDispatch()->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId ); + + for ( unsigned int ind = 0; ind < cNames; ind++ ) + rgDispId[ind] = DISPID_UNKNOWN; + + return DISP_E_UNKNOWNNAME; +} + +STDMETHODIMP EmbedDocument_Impl::Invoke( DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS FAR* pDispParams, + VARIANT FAR* pVarResult, + EXCEPINFO FAR* pExcepInfo, + unsigned int FAR* puArgErr ) +{ + if ( m_pDocHolder->GetIDispatch() ) + return m_pDocHolder->GetIDispatch()->Invoke( dispIdMember, + riid, + lcid, + wFlags, + pDispParams, + pVarResult, + pExcepInfo, + puArgErr ); + + return DISP_E_MEMBERNOTFOUND; +} + +//------------------------------------------------------------------------------- +// IExternalConnection + +DWORD STDMETHODCALLTYPE EmbedDocument_Impl::AddConnection( DWORD , DWORD ) +{ + return AddRef(); +} + +DWORD STDMETHODCALLTYPE EmbedDocument_Impl::ReleaseConnection( DWORD , DWORD , BOOL ) +{ + return Release(); +} + +// C++ - methods + +HRESULT EmbedDocument_Impl::SaveObject() +{ + HRESULT hr = S_OK; + + if(m_pClientSite) { + hr = m_pClientSite->SaveObject(); + + for ( AdviseSinkHashMapIterator iAdvise = + m_aAdviseHashMap.begin(); + iAdvise != m_aAdviseHashMap.end(); + iAdvise++ ) + if ( iAdvise->second ) + iAdvise->second->OnSave( ); + } + else if ( m_aFileName.getLength() && IsDirty() == S_OK ) + { + ::rtl::OUString aPreservFileName = m_aFileName; + + // in case of links the containers does not provide client site sometimes + hr = Save( (LPCOLESTR)NULL, FALSE ); // triggers saving to the link location + SaveCompleted( (LPCOLESTR)aPreservFileName.getStr() ); + } + + notify( false ); + + return hr; +} + + +HRESULT EmbedDocument_Impl::ShowObject() +{ + HRESULT hr = S_OK; + + if(m_pClientSite) + hr = m_pClientSite->ShowObject(); + + return hr; +} + + +void EmbedDocument_Impl::notify( bool bDataChanged ) +{ + for ( AdviseSinkHashMapIterator iAdvise = + m_aAdviseHashMap.begin(); + iAdvise != m_aAdviseHashMap.end(); + iAdvise++ ) + if ( iAdvise->second ) + iAdvise->second->OnViewChange( DVASPECT_CONTENT, -1 ); + + if ( m_pDAdviseHolder && bDataChanged ) + m_pDAdviseHolder->SendOnDataChange( (IDataObject*)this, 0, 0 ); +} + +void EmbedDocument_Impl::Deactivate() +{ + HRESULT hr = S_OK; + + if ( m_pDocHolder->HasFrame() ) + { + hr = SaveObject(); + m_pDocHolder->CloseFrame(); + OLENotifyDeactivation(); + } +} + +HRESULT EmbedDocument_Impl::OLENotifyDeactivation() +{ + HRESULT hr = S_OK; + + if ( m_pClientSite ) + hr = m_pClientSite->OnShowWindow( FALSE ); + + return hr; + +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif + diff --git a/embedserv/source/embed/ed_ipersiststr.cxx b/embedserv/source/embed/ed_ipersiststr.cxx new file mode 100755 index 000000000000..d0df506cf902 --- /dev/null +++ b/embedserv/source/embed/ed_ipersiststr.cxx @@ -0,0 +1,1021 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ed_ipersiststr.cxx,v $ + * $Revision: 1.27.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "embeddoc.hxx" +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XLoadable.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/util/XUrlTransformer.hpp> + + +#include <osl/mutex.hxx> +#include <osl/diagnose.h> + +#include <string.h> + +#define EXT_STREAM_LENGTH 16 + +using namespace ::com::sun::star; + +extern ::rtl::OUString getStorageTypeFromGUID_Impl( GUID* guid ); +extern ::rtl::OUString getServiceNameFromGUID_Impl( GUID* ); +extern ::rtl::OUString getFilterNameFromGUID_Impl( GUID* ); +// extern CLIPFORMAT getClipFormatFromGUID_Impl( GUID* ); +::rtl::OUString getTestFileURLFromGUID_Impl( GUID* guid ); + +const ::rtl::OUString aOfficeEmbedStreamName( RTL_CONSTASCII_USTRINGPARAM ( "package_stream" ) ); +const ::rtl::OUString aExtentStreamName( RTL_CONSTASCII_USTRINGPARAM ( "properties_stream" ) ); + +uno::Reference< io::XInputStream > createTempXInStreamFromIStream( + uno::Reference< lang::XMultiServiceFactory > xFactory, + IStream *pStream ) +{ + uno::Reference< io::XInputStream > xResult; + + if ( !pStream ) + return xResult; + + const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) ); + uno::Reference < io::XOutputStream > xTempOut = uno::Reference < io::XOutputStream > ( + xFactory->createInstance ( aServiceName ), + uno::UNO_QUERY ); + if ( xTempOut.is() ) + { + ULARGE_INTEGER nNewPos; + LARGE_INTEGER aZero = { 0L, 0L }; + HRESULT hr = pStream->Seek( aZero, STREAM_SEEK_SET, &nNewPos ); + if ( FAILED( hr ) ) return xResult; + + STATSTG aStat; + hr = pStream->Stat( &aStat, STATFLAG_NONAME ); + if ( FAILED( hr ) ) return xResult; + + sal_uInt32 nSize = (sal_uInt32)aStat.cbSize.QuadPart; + sal_uInt32 nCopied = 0; + uno::Sequence< sal_Int8 > aBuffer( nConstBufferSize ); + try + { + sal_uInt32 nRead = 0; + do + { + pStream->Read( (void*)aBuffer.getArray(), nConstBufferSize, &nRead ); + + if ( nRead < nConstBufferSize ) + aBuffer.realloc( nRead ); + + xTempOut->writeBytes( aBuffer ); + nCopied += nRead; + } while( nRead == nConstBufferSize ); + + if ( nCopied == nSize ) + { + uno::Reference < io::XSeekable > xTempSeek ( xTempOut, uno::UNO_QUERY ); + if ( xTempSeek.is() ) + { + xTempSeek->seek ( 0 ); + xResult = uno::Reference< io::XInputStream >( xTempOut, uno::UNO_QUERY ); + } + } + } + catch( uno::Exception& ) + { + } + } + + return xResult; +} + +HRESULT copyXTempOutToIStream( uno::Reference< io::XOutputStream > xTempOut, IStream* pStream ) +{ + if ( !xTempOut.is() || !pStream ) + return E_FAIL; + + uno::Reference < io::XSeekable > xTempSeek ( xTempOut, uno::UNO_QUERY ); + if ( !xTempSeek.is() ) + return E_FAIL; + + xTempSeek->seek ( 0 ); + + uno::Reference< io::XInputStream > xTempIn ( xTempOut, uno::UNO_QUERY ); + if ( !xTempSeek.is() ) + return E_FAIL; + + // Seek to zero and truncate the stream + ULARGE_INTEGER nNewPos; + LARGE_INTEGER aZero = { 0L, 0L }; + HRESULT hr = pStream->Seek( aZero, STREAM_SEEK_SET, &nNewPos ); + if ( FAILED( hr ) ) return E_FAIL; + ULARGE_INTEGER aUZero = { 0L, 0L }; + hr = pStream->SetSize( aUZero ); + if ( FAILED( hr ) ) return E_FAIL; + + uno::Sequence< sal_Int8 > aBuffer( nConstBufferSize ); + sal_uInt32 nReadBytes = 0; + + do + { + try { + nReadBytes = xTempIn->readBytes( aBuffer, nConstBufferSize ); + } + catch( uno::Exception& ) + { + return E_FAIL; + } + + sal_uInt32 nWritten = 0; + HRESULT hr = pStream->Write( (void*)aBuffer.getArray(), nReadBytes, &nWritten ); + if ( !SUCCEEDED( hr ) || nWritten != nReadBytes ) + return E_FAIL; + + } while( nReadBytes == nConstBufferSize ); + + return S_OK; +} + + +//=============================================================================== +// EmbedDocument_Impl +//=============================================================================== + +EmbedDocument_Impl::EmbedDocument_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory, const GUID* guid ) +: m_refCount( 0L ) +, m_xFactory( xFactory ) +, m_guid( *guid ) +, m_bIsDirty( sal_False ) +, m_nAdviseNum( 0 ) +, m_bIsInVerbHandling( sal_False ) +//, m_bLoadedFromFile( sal_False ) +{ + m_xOwnAccess = new EmbeddedDocumentInstanceAccess_Impl( this ); + m_pDocHolder = new DocumentHolder( xFactory, m_xOwnAccess ); + m_pDocHolder->acquire(); +} + +EmbedDocument_Impl::~EmbedDocument_Impl() +{ + m_pDocHolder->FreeOffice(); + + if ( m_pDocHolder->HasFrame() && m_pDocHolder->IsLink() ) + { + // a link with frame should be only disconnected, not closed + m_pDocHolder->DisconnectFrameDocument( sal_True ); + } + else + { + m_pDocHolder->CloseDocument(); + m_pDocHolder->CloseFrame(); + } + + m_pDocHolder->release(); +} + +uno::Sequence< beans::PropertyValue > EmbedDocument_Impl::fillArgsForLoading_Impl( uno::Reference< io::XInputStream > xStream, DWORD /*nStreamMode*/, LPCOLESTR pFilePath ) +{ + uno::Sequence< beans::PropertyValue > aArgs( 3 ); + + sal_Int32 nInd = 0; // must not be bigger than the preset size + aArgs[nInd].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "FilterName" ) ); + aArgs[nInd++].Value <<= getFilterNameFromGUID_Impl( &m_guid ); + + if ( xStream.is() ) + { + aArgs[nInd].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "InputStream" ) ); + aArgs[nInd++].Value <<= xStream; + aArgs[nInd].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "URL" ) ); + aArgs[nInd++].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "private:stream" ) ); + } + else + { + aArgs[nInd].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "URL" ) ); + + rtl::OUString sDocUrl; + if ( pFilePath ) + { + ::rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.util.URLTransformer" ) ); + uno::Reference< util::XURLTransformer > aTransformer( m_xFactory->createInstance( aServiceName ), + uno::UNO_QUERY ); + if ( aTransformer.is() ) + { + util::URL aURL; + + aURL.Complete = ::rtl::OUString( reinterpret_cast<const sal_Unicode*>(pFilePath) ); + + if ( aTransformer->parseSmart( aURL, ::rtl::OUString() ) ) + sDocUrl = aURL.Complete; + } + } + + aArgs[nInd++].Value <<= sDocUrl; + } + + aArgs.realloc( nInd ); + + // aArgs[].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ReadOnly" ) ); + // aArgs[].Value <<= sal_False; //( ( nStreamMode & ( STGM_READWRITE | STGM_WRITE ) ) ? sal_True : sal_False ); + + return aArgs; +} + +uno::Sequence< beans::PropertyValue > EmbedDocument_Impl::fillArgsForStoring_Impl( uno::Reference< io::XOutputStream > xStream) +{ + uno::Sequence< beans::PropertyValue > aArgs( xStream.is() ? 2 : 1 ); + + aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "FilterName" ) ); + aArgs[0].Value <<= getFilterNameFromGUID_Impl( &m_guid ); + + if ( xStream.is() ) + { + aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "OutputStream" ) ); + aArgs[1].Value <<= xStream; + } + + return aArgs; +} + +HRESULT EmbedDocument_Impl::SaveTo_Impl( IStorage* pStg ) +{ + if ( !pStg || pStg == m_pMasterStorage ) + return E_FAIL; + + // for saveto operation the master storage + // should not enter NoScribble mode + CComPtr< IStream > pOrigOwn = m_pOwnStream; + CComPtr< IStream > pOrigExt = m_pExtStream; + HRESULT hr = Save( pStg, sal_False ); + pStg->Commit( STGC_ONLYIFCURRENT ); + m_pOwnStream = pOrigOwn; + m_pExtStream = pOrigExt; + + return hr; +} + +//------------------------------------------------------------------------------- +// IUnknown + +STDMETHODIMP EmbedDocument_Impl::QueryInterface( REFIID riid, void FAR* FAR* ppv ) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + AddRef(); + *ppv = (IUnknown*) (IPersistStorage*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersist)) + { + AddRef(); + *ppv = (IPersist*) (IPersistStorage*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IExternalConnection)) + { + AddRef(); + *ppv = (IExternalConnection*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersistStorage)) + { + AddRef(); + *ppv = (IPersistStorage*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IDataObject)) + { + AddRef(); + *ppv = (IDataObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleObject)) + { + AddRef(); + *ppv = (IOleObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleWindow)) + { + AddRef(); + *ppv = (IOleWindow*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleInPlaceObject)) + { + AddRef(); + *ppv = (IOleInPlaceObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersistFile)) + { + AddRef(); + *ppv = (IPersistFile*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IDispatch)) + { + AddRef(); + *ppv = (IDispatch*) this; + return S_OK; + } + + *ppv = NULL; + return ResultFromScode(E_NOINTERFACE); +} + +STDMETHODIMP_(ULONG) EmbedDocument_Impl::AddRef() +{ + return osl_incrementInterlockedCount( &m_refCount); +} + +STDMETHODIMP_(ULONG) EmbedDocument_Impl::Release() +{ + // if there is a time when the last reference is destructed, that means that only internal pointers are alive + // after the following call either the refcount is increased or the pointers are empty + if ( m_refCount == 1 ) + m_xOwnAccess->ClearEmbedDocument(); + + sal_Int32 nCount = osl_decrementInterlockedCount( &m_refCount ); + if ( nCount == 0 ) + delete this; + return nCount; +} + +//------------------------------------------------------------------------------- +// IPersist + +STDMETHODIMP EmbedDocument_Impl::GetClassID( CLSID* pClassId ) +{ + *pClassId = *&m_guid; + return S_OK; +} + +//------------------------------------------------------------------------------- +// IPersistStorage + +STDMETHODIMP EmbedDocument_Impl::IsDirty() +{ + // the link modified state is controlled by the document + if ( m_bIsDirty && !m_aFileName.getLength() ) + return S_OK; + + uno::Reference< util::XModifiable > xMod( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if ( xMod.is() ) + return xMod->isModified() ? S_OK : S_FALSE; + return S_FALSE; +} + +STDMETHODIMP EmbedDocument_Impl::InitNew( IStorage *pStg ) +{ + HRESULT hr = CO_E_ALREADYINITIALIZED; + + if ( !m_pDocHolder->GetDocument().is() ) + { + + STATSTG aStat; + hr = pStg->Stat( &aStat, STATFLAG_NONAME ); + if ( FAILED( hr ) ) return E_FAIL; + + DWORD nStreamMode = aStat.grfMode; + + hr = E_FAIL; + if ( m_xFactory.is() && pStg ) + { + uno::Reference< frame::XModel > aDocument( + m_xFactory->createInstance( getServiceNameFromGUID_Impl( &m_guid ) ), + uno::UNO_QUERY ); + if ( aDocument.is() ) + { + m_pDocHolder->SetDocument( aDocument ); + + uno::Reference< frame::XLoadable > xLoadable( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if( xLoadable.is() ) + { + try + { + xLoadable->initNew(); + // xLoadable->load( fillArgsForLoading_Impl( uno::Reference< io::XInputStream >(), nStreamMode ) ); + hr = S_OK; + } + catch( uno::Exception& ) + { + } + } + + if ( hr == S_OK ) + { + ::rtl::OUString aCurType = getStorageTypeFromGUID_Impl( &m_guid ); // ??? + CLIPFORMAT cf = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + hr = WriteFmtUserTypeStg( pStg, + cf, // ??? + reinterpret_cast<LPWSTR>(( sal_Unicode* )aCurType.getStr()) ); + + if ( hr == S_OK ) + { + hr = pStg->CreateStream( reinterpret_cast<LPCWSTR>(aOfficeEmbedStreamName.getStr()), + STGM_CREATE | ( nStreamMode & 0x73 ), + 0, + 0, + &m_pOwnStream ); + + if ( hr == S_OK && m_pOwnStream ) + { + hr = pStg->CreateStream( reinterpret_cast<LPCWSTR>(aExtentStreamName.getStr()), + STGM_CREATE | ( nStreamMode & 0x73 ), + 0, + 0, + &m_pExtStream ); + + if ( hr == S_OK && m_pExtStream ) + { + + m_pMasterStorage = pStg; + m_bIsDirty = sal_True; + } + else + hr = E_FAIL; + } + else + hr = E_FAIL; + } + else + hr = E_FAIL; + } + + if ( hr != S_OK ) + m_pDocHolder->CloseDocument(); + } + } + } + + return hr; +} + +STDMETHODIMP EmbedDocument_Impl::Load( IStorage *pStg ) +{ + if ( m_pDocHolder->GetDocument().is() ) + return CO_E_ALREADYINITIALIZED; + + if ( !m_xFactory.is() || !pStg ) + return E_FAIL; + + HRESULT hr = E_FAIL; + + STATSTG aStat; + hr = pStg->Stat( &aStat, STATFLAG_NONAME ); + if ( FAILED( hr ) ) return E_FAIL; + + DWORD nStreamMode = aStat.grfMode; + hr = pStg->OpenStream( reinterpret_cast<LPCWSTR>(aOfficeEmbedStreamName.getStr()), + 0, + nStreamMode & 0x73, + 0, + &m_pOwnStream ); + if ( !m_pOwnStream ) hr = E_FAIL; + + if ( SUCCEEDED( hr ) ) + { + hr = pStg->OpenStream( reinterpret_cast<LPCWSTR>(aExtentStreamName.getStr()), + 0, + nStreamMode & 0x73, + 0, + &m_pExtStream ); + if ( !m_pExtStream ) hr = E_FAIL; + } + + // RECTL aRectToSet; + SIZEL aSizeToSet; + if ( SUCCEEDED( hr ) ) + { + ULARGE_INTEGER nNewPos; + LARGE_INTEGER aZero = { 0L, 0L }; + hr = m_pExtStream->Seek( aZero, STREAM_SEEK_SET, &nNewPos ); + if ( SUCCEEDED( hr ) ) + { + sal_uInt32 nRead; + sal_Int8 aInf[EXT_STREAM_LENGTH]; + hr = m_pExtStream->Read( (void*)aInf, EXT_STREAM_LENGTH, &nRead ); + if ( nRead != EXT_STREAM_LENGTH ) hr = E_FAIL; + + if ( SUCCEEDED( hr ) ) + { + // aRectToSet.left = *((sal_Int32*)aInf); + // aRectToSet.top = *((sal_Int32*)&aInf[4]); + // aRectToSet.right = *((sal_Int32*)&aInf[8]); + // aRectToSet.bottom = *((sal_Int32*)&aInf[12]); + aSizeToSet.cx = *((sal_Int32*)&aInf[8]) - *((sal_Int32*)aInf); + aSizeToSet.cy = *((sal_Int32*)&aInf[12]) - *((sal_Int32*)&aInf[4]); + } + } + } + + if ( SUCCEEDED( hr ) ) + { + hr = E_FAIL; + + uno::Reference < io::XInputStream > xTempIn = createTempXInStreamFromIStream( m_xFactory, m_pOwnStream ); + if ( xTempIn.is() ) + { + uno::Reference< frame::XModel > aDocument( + m_xFactory->createInstance( getServiceNameFromGUID_Impl( &m_guid ) ), + uno::UNO_QUERY ); + if ( aDocument.is() ) + { + m_pDocHolder->SetDocument( aDocument ); + + uno::Reference< frame::XLoadable > xLoadable( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if( xLoadable.is() ) + { + try + { + xLoadable->load( fillArgsForLoading_Impl( xTempIn, nStreamMode ) ); + m_pMasterStorage = pStg; + hr = m_pDocHolder->SetExtent( &aSizeToSet ); + // hr = m_pDocHolder->SetVisArea( &aRectToSet ); + } + catch( uno::Exception& ) + { + } + } + + if ( FAILED( hr ) ) + m_pDocHolder->CloseDocument(); + } + } + } + + if ( FAILED( hr ) ) + { + m_pOwnStream = CComPtr< IStream >(); + m_pExtStream = CComPtr< IStream >(); + hr = pStg->DestroyElement( reinterpret_cast<LPCWSTR>(aOfficeEmbedStreamName.getStr()) ); + hr = pStg->DestroyElement( reinterpret_cast<LPCWSTR>(aExtentStreamName.getStr()) ); + + OSL_ENSURE( SUCCEEDED( hr ), "Can not destroy created stream!\n" ); + if ( FAILED( hr ) ) + hr = E_FAIL; + } + + return hr; +} + +STDMETHODIMP EmbedDocument_Impl::Save( IStorage *pStgSave, BOOL fSameAsLoad ) +{ + if ( !m_pDocHolder->GetDocument().is() || !m_xFactory.is() || !pStgSave || !m_pOwnStream || !m_pExtStream ) + return E_FAIL; + + CComPtr< IStream > pTargetStream; + CComPtr< IStream > pNewExtStream; + + if ( !fSameAsLoad && pStgSave != m_pMasterStorage ) + { + OSL_ENSURE( m_pMasterStorage, "How could the document be initialized without storage!??\n" ); + HRESULT hr = m_pMasterStorage->CopyTo( NULL, NULL, NULL, pStgSave ); + if ( FAILED( hr ) ) return E_FAIL; + + STATSTG aStat; + hr = pStgSave->Stat( &aStat, STATFLAG_NONAME ); + if ( FAILED( hr ) ) return E_FAIL; + + DWORD nStreamMode = aStat.grfMode; + hr = pStgSave->CreateStream( reinterpret_cast<LPCWSTR>(aOfficeEmbedStreamName.getStr()), + STGM_CREATE | ( nStreamMode & 0x73 ), + 0, + 0, + &pTargetStream ); + if ( FAILED( hr ) || !pTargetStream ) return E_FAIL; + + hr = pStgSave->CreateStream( reinterpret_cast<LPCWSTR>(aExtentStreamName.getStr()), + STGM_CREATE | ( nStreamMode & 0x73 ), + 0, + 0, + &pNewExtStream ); + if ( FAILED( hr ) || !pNewExtStream ) return E_FAIL; + } + else + { + pTargetStream = m_pOwnStream; + pNewExtStream = m_pExtStream; + } + + HRESULT hr = E_FAIL; + + const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) ); + uno::Reference < io::XOutputStream > xTempOut = uno::Reference < io::XOutputStream > ( + m_xFactory->createInstance ( aServiceName ), + uno::UNO_QUERY ); + + if ( xTempOut.is() ) + { + uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if( xStorable.is() ) + { + try + { + xStorable->storeToURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "private:stream" ) ), + fillArgsForStoring_Impl( xTempOut ) ); + hr = copyXTempOutToIStream( xTempOut, pTargetStream ); + if ( SUCCEEDED( hr ) ) + { + // no need to truncate the stream, the size of the stream is always the same + ULARGE_INTEGER nNewPos; + LARGE_INTEGER aZero = { 0L, 0L }; + hr = pNewExtStream->Seek( aZero, STREAM_SEEK_SET, &nNewPos ); + if ( SUCCEEDED( hr ) ) + { + SIZEL aSize; + hr = m_pDocHolder->GetExtent( &aSize ); + + if ( SUCCEEDED( hr ) ) + { + sal_uInt32 nWritten; + sal_Int8 aInf[EXT_STREAM_LENGTH]; + *((sal_Int32*)aInf) = 0; + *((sal_Int32*)&aInf[4]) = 0; + *((sal_Int32*)&aInf[8]) = aSize.cx; + *((sal_Int32*)&aInf[12]) = aSize.cy; + + hr = pNewExtStream->Write( (void*)aInf, EXT_STREAM_LENGTH, &nWritten ); + if ( nWritten != EXT_STREAM_LENGTH ) hr = E_FAIL; + + if ( SUCCEEDED( hr ) ) + { + m_pOwnStream = CComPtr< IStream >(); + m_pExtStream = CComPtr< IStream >(); + if ( fSameAsLoad || pStgSave == m_pMasterStorage ) + { + uno::Reference< util::XModifiable > xMod( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if ( xMod.is() ) + xMod->setModified( sal_False ); + m_bIsDirty = sal_False; + } + } + } + } + } + } + catch( uno::Exception& ) + { + } + } + } + + return hr; +} + +STDMETHODIMP EmbedDocument_Impl::SaveCompleted( IStorage *pStgNew ) +{ + // m_pOwnStream == NULL && m_pMasterStorage != NULL means the object is in NoScribble mode + // m_pOwnStream == NULL && m_pMasterStorage == NULL means the object is in HandsOff mode + + if ( m_pOwnStream || m_pExtStream ) + return E_UNEXPECTED; + + if ( !m_pMasterStorage && !pStgNew ) + return E_INVALIDARG; + + if ( pStgNew ) + m_pMasterStorage = pStgNew; + + STATSTG aStat; + HRESULT hr = m_pMasterStorage->Stat( &aStat, STATFLAG_NONAME ); + if ( FAILED( hr ) ) return E_OUTOFMEMORY; + + DWORD nStreamMode = aStat.grfMode; + hr = m_pMasterStorage->OpenStream( reinterpret_cast<LPCWSTR>(aOfficeEmbedStreamName.getStr()), + 0, + nStreamMode & 0x73, + 0, + &m_pOwnStream ); + if ( FAILED( hr ) || !m_pOwnStream ) return E_OUTOFMEMORY; + + hr = m_pMasterStorage->OpenStream( reinterpret_cast<LPCWSTR>(aExtentStreamName.getStr()), + 0, + nStreamMode & 0x73, + 0, + &m_pExtStream ); + if ( FAILED( hr ) || !m_pExtStream ) return E_OUTOFMEMORY; + + sal_Bool bModified = sal_False; + uno::Reference< util::XModifiable > xMod( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if ( xMod.is() ) + bModified = xMod->isModified(); + + for ( AdviseSinkHashMapIterator iAdvise = m_aAdviseHashMap.begin(); iAdvise != m_aAdviseHashMap.end(); iAdvise++ ) + { + if ( iAdvise->second ) + iAdvise->second->OnSave(); + } + + if ( xMod.is() ) + bModified = xMod->isModified(); + + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::HandsOffStorage() +{ + m_pMasterStorage = CComPtr< IStorage >(); + m_pOwnStream = CComPtr< IStream >(); + m_pExtStream = CComPtr< IStream >(); + + return S_OK; +} + +//------------------------------------------------------------------------------- +// IPersistFile + +STDMETHODIMP EmbedDocument_Impl::Load( LPCOLESTR pszFileName, DWORD /*dwMode*/ ) +{ + if ( m_pDocHolder->GetDocument().is() ) + return CO_E_ALREADYINITIALIZED; + + if ( !m_xFactory.is() ) + return E_FAIL; + + DWORD nStreamMode = STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE | STGM_SHARE_EXCLUSIVE; + HRESULT hr = StgCreateDocfile( NULL, + nStreamMode , + 0, + &m_pMasterStorage ); + + if ( FAILED( hr ) || !m_pMasterStorage ) return E_FAIL; + + ::rtl::OUString aCurType = getServiceNameFromGUID_Impl( &m_guid ); // ??? + CLIPFORMAT cf = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + hr = WriteFmtUserTypeStg( m_pMasterStorage, + cf, // ??? + reinterpret_cast<LPWSTR>(( sal_Unicode* )aCurType.getStr()) ); + if ( FAILED( hr ) ) return E_FAIL; + + hr = m_pMasterStorage->SetClass( m_guid ); + if ( FAILED( hr ) ) return E_FAIL; + + hr = m_pMasterStorage->CreateStream( reinterpret_cast<LPCWSTR>(aOfficeEmbedStreamName.getStr()), + STGM_CREATE | ( nStreamMode & 0x73 ), + 0, + 0, + &m_pOwnStream ); + if ( FAILED( hr ) || !m_pOwnStream ) return E_FAIL; + + hr = m_pMasterStorage->CreateStream( reinterpret_cast<LPCWSTR>(aExtentStreamName.getStr()), + STGM_CREATE | ( nStreamMode & 0x73 ), + 0, + 0, + &m_pExtStream ); + if ( FAILED( hr ) || !m_pExtStream ) return E_FAIL; + + + uno::Reference< frame::XModel > aDocument( + m_xFactory->createInstance( getServiceNameFromGUID_Impl( &m_guid ) ), + uno::UNO_QUERY ); + if ( aDocument.is() ) + { + m_pDocHolder->SetDocument( aDocument, sal_True ); + + uno::Reference< frame::XLoadable > xLoadable( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); + if( xLoadable.is() ) + { + try + { + xLoadable->load( fillArgsForLoading_Impl( uno::Reference< io::XInputStream >(), + STGM_READWRITE, + pszFileName ) ); + hr = S_OK; + + m_aFileName = ::rtl::OUString( reinterpret_cast<const sal_Unicode*>(pszFileName) ); + } + catch( uno::Exception& ) + { + } + } + + if ( hr == S_OK ) + { + ::rtl::OUString aCurType = getServiceNameFromGUID_Impl( &m_guid ); // ??? + CLIPFORMAT cf = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); + hr = WriteFmtUserTypeStg( m_pMasterStorage, + cf, // ??? + reinterpret_cast<LPWSTR>(( sal_Unicode* )aCurType.getStr()) ); + + if ( SUCCEEDED( hr ) ) + { + // no need to truncate the stream, the size of the stream is always the same + ULARGE_INTEGER nNewPos; + LARGE_INTEGER aZero = { 0L, 0L }; + hr = m_pExtStream->Seek( aZero, STREAM_SEEK_SET, &nNewPos ); + if ( SUCCEEDED( hr ) ) + { + SIZEL aSize; + hr = m_pDocHolder->GetExtent( &aSize ); + + if ( SUCCEEDED( hr ) ) + { + sal_uInt32 nWritten; + sal_Int8 aInf[EXT_STREAM_LENGTH]; + *((sal_Int32*)aInf) = 0; + *((sal_Int32*)&aInf[4]) = 0; + *((sal_Int32*)&aInf[8]) = aSize.cx; + *((sal_Int32*)&aInf[12]) = aSize.cy; + + hr = m_pExtStream->Write( (void*)aInf, EXT_STREAM_LENGTH, &nWritten ); + if ( nWritten != EXT_STREAM_LENGTH ) hr = E_FAIL; + } + } + } + + if ( SUCCEEDED( hr ) ) + m_bIsDirty = sal_True; + else + hr = E_FAIL; + } + + if ( FAILED( hr ) ) + { + m_pDocHolder->CloseDocument(); + m_pOwnStream = NULL; + m_pExtStream = NULL; + m_pMasterStorage = NULL; + } + } + + return hr; +} + +STDMETHODIMP EmbedDocument_Impl::Save( LPCOLESTR pszFileName, BOOL fRemember ) +{ + if ( !m_pDocHolder->GetDocument().is() || !m_xFactory.is() ) + return E_FAIL; + + HRESULT hr = E_FAIL; + + // TODO/LATER: currently there is no hands off state implemented + try + { + uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetDocument(), uno::UNO_QUERY_THROW ); + + if ( !pszFileName ) + xStorable->store(); + else + { + util::URL aURL; + aURL.Complete = ::rtl::OUString( reinterpret_cast<const sal_Unicode*>( pszFileName ) ); + + ::rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.util.URLTransformer" ) ); + uno::Reference< util::XURLTransformer > aTransformer( m_xFactory->createInstance( aServiceName ), + uno::UNO_QUERY_THROW ); + + if ( aTransformer->parseSmart( aURL, ::rtl::OUString() ) && aURL.Complete.getLength() ) + { + if ( fRemember ) + { + xStorable->storeAsURL( aURL.Complete, fillArgsForStoring_Impl( uno::Reference< io::XOutputStream >() ) ); + m_aFileName = aURL.Complete; + } + else + xStorable->storeToURL( aURL.Complete, fillArgsForStoring_Impl( uno::Reference< io::XOutputStream >() ) ); + } + } + + hr = S_OK; + } + catch( uno::Exception& ) + { + } + + return hr; +} + +STDMETHODIMP EmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName ) +{ + // the different file name would mean error here + m_aFileName = ::rtl::OUString( reinterpret_cast<const sal_Unicode*>(pszFileName) ); + return S_OK; +} + +STDMETHODIMP EmbedDocument_Impl::GetCurFile( LPOLESTR *ppszFileName ) +{ + CComPtr<IMalloc> pMalloc; + + HRESULT hr = CoGetMalloc( 1, &pMalloc ); + if ( FAILED( hr ) || !pMalloc ) return E_FAIL; + + *ppszFileName = (LPOLESTR)( pMalloc->Alloc( sizeof( sal_Unicode ) * ( m_aFileName.getLength() + 1 ) ) ); + wcsncpy( *ppszFileName, reinterpret_cast<LPCWSTR>(m_aFileName.getStr()), m_aFileName.getLength() + 1 ); + + return m_aFileName.getLength() ? S_OK : S_FALSE; +} + +// =============================================== + +LockedEmbedDocument_Impl EmbeddedDocumentInstanceAccess_Impl::GetEmbedDocument() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + return LockedEmbedDocument_Impl( m_pEmbedDocument ); +} + +void EmbeddedDocumentInstanceAccess_Impl::ClearEmbedDocument() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_pEmbedDocument = NULL; +} + +// =============================================== + +LockedEmbedDocument_Impl::LockedEmbedDocument_Impl() +: m_pEmbedDocument( NULL ) +{} + +LockedEmbedDocument_Impl::LockedEmbedDocument_Impl( EmbedDocument_Impl* pEmbedDocument ) +: m_pEmbedDocument( pEmbedDocument ) +{ + if ( m_pEmbedDocument ) + m_pEmbedDocument->AddRef(); +} + +LockedEmbedDocument_Impl::LockedEmbedDocument_Impl( const LockedEmbedDocument_Impl& aDocLock ) +: m_pEmbedDocument( aDocLock.m_pEmbedDocument ) +{ + if ( m_pEmbedDocument ) + m_pEmbedDocument->AddRef(); +} + +LockedEmbedDocument_Impl& LockedEmbedDocument_Impl::operator=( const LockedEmbedDocument_Impl& aDocLock ) +{ + if ( m_pEmbedDocument ) + m_pEmbedDocument->Release(); + + m_pEmbedDocument = aDocLock.m_pEmbedDocument; + if ( m_pEmbedDocument ) + m_pEmbedDocument->AddRef(); + + return *this; +} + +LockedEmbedDocument_Impl::~LockedEmbedDocument_Impl() +{ + if ( m_pEmbedDocument ) + m_pEmbedDocument->Release(); +} + +void LockedEmbedDocument_Impl::ExecuteMethod( sal_Int16 nId ) +{ + if ( m_pEmbedDocument ) + { + if ( nId == OLESERV_SAVEOBJECT ) + m_pEmbedDocument->SaveObject(); + else if ( nId == OLESERV_CLOSE ) + m_pEmbedDocument->Close( 0 ); + else if ( nId == OLESERV_NOTIFY ) + m_pEmbedDocument->notify(); + else if ( nId == OLESERV_NOTIFYCLOSING ) + m_pEmbedDocument->OLENotifyClosing(); + else if ( nId == OLESERV_SHOWOBJECT ) + m_pEmbedDocument->ShowObject(); + else if ( nId == OLESERV_DEACTIVATE ) + m_pEmbedDocument->Deactivate(); + } +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif + diff --git a/embedserv/source/embed/esdll.cxx b/embedserv/source/embed/esdll.cxx new file mode 100755 index 000000000000..369dda86bd74 --- /dev/null +++ b/embedserv/source/embed/esdll.cxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: esdll.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define STRICT +#define _WIN32_WINNT 0x0400 +#define _WIN32_DCOM +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +#undef _DEBUG +#endif +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#ifdef __MINGW32__ +#define _INIT_ATL_COMMON_VARS +#endif + +#include "stdafx.h" + +#include <atlbase.h> +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4710 ) +#endif +CComModule _Module; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif +#include <atlcom.h> + +BEGIN_OBJECT_MAP(ObjectMap) +END_OBJECT_MAP() + +///////////////////////////////////////////////////////////////////////////// +// DLL Entry Point + + +#include "syswinwrapper.hxx" +#include "docholder.hxx" + + +HINSTANCE DocumentHolder::m_hInstance; + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + DocumentHolder::m_hInstance = hInstance; + if (!winwrap::HatchWindowRegister(hInstance)) + return FALSE; + + if (dwReason == DLL_PROCESS_ATTACH) + { + _Module.Init(ObjectMap, hInstance, NULL); + DisableThreadLibraryCalls(hInstance); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + _Module.Term(); + } + return TRUE; // ok +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif
\ No newline at end of file diff --git a/embedserv/source/embed/guid.cxx b/embedserv/source/embed/guid.cxx new file mode 100755 index 000000000000..340c0681f799 --- /dev/null +++ b/embedserv/source/embed/guid.cxx @@ -0,0 +1,216 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: guid.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "common.h" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> + +::rtl::OUString getStorageTypeFromGUID_Impl( GUID* guid ) +{ + if ( *guid == OID_WriterTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "soffice.StarWriterDocument.6" ) ); + + if ( *guid == OID_WriterOASISTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "opendocument.WriterDocument.1" ) ); + + if ( *guid == OID_CalcServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "soffice.StarCalcDocument.6" ) ); + + if ( *guid == OID_CalcOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "opendocument.CalcDocument.1" ) ); + + if ( *guid == OID_DrawingServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "soffice.StarDrawDocument.6" ) ); + + if ( *guid == OID_DrawingOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "opendocument.DrawDocument.1" ) ); + + if ( *guid == OID_PresentationServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "soffice.StarImpressDocument.6" ) ); + + if ( *guid == OID_PresentationOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "opendocument.ImpressDocument.1" ) ); + + if ( *guid == OID_MathServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "soffice.StarMathDocument.6" ) ); + + if ( *guid == OID_MathOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "opendocument.MathDocument.1" ) ); + + return ::rtl::OUString(); +} + +::rtl::OUString getServiceNameFromGUID_Impl( GUID* guid ) +{ + if ( *guid == OID_WriterTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.TextDocument" ) ); + + if ( *guid == OID_WriterOASISTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.TextDocument" ) ); + + if ( *guid == OID_CalcServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Calc.SpreadsheetDocument" ) ); + + if ( *guid == OID_CalcOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Calc.SpreadsheetDocument" ) ); + + if ( *guid == OID_DrawingServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Draw.DrawingDocument" ) ); + + if ( *guid == OID_DrawingOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Draw.DrawingDocument" ) ); + + if ( *guid == OID_PresentationServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Draw.PresentationDocument" ) ); + + if ( *guid == OID_PresentationOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Draw.PresentationDocument" ) ); + + if ( *guid == OID_MathServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Math.FormulaDocument" ) ); + + if ( *guid == OID_MathOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Math.FormulaDocument" ) ); + + return ::rtl::OUString(); +} + +::rtl::OUString getFilterNameFromGUID_Impl( GUID* guid ) +{ + if ( *guid == OID_WriterTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "StarOffice XML (Writer)" ) ); + + if ( *guid == OID_WriterOASISTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "writer8" ) ); + + if ( *guid == OID_CalcServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "StarOffice XML (Calc)" ) ); + + if ( *guid == OID_CalcOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "calc8" ) ); + + if ( *guid == OID_DrawingServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "StarOffice XML (Draw)" ) ); + + if ( *guid == OID_DrawingOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "draw8" ) ); + + if ( *guid == OID_PresentationServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "StarOffice XML (Impress)" ) ); + + if ( *guid == OID_PresentationOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "impress8" ) ); + + if ( *guid == OID_MathServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "StarOffice XML (Math)" ) ); + + if ( *guid == OID_MathOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "math8" ) ); + + return ::rtl::OUString(); +} + +::rtl::OUString getTestFileURLFromGUID_Impl( GUID* guid ) +{ + if ( *guid == OID_WriterTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.sxw" ) ); + + if ( *guid == OID_WriterOASISTextServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.odt" ) ); + + if ( *guid == OID_CalcServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.sxc" ) ); + + if ( *guid == OID_CalcOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.ods" ) ); + + if ( *guid == OID_DrawingServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.sxd" ) ); + + if ( *guid == OID_DrawingOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.odg" ) ); + + if ( *guid == OID_PresentationServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.sxi" ) ); + + if ( *guid == OID_PresentationOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.odp" ) ); + + if ( *guid == OID_MathServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.sxm" ) ); + + if ( *guid == OID_MathOASISServer ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "file:///d:/OLE_TEST/test.odf" ) ); + + return ::rtl::OUString(); +} + +/* +::rtl::OUString getCurTypeNameFromGUID_Impl( const uno::Reference< lang::XMultiServiceFactory > xFactory, GUID* guid ) +{ + ::rtl::OUString aResult; + + const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.document.FilterFactory" ) ); + uno::Reference < container::XNameAccess > xFilters = uno::Reference < io::XOutputStream > ( + xFactory->createInstance ( aServiceName ), + uno::UNO_QUERY ); + + if ( xFilters.is() ) + { + ::rtl::OUString aFilterName = getFilterNameFromGUID_Impl( guid ); + if ( aFilterName.getLength() ) + { + uno::Any aAnyProp = xFilters->getByName( aFilterName ); + uno::Sequence< beans::PropertyValue > aProperties; + if ( aAnyProp >>= aProperties ) ) + { + for ( sal_Int32 nInd = 0; nInd < aProperties.getLength; nInd++ ) + if ( aProperties[nInd].Name.equalsAscii( "UIName" ) + { + aProperties[nInd].Value >>= aResult; + break; + } + } + } + } + + return aResult; +} +*/ + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/iipaobj.cxx b/embedserv/source/embed/iipaobj.cxx new file mode 100644 index 000000000000..45fcfda78549 --- /dev/null +++ b/embedserv/source/embed/iipaobj.cxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: iipaobj.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "iipaobj.hxx" +#include "embeddoc.hxx" + + + +CIIAObj::CIIAObj(DocumentHolder* pDocHolder) + : m_refCount( 0L ), + m_rDocHolder( pDocHolder ) +{ +} + + +CIIAObj::~CIIAObj() +{ + return; +} + +/* IUnknown methods */ + +STDMETHODIMP CIIAObj::QueryInterface(REFIID riid, LPVOID FAR *ppv) +{ + *ppv=NULL; + + if(IID_IUnknown==riid || + IID_IOleWindow==riid || + IID_IOleInPlaceActiveObject==riid) + *ppv=this; + + //AddRef any interface we'll return. + if (NULL!=*ppv) + { + ((LPUNKNOWN)*ppv)->AddRef(); + return NOERROR; + } + + return ResultFromScode(E_NOINTERFACE); +} + + +STDMETHODIMP_(ULONG) CIIAObj::AddRef(void) +{ + return osl_incrementInterlockedCount( &m_refCount); +} + +STDMETHODIMP_(ULONG) CIIAObj::Release(void) +{ + sal_Int32 nCount = osl_decrementInterlockedCount( &m_refCount); + if ( nCount == 0 ) + delete this; + + return nCount; +} + +/* IOleInPlaceActiveObject methods*/ + +STDMETHODIMP CIIAObj::GetWindow(HWND *) +{ + return NOERROR; +} + +STDMETHODIMP CIIAObj::ContextSensitiveHelp(BOOL) +{ + return NOERROR; +} + +STDMETHODIMP CIIAObj::TranslateAccelerator(LPMSG) +{ + return NOERROR; +} + +STDMETHODIMP CIIAObj::OnFrameWindowActivate(BOOL) +{ + return NOERROR; +} + +STDMETHODIMP CIIAObj::OnDocWindowActivate(BOOL) +{ + return NOERROR; +} + +STDMETHODIMP CIIAObj::ResizeBorder( + LPCRECT pRect,LPOLEINPLACEUIWINDOW,BOOL bFrame) +{ + if(!bFrame) return NOERROR; + + if ( !m_rDocHolder.is() ) + return E_FAIL; + + return m_rDocHolder->SetContRects(pRect); +} + + +STDMETHODIMP CIIAObj::EnableModeless(BOOL) +{ + return NOERROR; +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/intercept.cxx b/embedserv/source/embed/intercept.cxx new file mode 100644 index 000000000000..9ab5edac01bd --- /dev/null +++ b/embedserv/source/embed/intercept.cxx @@ -0,0 +1,592 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: intercept.cxx,v $ + * $Revision: 1.14.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <cppuhelper/weak.hxx> + +#include <embeddoc.hxx> +#include <docholder.hxx> +#include <intercept.hxx> + +using namespace ::com::sun::star; + + + +#define IUL 6 + + + +uno::Sequence< ::rtl::OUString > Interceptor::m_aInterceptedURL(IUL); + + + + +struct equalOUString +{ + bool operator()( + const rtl::OUString& rKey1, + const rtl::OUString& rKey2 ) const + { + return !!( rKey1 == rKey2 ); + } +}; + + +struct hashOUString +{ + size_t operator()( const rtl::OUString& rName ) const + { + return rName.hashCode(); + } +}; + + + +class StatusChangeListenerContainer + : public ::cppu::OMultiTypeInterfaceContainerHelperVar< +rtl::OUString,hashOUString,equalOUString> +{ +public: + StatusChangeListenerContainer( ::osl::Mutex& aMutex ) + : cppu::OMultiTypeInterfaceContainerHelperVar< + rtl::OUString,hashOUString,equalOUString>(aMutex) + { + } +}; + + +void SAL_CALL +Interceptor::addEventListener( + const uno::Reference<lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ! m_pDisposeEventListeners ) + m_pDisposeEventListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +Interceptor::removeEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pDisposeEventListeners ) + m_pDisposeEventListeners->removeInterface( Listener ); +} + + +void SAL_CALL Interceptor::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = static_cast< frame::XDispatch* >( this ); + + osl::MutexGuard aGuard(m_aMutex); + + if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) + m_pDisposeEventListeners->disposeAndClear( aEvt ); + + if(m_pStatCL) + m_pStatCL->disposeAndClear( aEvt ); + + m_xSlaveDispatchProvider = 0; + m_xMasterDispatchProvider = 0; +} + + + +Interceptor::Interceptor( + const ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl >& xOleAccess, + DocumentHolder* pDocH, + sal_Bool bLink ) + : m_xOleAccess( xOleAccess ), + m_xDocHLocker( static_cast< ::cppu::OWeakObject* >( pDocH ) ), + m_pDocH(pDocH), + m_pStatCL(0), + m_pDisposeEventListeners(0), + m_bLink( bLink ) +{ + m_aInterceptedURL[0] = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(".uno:Save")); + m_aInterceptedURL[1] = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll")); + m_aInterceptedURL[2] = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc")); + m_aInterceptedURL[3] = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin")); + m_aInterceptedURL[4] = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame")); + m_aInterceptedURL[5] = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs")); +} + + +Interceptor::~Interceptor() +{ + if( m_pDisposeEventListeners ) + delete m_pDisposeEventListeners; + + if(m_pStatCL) + delete m_pStatCL; + + DocumentHolder* pTmpDocH = NULL; + uno::Reference< uno::XInterface > xLock; + { + osl::MutexGuard aGuard(m_aMutex); + xLock = m_xDocHLocker.get(); + if ( xLock.is() ) + pTmpDocH = m_pDocH; + } + + if ( pTmpDocH ) + pTmpDocH->ClearInterceptor(); +} + +void Interceptor::DisconnectDocHolder() +{ + osl::MutexGuard aGuard(m_aMutex); + m_xDocHLocker = uno::Reference< uno::XInterface >(); + m_pDocH = NULL; + m_xOleAccess = NULL; +} + +//XDispatch +void SAL_CALL +Interceptor::dispatch( + const util::URL& URL, + const uno::Sequence< + beans::PropertyValue >& Arguments ) + throw (uno::RuntimeException) +{ + ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > xOleAccess; + { + osl::MutexGuard aGuard(m_aMutex); + xOleAccess = m_xOleAccess; + } + + if ( xOleAccess.is() ) + { + LockedEmbedDocument_Impl aDocLock = xOleAccess->GetEmbedDocument(); + if ( aDocLock.GetEmbedDocument() ) + { + if( !m_bLink && URL.Complete == m_aInterceptedURL[0]) + aDocLock.GetEmbedDocument()->SaveObject(); + else if(!m_bLink + && ( URL.Complete == m_aInterceptedURL[2] || + URL.Complete == m_aInterceptedURL[3] || + URL.Complete == m_aInterceptedURL[4] ) ) + aDocLock.GetEmbedDocument()->Close( 0 ); + else if ( URL.Complete == m_aInterceptedURL[5] ) + { + uno::Sequence< beans::PropertyValue > aNewArgs = Arguments; + sal_Int32 nInd = 0; + + while( nInd < aNewArgs.getLength() ) + { + if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) ) + { + aNewArgs[nInd].Value <<= sal_True; + break; + } + nInd++; + } + + if ( nInd == aNewArgs.getLength() ) + { + aNewArgs.realloc( nInd + 1 ); + aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" ); + aNewArgs[nInd].Value <<= sal_True; + } + + uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch( + URL, ::rtl::OUString::createFromAscii( "_self" ), 0 ); + if ( xDispatch.is() ) + xDispatch->dispatch( URL, aNewArgs ); + } + } + } +} + + +void Interceptor::generateFeatureStateEvent() +{ + if( m_pStatCL ) + { + DocumentHolder* pTmpDocH = NULL; + uno::Reference< uno::XInterface > xLock; + { + osl::MutexGuard aGuard(m_aMutex); + xLock = m_xDocHLocker.get(); + if ( xLock.is() ) + pTmpDocH = m_pDocH; + } + + ::rtl::OUString aTitle; + if ( pTmpDocH ) + aTitle = pTmpDocH->getTitle(); + + for(int i = 0; i < IUL; ++i) + { + if( i == 1 || m_bLink && i != 5 ) + continue; + + cppu::OInterfaceContainerHelper* pICH = + m_pStatCL->getContainer(m_aInterceptedURL[i]); + uno::Sequence<uno::Reference<uno::XInterface> > aSeq; + if(pICH) + aSeq = pICH->getElements(); + if(!aSeq.getLength()) + continue; + + frame::FeatureStateEvent aStateEvent; + aStateEvent.IsEnabled = sal_True; + aStateEvent.Requery = sal_False; + if(i == 0) + { + + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Update")); + aStateEvent.State <<= (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("($1) ")) + + aTitle); + + } + else if ( i == 5 ) + { + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo")); + aStateEvent.State <<= (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("($3)"))); + } + else + { + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Close and Return")); + aStateEvent.State <<= (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("($2) ")) + + aTitle); + + } + + for(sal_Int32 k = 0; k < aSeq.getLength(); ++k) + { + uno::Reference<frame::XStatusListener> + Control(aSeq[k],uno::UNO_QUERY); + if(Control.is()) + Control->statusChanged(aStateEvent); + + } + } + } +} + + +void SAL_CALL +Interceptor::addStatusListener( + const uno::Reference< + frame::XStatusListener >& Control, + const util::URL& URL ) + throw ( + uno::RuntimeException + ) +{ + if(!Control.is()) + return; + + if( !m_bLink && URL.Complete == m_aInterceptedURL[0] ) + { // Save + DocumentHolder* pTmpDocH = NULL; + uno::Reference< uno::XInterface > xLock; + { + osl::MutexGuard aGuard(m_aMutex); + xLock = m_xDocHLocker.get(); + if ( xLock.is() ) + pTmpDocH = m_pDocH; + } + + ::rtl::OUString aTitle; + if ( pTmpDocH ) + aTitle = pTmpDocH->getTitle(); + + frame::FeatureStateEvent aStateEvent; + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Update")); + aStateEvent.IsEnabled = sal_True; + aStateEvent.Requery = sal_False; + aStateEvent.State <<= (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("($1) ")) + + aTitle ); + Control->statusChanged(aStateEvent); + + { + osl::MutexGuard aGuard(m_aMutex); + if(!m_pStatCL) + m_pStatCL = + new StatusChangeListenerContainer(m_aMutex); + } + + m_pStatCL->addInterface(URL.Complete,Control); + return; + } + + sal_Int32 i = 2; + if ( !m_bLink + && ( URL.Complete == m_aInterceptedURL[i] || + URL.Complete == m_aInterceptedURL[++i] || + URL.Complete == m_aInterceptedURL[++i] ) ) + { // Close and return + DocumentHolder* pTmpDocH = NULL; + uno::Reference< uno::XInterface > xLock; + { + osl::MutexGuard aGuard(m_aMutex); + xLock = m_xDocHLocker.get(); + if ( xLock.is() ) + pTmpDocH = m_pDocH; + } + + ::rtl::OUString aTitle; + if ( pTmpDocH ) + aTitle = pTmpDocH->getTitle(); + + frame::FeatureStateEvent aStateEvent; + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Close and Return")); + aStateEvent.IsEnabled = sal_True; + aStateEvent.Requery = sal_False; + aStateEvent.State <<= (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("($2) ")) + + aTitle ); + Control->statusChanged(aStateEvent); + + + { + osl::MutexGuard aGuard(m_aMutex); + if(!m_pStatCL) + m_pStatCL = + new StatusChangeListenerContainer(m_aMutex); + } + + m_pStatCL->addInterface(URL.Complete,Control); + return; + } + + if(URL.Complete == m_aInterceptedURL[5]) + { // SaveAs + frame::FeatureStateEvent aStateEvent; + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo")); + aStateEvent.IsEnabled = sal_True; + aStateEvent.Requery = sal_False; + aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)"))); + Control->statusChanged(aStateEvent); + + { + osl::MutexGuard aGuard(m_aMutex); + if(!m_pStatCL) + m_pStatCL = + new StatusChangeListenerContainer(m_aMutex); + } + + m_pStatCL->addInterface(URL.Complete,Control); + return; + } + +} + + +void SAL_CALL +Interceptor::removeStatusListener( + const uno::Reference< + frame::XStatusListener >& Control, + const util::URL& URL ) + throw ( + uno::RuntimeException + ) +{ + if(!(Control.is() && m_pStatCL)) + return; + else { + m_pStatCL->removeInterface(URL.Complete,Control); + return; + } +} + + +//XInterceptorInfo +uno::Sequence< ::rtl::OUString > +SAL_CALL +Interceptor::getInterceptedURLs( ) + throw ( + uno::RuntimeException + ) +{ + // now implemented as update + if ( m_bLink ) + { + uno::Sequence< ::rtl::OUString > aResult( 2 ); + aResult[0] = m_aInterceptedURL[1]; + aResult[1] = m_aInterceptedURL[5]; + + return aResult; + } + + return m_aInterceptedURL; +} + + +// XDispatchProvider + +uno::Reference< frame::XDispatch > SAL_CALL +Interceptor::queryDispatch( + const util::URL& URL, + const ::rtl::OUString& TargetFrameName, + sal_Int32 SearchFlags ) + throw ( + uno::RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + if( !m_bLink && URL.Complete == m_aInterceptedURL[0] ) + return (frame::XDispatch*)this; + else if(URL.Complete == m_aInterceptedURL[1]) + return (frame::XDispatch*)0 ; + else if( !m_bLink && URL.Complete == m_aInterceptedURL[2] ) + return (frame::XDispatch*)this; + else if( !m_bLink && URL.Complete == m_aInterceptedURL[3] ) + return (frame::XDispatch*)this; + else if( !m_bLink && URL.Complete == m_aInterceptedURL[4] ) + return (frame::XDispatch*)this; + else if(URL.Complete == m_aInterceptedURL[5]) + return (frame::XDispatch*)this; + else { + if(m_xSlaveDispatchProvider.is()) + return m_xSlaveDispatchProvider->queryDispatch( + URL,TargetFrameName,SearchFlags); + else + return uno::Reference<frame::XDispatch>(0); + } +} + +uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL +Interceptor::queryDispatches( + const uno::Sequence<frame::DispatchDescriptor >& Requests ) + throw ( + uno::RuntimeException + ) +{ + uno::Sequence< uno::Reference< frame::XDispatch > > aRet; + osl::MutexGuard aGuard(m_aMutex); + if(m_xSlaveDispatchProvider.is()) + aRet = m_xSlaveDispatchProvider->queryDispatches(Requests); + else + aRet.realloc(Requests.getLength()); + + for(sal_Int32 i = 0; i < Requests.getLength(); ++i) + if ( !m_bLink && m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete ) + aRet[i] = (frame::XDispatch*) this; + else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete) + aRet[i] = (frame::XDispatch*) 0; + else if( !m_bLink && m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete ) + aRet[i] = (frame::XDispatch*) this; + else if( !m_bLink && m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete ) + aRet[i] = (frame::XDispatch*) this; + else if( !m_bLink && m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete ) + aRet[i] = (frame::XDispatch*) this; + else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete) + aRet[i] = (frame::XDispatch*) this; + + return aRet; +} + + + +//XDispatchProviderInterceptor + +uno::Reference< frame::XDispatchProvider > SAL_CALL +Interceptor::getSlaveDispatchProvider( ) + throw ( + uno::RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + return m_xSlaveDispatchProvider; +} + +void SAL_CALL +Interceptor::setSlaveDispatchProvider( + const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider ) + throw ( + uno::RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + m_xSlaveDispatchProvider = NewDispatchProvider; +} + + +uno::Reference< frame::XDispatchProvider > SAL_CALL +Interceptor::getMasterDispatchProvider( ) + throw ( + uno::RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + return m_xMasterDispatchProvider; +} + + +void SAL_CALL +Interceptor::setMasterDispatchProvider( + const uno::Reference< frame::XDispatchProvider >& NewSupplier ) + throw ( + uno::RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + m_xMasterDispatchProvider = NewSupplier; +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/makefile.mk b/embedserv/source/embed/makefile.mk new file mode 100755 index 000000000000..69cae028349f --- /dev/null +++ b/embedserv/source/embed/makefile.mk @@ -0,0 +1,85 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.9 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#MKDEPENDSOLVER=YES + +PRJ=..$/.. + +PRJNAME=embedserv +TARGET=emser + + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +#.INCLUDE : $(PRJ)$/util$/makefile.pmk + +.IF "$(DISABLE_ATL)"=="" + +LIBTARGET=NO +USE_DEFFILE=NO + +INCPRE+= $(ATL_INCLUDE) + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/register.obj \ + $(SLO)$/servprov.obj \ + $(SLO)$/docholder.obj \ + $(SLO)$/ed_ipersiststr.obj \ + $(SLO)$/ed_idataobj.obj \ + $(SLO)$/ed_ioleobject.obj \ + $(SLO)$/ed_iinplace.obj \ + $(SLO)$/iipaobj.obj \ + $(SLO)$/guid.obj \ + $(SLO)$/esdll.obj \ + $(SLO)$/intercept.obj \ + $(SLO)$/syswinwrapper.obj \ + $(SLO)$/tracker.obj + +EXCEPTIONSFILES= \ + $(SLO)$/register.obj \ + $(SLO)$/docholder.obj \ + $(SLO)$/ed_ipersiststr.obj \ + $(SLO)$/ed_idataobj.obj \ + $(SLO)$/ed_iinplace.obj \ + $(SLO)$/ed_ioleobject.obj \ + $(SLO)$/iipaobj.obj \ + $(SLO)$/intercept.obj \ + $(SLO)$/syswinwrapper.obj \ + $(SLO)$/tracker.obj + +.ENDIF +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/embedserv/source/embed/register.cxx b/embedserv/source/embed/register.cxx new file mode 100755 index 000000000000..eed34e984821 --- /dev/null +++ b/embedserv/source/embed/register.cxx @@ -0,0 +1,136 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: register.cxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#ifdef __MINGW32__ +#define INITGUID +#endif +#include "servprov.hxx" +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/InvalidRegistryException.hpp> +#include <rtl/ustring.h> +#include <cppuhelper/factory.hxx> + + +using namespace ::com::sun::star; + + +uno::Reference<uno::XInterface> SAL_CALL EmbedServer_createInstance( + const uno::Reference<lang::XMultiServiceFactory> & xSMgr) +throw (uno::Exception) +{ + uno::Reference<uno::XInterface > xService = *new EmbedServer_Impl( xSMgr ); + return xService; +} + +::rtl::OUString SAL_CALL EmbedServer_getImplementationName() throw() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.ole.EmbedServer") ); + +} + +uno::Sequence< ::rtl::OUString > SAL_CALL EmbedServer_getSupportedServiceNames() throw() +{ + uno::Sequence< ::rtl::OUString > aServiceNames( 1 ); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.OleEmbeddedServerRegistration" ) ); + return aServiceNames; +} + +extern "C" { + +void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) +{ + void * pRet = 0; + + ::rtl::OUString aImplName( ::rtl::OUString::createFromAscii( pImplName ) ); + uno::Reference< lang::XSingleServiceFactory > xFactory; + + if(pServiceManager && aImplName.equals( EmbedServer_getImplementationName() ) ) + { + xFactory= ::cppu::createOneInstanceFactory( reinterpret_cast< lang::XMultiServiceFactory*>(pServiceManager), + EmbedServer_getImplementationName(), + EmbedServer_createInstance, + EmbedServer_getSupportedServiceNames() ); + } + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + +sal_Bool SAL_CALL component_writeInfo( void * /*pServiceManager*/, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + uno::Reference< registry::XRegistryKey > xKey( reinterpret_cast< registry::XRegistryKey* >( pRegistryKey ) ); + + uno::Reference< registry::XRegistryKey > xNewKey; + + xNewKey = xKey->createKey( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + + EmbedServer_getImplementationName() + + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) ); + + uno::Sequence< ::rtl::OUString > rServices = EmbedServer_getSupportedServiceNames(); + for( sal_Int32 ind = 0; ind < rServices.getLength(); ind++ ) + xNewKey->createKey( rServices.getConstArray()[ind] ); + + return sal_True; + } + catch (registry::InvalidRegistryException &) + { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} + +} // extern "C" + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif
\ No newline at end of file diff --git a/embedserv/source/embed/servprov.cxx b/embedserv/source/embed/servprov.cxx new file mode 100755 index 000000000000..87cd69d7d9b9 --- /dev/null +++ b/embedserv/source/embed/servprov.cxx @@ -0,0 +1,308 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: servprov.cxx,v $ + * $Revision: 1.12 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "stdafx.h" +#include "servprov.hxx" +#include "embeddoc.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <cppuhelper/typeprovider.hxx> +#include <osl/mutex.hxx> +#include <osl/thread.h> + +using namespace com::sun::star; + +const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = { + &OID_WriterTextServer, + &OID_WriterOASISTextServer, + &OID_CalcServer, + &OID_CalcOASISServer, + &OID_DrawingServer, + &OID_DrawingOASISServer, + &OID_PresentationServer, + &OID_PresentationOASISServer, + &OID_MathServer, + &OID_MathOASISServer +}; + +class CurThreadData +{ + public: + CurThreadData(); + virtual ~CurThreadData(); + + sal_Bool SAL_CALL setData(void *pData); + + void* SAL_CALL getData(); + + protected: + oslThreadKey m_hKey; +}; + +CurThreadData::CurThreadData() +{ + m_hKey = osl_createThreadKey( (oslThreadKeyCallbackFunction)NULL ); +} + +CurThreadData::~CurThreadData() +{ + osl_destroyThreadKey(m_hKey); +} + +sal_Bool CurThreadData::setData(void *pData) +{ + OSL_ENSURE( m_hKey, "No thread key!\n" ); + return (osl_setThreadKeyData(m_hKey, pData)); +} + +void *CurThreadData::getData() +{ + OSL_ENSURE( m_hKey, "No thread key!\n" ); + return (osl_getThreadKeyData(m_hKey)); +} + + +// CoInitializeEx * +typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *ptrCoInitEx)( LPVOID, DWORD); +// CoInitialize * +typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *ptrCoInit)( LPVOID); + +void o2u_attachCurrentThread() +{ + static CurThreadData oleThreadData; + + if ( oleThreadData.getData() != 0 ) + { + HINSTANCE inst= LoadLibrary( _T("ole32.dll")); + if( inst ) + { + HRESULT hr; + ptrCoInitEx initFuncEx= (ptrCoInitEx)GetProcAddress( inst, _T("CoInitializeEx")); + if( initFuncEx) + hr= initFuncEx( NULL, COINIT_MULTITHREADED); + else + { + ptrCoInit initFunc= (ptrCoInit)GetProcAddress( inst,_T("CoInitialize")); + if( initFunc) + hr= initFunc( NULL); + } + } + oleThreadData.setData((void*)sal_True); + } +} + + +//=============================================================================== +// EmbedServer_Impl + +EmbedServer_Impl::EmbedServer_Impl( const uno::Reference<lang::XMultiServiceFactory>& xFactory): + m_xFactory( xFactory) +{ + for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ ) + { + m_pOLEFactories[nInd] = new EmbedProviderFactory_Impl( m_xFactory, guidList[nInd] ); + m_pOLEFactories[nInd]->registerClass(); + } +} + +EmbedServer_Impl::~EmbedServer_Impl() +{ + for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ ) + { + if ( m_pOLEFactories[nInd] ) + m_pOLEFactories[nInd]->deregisterClass(); + } +} + +// XInterface -------------------------------------------------- +uno::Any SAL_CALL +EmbedServer_Impl::queryInterface( + const uno::Type& aType ) + throw( + uno::RuntimeException + ) +{ + uno::Any a= + ::cppu::queryInterface( + aType, static_cast<lang::XTypeProvider*>(this)); + if( a == uno::Any()) + return OWeakObject::queryInterface( aType); + else + return a; +} + +void SAL_CALL EmbedServer_Impl::acquire( ) throw(uno::RuntimeException) +{ + OWeakObject::acquire(); +} + +void SAL_CALL EmbedServer_Impl::release( ) throw (uno::RuntimeException) +{ + OWeakObject::release(); +} + + +// XTypeProvider -------------------------------------------------- +uno::Sequence< uno::Type > SAL_CALL +EmbedServer_Impl::getTypes( ) + throw( + uno::RuntimeException + ) +{ + static ::cppu::OTypeCollection *pCollection = 0; + if( ! pCollection ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( ! pCollection ) + { + static ::cppu::OTypeCollection collection( + getCppuType( + reinterpret_cast<uno::Reference< uno::XWeak>*>(0)), + getCppuType( + reinterpret_cast< + uno::Reference< lang::XTypeProvider>*>(0))); + pCollection = &collection; + } + } + return (*pCollection).getTypes(); +} + +uno::Sequence< sal_Int8 > SAL_CALL EmbedServer_Impl::getImplementationId() throw(uno::RuntimeException) +{ + static ::cppu::OImplementationId *pId = 0; + if( ! pId ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( ! pId ) + { + static ::cppu::OImplementationId id( sal_False ); + pId = &id; + } + } + return (*pId).getImplementationId(); +} + +//=============================================================================== +// EmbedProviderFactory_Impl + +EmbedProviderFactory_Impl::EmbedProviderFactory_Impl(const uno::Reference<lang::XMultiServiceFactory>& xFactory, const GUID* pGuid) + : m_refCount( 0L ) + , m_xFactory( xFactory ) + , m_guid( *pGuid ) +{ +} + +EmbedProviderFactory_Impl::~EmbedProviderFactory_Impl() +{ +} + +sal_Bool EmbedProviderFactory_Impl::registerClass() +{ + HRESULT hresult; + + o2u_attachCurrentThread(); + + hresult = CoRegisterClassObject( + m_guid, + this, + CLSCTX_LOCAL_SERVER, + REGCLS_MULTIPLEUSE, + &m_factoryHandle); + + return (hresult == NOERROR); +} + +sal_Bool EmbedProviderFactory_Impl::deregisterClass() +{ + HRESULT hresult = CoRevokeClassObject( m_factoryHandle ); + + return (hresult == NOERROR); +} + +STDMETHODIMP EmbedProviderFactory_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + AddRef(); + *ppv = (IUnknown*) (IClassFactory*) this; + return NOERROR; + } + else if (IsEqualIID(riid, IID_IClassFactory)) + { + AddRef(); + *ppv = (IClassFactory*) this; + return NOERROR; + } + + *ppv = NULL; + return ResultFromScode(E_NOINTERFACE); +} + +STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::AddRef() +{ + return osl_incrementInterlockedCount( &m_refCount); +} + +STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::Release() +{ + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex()); + sal_Int32 nCount = --m_refCount; + if ( nCount == 0 ) + { + delete this; + } + + return nCount; +} + +STDMETHODIMP EmbedProviderFactory_Impl::CreateInstance(IUnknown FAR* punkOuter, + REFIID riid, + void FAR* FAR* ppv) +{ + punkOuter = NULL; + + IUnknown* pEmbedDocument = (IUnknown*)(IPersistStorage*)( new EmbedDocument_Impl( m_xFactory, &m_guid ) ); + + return pEmbedDocument->QueryInterface( riid, ppv ); +} + +STDMETHODIMP EmbedProviderFactory_Impl::LockServer( int /*fLock*/ ) +{ + return NOERROR; +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/stdafx.cpp b/embedserv/source/embed/stdafx.cpp new file mode 100755 index 000000000000..0db31dca718d --- /dev/null +++ b/embedserv/source/embed/stdafx.cpp @@ -0,0 +1,14 @@ +// stdafx1.cpp : source file that includes just the standard includes +// stdafx1.pch will be the pre-compiled header +// stdafx1.obj will contain the pre-compiled type information + + +#include "stdafx2.h" + +#ifdef _ATL_STATIC_REGISTRY +#include <statreg.h> +#include <statreg.cpp> +#endif + +#include <atlimpl.cpp> + diff --git a/embedserv/source/embed/syswinwrapper.cxx b/embedserv/source/embed/syswinwrapper.cxx new file mode 100644 index 000000000000..613f4c73bfae --- /dev/null +++ b/embedserv/source/embed/syswinwrapper.cxx @@ -0,0 +1,480 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: syswinwrapper.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "docholder.hxx" +#include "syswinwrapper.hxx" + +/* + * CWindow::CWindow + * CWindow::~CWindow + * + * Constructor Parameters: + * hInst HINSTANCE of the task owning us. + */ + + +using namespace winwrap; + + +#define HWWL_STRUCTURE 0 + +//Notification codes for WM_COMMAND messages +#define HWN_BORDERDOUBLECLICKED 1 +#define CBHATCHWNDEXTRA (sizeof(LONG)) +#define SZCLASSHATCHWIN TEXT("hatchwin") +#define SendCommand(hWnd, wID, wCode, hControl) \ + SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(wID, wCode) \ + , (LPARAM)hControl) + + +typedef CHatchWin *PCHatchWin; + + +void DrawShading(LPRECT prc, HDC hDC, UINT cWidth); + + + +winwrap::CWindow::CWindow(HINSTANCE hInst) +{ + m_hInst=hInst; + m_hWnd=NULL; + return; +} + +winwrap::CWindow::~CWindow(void) +{ + if (IsWindow(m_hWnd)) + DestroyWindow(m_hWnd); + + return; +} + + + +/* + * CWindow::Window + * + * Purpose: + * Returns the window handle associated with this object. + * + * Return Value: + * HWND Window handle for this object + */ + +HWND winwrap::CWindow::Window(void) +{ + return m_hWnd; +} + + + +/* + * CWindow::Instance + * + * Purpose: + * Returns the instance handle associated with this object. + * + * Return Value: + * HINSTANCE Instance handle of the module stored here. + */ + +HINSTANCE winwrap::CWindow::Instance(void) +{ + return m_hInst; +} + + + + + +//Hatch pattern brush bits +static WORD g_wHatchBmp[]={0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}; + +// void DrawShading(LPRECT, HDC, UINT); + + +/* + * HatchWindowRegister + * + * Purpose: + * Registers the hatch window class for use with CHatchWin. + * + * Parameters: + * hInst HINSTANCE under which to register. + * + * Return Value: + * BOOL TRUE if successful, FALSE otherwise. + */ + +BOOL winwrap::HatchWindowRegister(HINSTANCE hInst) +{ + WNDCLASS wc; + + //Must have CS_DBLCLKS for border! + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wc.hInstance = hInst; + wc.cbClsExtra = 0; + wc.lpfnWndProc = HatchWndProc; + wc.cbWndExtra = CBHATCHWNDEXTRA; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = SZCLASSHATCHWIN; + + return RegisterClass(&wc); + return FALSE; +} + + + + +/* + * CHatchWin:CHatchWin + * CHatchWin::~CHatchWin + * + * Constructor Parameters: + * hInst HINSTANCE of the application we're in. + */ + +CHatchWin::CHatchWin(HINSTANCE hInst,const DocumentHolder* pDocHolder) + : CWindow(hInst), + m_aTracker() +{ + m_hWnd=NULL; + m_hWndKid=NULL; + m_hWndAssociate=NULL; + m_uID=0; + + m_dBorderOrg=GetProfileInt(TEXT("windows") + , TEXT("OleInPlaceBorderWidth") + , HATCHWIN_BORDERWIDTHDEFAULT); + + m_dBorder=m_dBorderOrg; + SetRect(&m_rcPos, 0, 0, 0, 0); + SetRect(&m_rcClip, 0, 0, 0, 0); + + m_pDocHolder = pDocHolder; + return; +} + + +CHatchWin::~CHatchWin(void) +{ + /* + * Chances are this was already destroyed when a document + * was destroyed. + */ + if (NULL!=m_hWnd && IsWindow(m_hWnd)) + DestroyWindow(m_hWnd); + + return; +} + + + +/* + * CHatchWin::Init + * + * Purpose: + * Instantiates a hatch window within a given parent with a + * default rectangle. This is not initially visible. + * + * Parameters: + * hWndParent HWND of the parent of this window + * uID UINT identifier for this window (send in + * notifications to associate window). + * hWndAssoc HWND of the initial associate. + * + * Return Value: + * BOOL TRUE if the function succeeded, FALSE otherwise. + */ + +BOOL CHatchWin::Init(HWND hWndParent, UINT uID, HWND hWndAssoc) +{ + m_hWndParent = hWndParent; + m_hWnd=CreateWindowEx( + WS_EX_NOPARENTNOTIFY, SZCLASSHATCHWIN + , SZCLASSHATCHWIN, WS_CHILD | WS_CLIPSIBLINGS + | WS_CLIPCHILDREN, 0, 0, 100, 100, hWndParent, (HMENU)uID + , m_hInst, this); + + m_uID=uID; + m_hWndAssociate=hWndAssoc; + + return (NULL!=m_hWnd); +} + + +void CHatchWin::SetTrans() +{ + HRGN hrgn = CreateRectRgn(0,0,0,0); + SetWindowRgn(m_hWnd,hrgn,true); +} + +/* + * CHatchWin::HwndAssociateSet + * CHatchWin::HwndAssociateGet + * + * Purpose: + * Sets (Set) or retrieves (Get) the associate window of the + * hatch window. + * + * Parameters: (Set only) + * hWndAssoc HWND to set as the associate. + * + * Return Value: + * HWND Previous (Set) or current (Get) associate + * window. + */ + +HWND CHatchWin::HwndAssociateSet(HWND hWndAssoc) +{ + HWND hWndT=m_hWndAssociate; + + m_hWndAssociate=hWndAssoc; + return hWndT; +} + + +HWND CHatchWin::HwndAssociateGet(void) +{ + return m_hWndAssociate; +} + + +/* + * CHatchWin::RectsSet + * + * Purpose: + * Changes the size and position of the hatch window and the child + * window within it using a position rectangle for the child and + * a clipping rectangle for the hatch window and child. The hatch + * window occupies prcPos expanded by the hatch border and clipped + * by prcClip. The child window is fit to prcPos to give the + * proper scaling, but it clipped to the hatch window which + * therefore clips it to prcClip without affecting the scaling. + * + * Parameters: + * prcPos LPRECT providing the position rectangle. + * prcClip LPRECT providing the clipping rectangle. + * + * Return Value: + * None + */ + +void CHatchWin::RectsSet(LPRECT prcPos, LPRECT prcClip) +{ + RECT rc; + RECT rcPos; + + m_rcPos=*prcPos; + m_rcClip=*prcClip; + + //Calculate the rectangle for the hatch window, then clip it. + rcPos=*prcPos; + InflateRect(&rcPos, m_dBorder, m_dBorder); + IntersectRect(&rc, &rcPos, prcClip); + + SetWindowPos(m_hWnd, NULL, rc.left, rc.top, rc.right-rc.left + , rc.bottom-rc.top, SWP_NOZORDER | SWP_NOACTIVATE); + + /* + * Set the rectangle of the child window to be at m_dBorder + * from the top and left but with the same size as prcPos + * contains. The hatch window will clip it. + */ +// SetWindowPos(m_hWndKid, NULL, rcPos.left-rc.left+m_dBorder +// , rcPos.top-rc.top+m_dBorder, prcPos->right-prcPos->left +// , prcPos->bottom-prcPos->top, SWP_NOZORDER | SWP_NOACTIVATE); + + RECT newRC; + GetClientRect(m_hWnd,&newRC); + m_aTracker = Tracker( + &newRC, + Tracker::hatchInside | + Tracker::hatchedBorder | + Tracker::resizeInside + ); + + return; +} + + + +/* + * CHatchWin::ChildSet + * + * Purpose: + * Assigns a child window to this hatch window. + * + * Parameters: + * hWndKid HWND of the child window. + * + * Return Value: + * None + */ + +void CHatchWin::ChildSet(HWND hWndKid) +{ + m_hWndKid=hWndKid; + + if (NULL!=hWndKid) + { + SetParent(hWndKid, m_hWnd); + + //Insure this is visible when the hatch window becomes visible. + ShowWindow(hWndKid, SW_SHOW); + } + + return; +} + + + +/* + * CHatchWin::ShowHatch + * + * Purpose: + * Turns hatching on and off; turning the hatching off changes + * the size of the window to be exactly that of the child, leaving + * everything else the same. The result is that we don't have + * to turn off drawing because our own WM_PAINT will never be + * called. + * + * Parameters: + * fHatch BOOL indicating to show (TRUE) or hide (FALSE) + the hatching. + * + * Return Value: + * None + */ + +void CHatchWin::ShowHatch(BOOL fHatch) +{ + /* + * All we have to do is set the border to zero and + * call SetRects again with the last rectangles the + * child sent to us. + */ + m_dBorder=fHatch ? m_dBorderOrg : 0; + RectsSet(&m_rcPos, &m_rcClip); + return; +} + + + +/* + * HatchWndProc + * + * Purpose: + * Standard window procedure for the Hatch Window + */ + +LRESULT APIENTRY winwrap::HatchWndProc( + HWND hWnd, UINT iMsg + , WPARAM wParam, LPARAM lParam) +{ + PCHatchWin phw; + HDC hDC; + PAINTSTRUCT ps; + + phw=(PCHatchWin)GetWindowLong(hWnd, HWWL_STRUCTURE); + POINT ptMouse; + + switch (iMsg) + { + case WM_CREATE: + phw=(PCHatchWin)((LPCREATESTRUCT)lParam)->lpCreateParams; + SetWindowLong(hWnd, HWWL_STRUCTURE, (LONG)phw); + break; + case WM_PAINT: + hDC=BeginPaint(hWnd,&ps); + //Always draw the hatching. + phw->m_aTracker.Draw(hDC); + EndPaint(hWnd,&ps); + break; + case WM_LBUTTONDOWN: + GetCursorPos(&ptMouse); + ScreenToClient(hWnd,&ptMouse); + + // track in case we have to + if(phw->m_aTracker.Track(hWnd,ptMouse,FALSE,GetParent(hWnd))) + { + RECT aRect = phw->m_aTracker.m_rect; + TransformRect(&aRect,hWnd,GetParent(hWnd)); + phw->m_pDocHolder->OnPosRectChanged(&aRect); + } + break; + case WM_LBUTTONUP: + case WM_MOUSEMOVE: + GetCursorPos(&ptMouse); + ScreenToClient(hWnd,&ptMouse); + phw->m_aTracker.SetCursor(hWnd,HTCLIENT); + break; + case WM_SETFOCUS: + //We need this since the container will SetFocus to us. + if (NULL!=phw->m_hWndKid) + SetFocus(phw->m_hWndKid); + + break; + case WM_LBUTTONDBLCLK: + /* + * If the double click was within m_dBorder of an + * edge, send the HWN_BORDERDOUBLECLICKED notification. + * + * Because we're always sized just larger than our child + * window by the border width, we can only *get* this + * message when the mouse is on the border. So we can + * just send the notification. + */ + if (NULL!=phw->m_hWndAssociate) + { + SendCommand(phw->m_hWndAssociate, phw->m_uID + , HWN_BORDERDOUBLECLICKED, hWnd); + } + + break; + default: + return DefWindowProc(hWnd, iMsg, wParam, lParam); + } + + return 0L; +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/tracker.cxx b/embedserv/source/embed/tracker.cxx new file mode 100644 index 000000000000..0c1c1d67982d --- /dev/null +++ b/embedserv/source/embed/tracker.cxx @@ -0,0 +1,841 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tracker.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "stdafx.h" +#include <stddef.h> +#include "syswinwrapper.hxx" + + +HCURSOR _afxCursors[10] = { 0, }; +HBRUSH _afxHalftoneBrush = 0; + + +// the struct below is used to determine the qualities of a particular handle +struct AFX_HANDLEINFO +{ + size_t nOffsetX; // offset within RECT for X coordinate + size_t nOffsetY; // offset within RECT for Y coordinate + int nCenterX; // adjust X by Width()/2 * this number + int nCenterY; // adjust Y by Height()/2 * this number + int nHandleX; // adjust X by handle size * this number + int nHandleY; // adjust Y by handle size * this number + int nInvertX; // handle converts to this when X inverted + int nInvertY; // handle converts to this when Y inverted +}; + +// this array describes all 8 handles (clock-wise) +const AFX_HANDLEINFO _afxHandleInfo[] = +{ + // corner handles (top-left, top-right, bottom-right, bottom-left + { offsetof(RECT, left), offsetof(RECT, top), 0, 0, 0, 0, 1, 3 }, + { offsetof(RECT, right), offsetof(RECT, top), 0, 0, -1, 0, 0, 2 }, + { offsetof(RECT, right), offsetof(RECT, bottom), 0, 0, -1, -1, 3, 1 }, + { offsetof(RECT, left), offsetof(RECT, bottom), 0, 0, 0, -1, 2, 0 }, + + // side handles (top, right, bottom, left) + { offsetof(RECT, left), offsetof(RECT, top), 1, 0, 0, 0, 4, 6 }, + { offsetof(RECT, right), offsetof(RECT, top), 0, 1, -1, 0, 7, 5 }, + { offsetof(RECT, left), offsetof(RECT, bottom), 1, 0, 0, -1, 6, 4 }, + { offsetof(RECT, left), offsetof(RECT, top), 0, 1, 0, 0, 5, 7 } +}; + +// the struct below gives us information on the layout of a RECT struct and +// the relationship between its members +struct AFX_RECTINFO +{ + size_t nOffsetAcross; // offset of opposite point (ie. left->right) + int nSignAcross; // sign relative to that point (ie. add/subtract) +}; + +// this array is indexed by the offset of the RECT member / sizeof(int) +const AFX_RECTINFO _afxRectInfo[] = +{ + { offsetof(RECT, right), +1 }, + { offsetof(RECT, bottom), +1 }, + { offsetof(RECT, left), -1 }, + { offsetof(RECT, top), -1 }, +}; + + +HBRUSH HalftoneBrush() +{ + if (_afxHalftoneBrush == NULL) + { + WORD grayPattern[8]; + for (int i = 0; i < 8; i++) + grayPattern[i] = (WORD)(0x5555 << (i & 1)); + HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern); + if (grayBitmap != NULL) + { + _afxHalftoneBrush = CreatePatternBrush(grayBitmap); + DeleteObject(grayBitmap); + } + } + return _afxHalftoneBrush; +} + + + +void DrawDragRect( + HDC hDC,LPRECT lpRect,SIZE size, + LPRECT lpRectLast,SIZE sizeLast, + HBRUSH hBrush = NULL,HBRUSH hBrushLast = NULL) +{ + // first, determine the update region and select it + HRGN rgnNew; + HRGN rgnOutside,rgnInside; + rgnOutside = CreateRectRgnIndirect(lpRect); + RECT rect = *lpRect; + InflateRect(&rect,-size.cx, -size.cy); + IntersectRect(&rect,&rect,lpRect); + rgnInside = CreateRectRgnIndirect(&rect); + rgnNew = CreateRectRgn(0, 0, 0, 0); + CombineRgn(rgnNew,rgnOutside,rgnInside,RGN_XOR); + + HBRUSH hBrushOld = NULL; + if (hBrush == NULL) + hBrush = HalftoneBrush(); + if (hBrushLast == NULL) + hBrushLast = hBrush; + + HRGN rgnLast(NULL); + HRGN rgnUpdate(NULL); + if (lpRectLast != NULL) + { + // find difference between new region and old region + rgnLast = CreateRectRgn(0, 0, 0, 0); + SetRectRgn( + rgnOutside, + lpRectLast->left, + lpRectLast->top, + lpRectLast->right, + lpRectLast->bottom); + rect = *lpRectLast; + InflateRect(&rect,-sizeLast.cx, -sizeLast.cy); + IntersectRect(&rect,&rect, lpRectLast); + SetRectRgn(rgnInside,rect.left,rect.top,rect.right,rect.bottom); + CombineRgn(rgnLast,rgnOutside,rgnInside, RGN_XOR); + +// // only diff them if brushes are the same + if (hBrush == hBrushLast) + { + rgnUpdate = CreateRectRgn(0, 0, 0, 0); + CombineRgn(rgnUpdate,rgnLast,rgnNew, RGN_XOR); + } + } + if (hBrush != hBrushLast && lpRectLast != NULL) + { + // brushes are different -- erase old region first + SelectClipRgn(hDC,rgnLast); + GetClipBox(hDC,&rect); + hBrushOld = (HBRUSH)SelectObject(hDC,(HGDIOBJ)hBrushLast); + PatBlt(hDC,rect.left,rect.top,(rect.right-rect.left),(rect.bottom-rect.top),PATINVERT); + + SelectObject(hDC,(HGDIOBJ)hBrushOld); + hBrushOld = NULL; + } + + // draw into the update/new region + SelectClipRgn(hDC,rgnUpdate); + + GetClipBox(hDC,&rect); + hBrushOld = (HBRUSH) SelectObject(hDC,(HGDIOBJ) hBrush); + PatBlt(hDC,rect.left, rect.top,(rect.right-rect.left),(rect.bottom-rect.top), PATINVERT); + + // cleanup DC + if (hBrushOld != NULL) + SelectObject(hDC,(HGDIOBJ)hBrushOld); + SelectClipRgn(hDC,NULL); +} + + +void winwrap::TransformRect(LPRECT rect,HWND pWnd,HWND pWndClipTo) +{ + POINT pt; + pt.x = rect->left;pt.y = rect->top; + ClientToScreen(pWnd,&pt); + ScreenToClient(pWndClipTo,&pt); + rect->left = pt.x; rect->top = pt.y; + + pt.x = rect->right;pt.y = rect->bottom; + ClientToScreen(pWnd,&pt); + ScreenToClient(pWndClipTo,&pt); + rect->right = pt.x; rect->bottom = pt.y; +} + + +void NormalizeRect(LPRECT rp) +{ + if(rp->left > rp->right) { + UINT tmp = rp->left; + rp->left = rp->right; + rp->right = tmp; + } + + if(rp->top > rp->bottom) { + UINT tmp = rp->top; + rp->top = rp->bottom; + rp->bottom = tmp; + } +} + + +using namespace winwrap; + + +Tracker::Tracker() +{ +} + + +Tracker::Tracker(LPCRECT lpSrcRect, UINT nStyle) +{ + Construct(); + CopyRect(&m_rect,lpSrcRect); + m_nStyle = nStyle; +} + +HBRUSH _afxHatchBrush = 0; +HPEN _afxBlackDottedPen = 0; +int _afxHandleSize = 0; + + +void Tracker::Construct() +{ + static BOOL bInitialized = false; + if (!bInitialized) + { + if (_afxHatchBrush == NULL) + { + // create the hatch pattern + bitmap + WORD hatchPattern[8]; + WORD wPattern = 0x1111; + for (int i = 0; i < 4; i++) + { + hatchPattern[i] = wPattern; + hatchPattern[i+4] = wPattern; + wPattern <<= 1; + } + HBITMAP hatchBitmap = CreateBitmap(8, 8, 1, 1,&hatchPattern); + + // create black hatched brush + _afxHatchBrush = CreatePatternBrush(hatchBitmap); + DeleteObject(hatchBitmap); + } + + if (_afxBlackDottedPen == NULL) + { + // create black dotted pen + _afxBlackDottedPen = CreatePen(PS_DOT, 0, RGB(0, 0, 0)); + } + + // get default handle size from Windows profile setting + static const TCHAR szWindows[] = TEXT("windows"); + static const TCHAR szInplaceBorderWidth[] = + TEXT("oleinplaceborderwidth"); + _afxHandleSize = GetProfileInt(szWindows, szInplaceBorderWidth, 4); + bInitialized = TRUE; + + _afxCursors[0] = _afxCursors[2] = LoadCursor(0,IDC_SIZENWSE); + _afxCursors[4] = _afxCursors[6] = LoadCursor(0,IDC_SIZENS); + _afxCursors[1] = _afxCursors[3] = LoadCursor(0,IDC_SIZENESW); + _afxCursors[5] = _afxCursors[7] = LoadCursor(0,IDC_SIZEWE); + _afxCursors[8] = LoadCursor(0,IDC_SIZEALL); + } + + m_nStyle = 0; + m_nHandleSize = _afxHandleSize; + m_sizeMin.cy = m_sizeMin.cx = m_nHandleSize*2; + + SetRectEmpty(&m_rectLast); + m_sizeLast.cx = m_sizeLast.cy = 0; + m_bErase = FALSE; + m_bFinalErase = FALSE; +} + +Tracker::~Tracker() +{ +} + + +int Tracker::HitTest(POINT point) const +{ + TrackerHit hitResult = hitNothing; + + RECT rectTrue; + GetTrueRect(&rectTrue); + NormalizeRect(&rectTrue); + if (PtInRect(&rectTrue,point)) + { + if ((m_nStyle & (resizeInside|resizeOutside)) != 0) + hitResult = (TrackerHit)HitTestHandles(point); + else + hitResult = hitMiddle; + } + return hitResult; +} + + +BOOL Tracker::SetCursor(HWND pWnd, UINT nHitTest) const +{ + // trackers should only be in client area + if (nHitTest != HTCLIENT) + return FALSE; + + // convert cursor position to client co-ordinates + POINT point; + GetCursorPos(&point); + ScreenToClient(pWnd,&point); + + // do hittest and normalize hit + int nHandle = HitTestHandles(point); + if (nHandle < 0) + return FALSE; + + // need to normalize the hittest such that we get proper cursors + nHandle = NormalizeHit(nHandle); + + // handle special case of hitting area between handles + // (logically the same -- handled as a move -- but different cursor) + if (nHandle == hitMiddle && !PtInRect(&m_rect,point)) + { + // only for trackers with hatchedBorder (ie. in-place resizing) + if (m_nStyle & hatchedBorder) + nHandle = (TrackerHit)9; + } + + ::SetCursor(_afxCursors[nHandle]); + return TRUE; +} + + + +BOOL Tracker::Track(HWND hWnd,POINT point,BOOL bAllowInvert, + HWND hWndClipTo) +{ + // perform hit testing on the handles + int nHandle = HitTestHandles(point); + if (nHandle < 0) + { + // didn't hit a handle, so just return FALSE + return FALSE; + } + + // otherwise, call helper function to do the tracking + m_bAllowInvert = bAllowInvert; + SetCursor(hWnd,nHandle); + return TrackHandle(nHandle, hWnd, point, hWndClipTo); +} + + +BOOL Tracker::TrackHandle(int nHandle,HWND hWnd,POINT point,HWND hWndClipTo) +{ + // don't handle if capture already set + if (GetCapture() != NULL) + return FALSE; + + // save original width & height in pixels + int nWidth = m_rect.right - m_rect.left; + int nHeight = m_rect.bottom - m_rect.top; + + // set capture to the window which received this message + SetCapture(hWnd); + UpdateWindow(hWnd); + if (hWndClipTo != NULL) + UpdateWindow(hWndClipTo); + RECT rectSave = m_rect; + + // find out what x/y coords we are supposed to modify + int *px, *py; + int xDiff, yDiff; + GetModifyPointers(nHandle, &px, &py, &xDiff, &yDiff); + xDiff = point.x - xDiff; + yDiff = point.y - yDiff; + + // get DC for drawing + HDC hDrawDC; + if (hWndClipTo != NULL) + { + // clip to arbitrary window by using adjusted Window DC + hDrawDC = GetDCEx(hWndClipTo,NULL, DCX_CACHE); + } + else + { + // otherwise, just use normal DC + hDrawDC = GetDC(hWnd); + } + + RECT rectOld; + BOOL bMoved = FALSE; + + // get messages until capture lost or cancelled/accepted + for (;;) + { + MSG msg; + GetMessage(&msg, NULL, 0, 0); + + if (GetCapture() != hWnd) + break; + + switch (msg.message) + { + // handle movement/accept messages + case WM_LBUTTONUP: + case WM_MOUSEMOVE: + rectOld = m_rect; + // handle resize cases (and part of move) + if (px != NULL) + *px = (int)(short)LOWORD(msg.lParam) - xDiff; + if (py != NULL) + *py = (int)(short)HIWORD(msg.lParam) - yDiff; + + // handle move case + if (nHandle == hitMiddle) + { + m_rect.right = m_rect.left + nWidth; + m_rect.bottom = m_rect.top + nHeight; + } + // allow caller to adjust the rectangle if necessary + AdjustRect(nHandle,&m_rect); + + // only redraw and callback if the rect actually changed! + m_bFinalErase = (msg.message == WM_LBUTTONUP); + if (!EqualRect(&rectOld,&m_rect) || m_bFinalErase) + { + if (bMoved) + { + m_bErase = TRUE; + DrawTrackerRect(&rectOld,hWndClipTo,hDrawDC,hWnd); + } + OnChangedRect(rectOld); + if (msg.message != WM_LBUTTONUP) + bMoved = TRUE; + } + if (m_bFinalErase) + goto ExitLoop; + + if (!EqualRect(&rectOld,&m_rect)) + { + m_bErase = FALSE; + DrawTrackerRect(&m_rect,hWndClipTo,hDrawDC,hWnd); + } + break; + + // handle cancel messages + case WM_KEYDOWN: + if (msg.wParam != VK_ESCAPE) + break; + case WM_RBUTTONDOWN: + if (bMoved) + { + m_bErase = m_bFinalErase = TRUE; + DrawTrackerRect(&m_rect, hWndClipTo, hDrawDC, hWnd); + } + m_rect = rectSave; + goto ExitLoop; + + // just dispatch rest of the messages + default: + DispatchMessage(&msg); + break; + } + } + + ExitLoop: + if (hWndClipTo != NULL) + ReleaseDC(hWndClipTo,hDrawDC); + else + ReleaseDC(hWnd,hDrawDC); + ReleaseCapture(); + + // restore rect in case bMoved is still FALSE + if (!bMoved) + m_rect = rectSave; + m_bFinalErase = FALSE; + m_bErase = FALSE; + + // return TRUE only if rect has changed + return !EqualRect(&rectSave,&m_rect); +} + + +void Tracker::OnChangedRect(const RECT& /*rectOld*/) +{ +} + + +void Tracker::AdjustRect(int nHandle, LPRECT) +{ + if(nHandle == hitMiddle) + return; + + // convert the handle into locations within m_rect + int *px, *py; + GetModifyPointers(nHandle, &px, &py, NULL, NULL); + + // enforce minimum width + int nNewWidth = m_rect.right - m_rect.left; + int nAbsWidth = m_bAllowInvert ? abs(nNewWidth) : nNewWidth; + if (px != NULL && nAbsWidth < m_sizeMin.cx) + { + nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1; + const AFX_RECTINFO* pRectInfo = + &_afxRectInfo[(int*)px - (int*)&m_rect]; + *px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) + + nNewWidth * m_sizeMin.cx * -pRectInfo->nSignAcross; + } + + // enforce minimum height + int nNewHeight = m_rect.bottom - m_rect.top; + int nAbsHeight = m_bAllowInvert ? abs(nNewHeight) : nNewHeight; + if (py != NULL && nAbsHeight < m_sizeMin.cy) + { + nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1; + const AFX_RECTINFO* pRectInfo = + &_afxRectInfo[(int*)py - (int*)&m_rect]; + *py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) + + nNewHeight * m_sizeMin.cy * -pRectInfo->nSignAcross; + } +} + + +void Tracker::DrawTrackerRect( + LPRECT lpRect,HWND pWndClipTo,HDC pDC,HWND pWnd) +{ + // first, normalize the rectangle for drawing + RECT rect = *lpRect; + NormalizeRect(&rect); + + // convert to client coordinates + if (pWndClipTo != NULL) + TransformRect(&rect,pWnd,pWndClipTo); + + SIZE size; + size.cx = 0; size.cy = 0; + if (!m_bFinalErase) + { + // otherwise, size depends on the style + if (m_nStyle & hatchedBorder) + { + size.cx = size.cy = max(1,GetHandleSize(&rect)-1); + InflateRect(&rect,size.cx,size.cy); + } + else + { + size.cx = 1; // CX_BORDER; + size.cy = 1; // CY_BORDER; + } + } + + // and draw it + if (m_bFinalErase || !m_bErase) + DrawDragRect(pDC,&rect,size,&m_rectLast,m_sizeLast); + + // remember last rectangles + m_rectLast = rect; + m_sizeLast = size; +} + + +void Tracker::Draw(HDC hDC) const +{ + // set initial DC state + SetMapMode(hDC,MM_TEXT); + SetViewportOrgEx(hDC,0, 0,NULL); + SetWindowOrgEx(hDC,0, 0,NULL); + + // get normalized rectangle + RECT rect = m_rect; + NormalizeRect(&rect); + + HPEN pOldPen = NULL; + HBRUSH pOldBrush = NULL; + HGDIOBJ pTemp; + int nOldROP; + + // draw lines + if ((m_nStyle & (dottedLine|solidLine)) != 0) + { + if (m_nStyle & dottedLine) + pOldPen = (HPEN)SelectObject(hDC,_afxBlackDottedPen); + else + pOldPen = (HPEN)SelectObject(hDC,(HGDIOBJ)BLACK_PEN); + pOldBrush = (HBRUSH)SelectObject(hDC,(HGDIOBJ)NULL_BRUSH); + nOldROP = SetROP2(hDC,R2_COPYPEN); + InflateRect(&rect,+1, +1); // borders are one pixel outside + Rectangle(hDC,rect.left, rect.top, rect.right, rect.bottom); + SetROP2(hDC,nOldROP); + } + + // if hatchBrush is going to be used, need to unrealize it + if ((m_nStyle & (hatchInside|hatchedBorder)) != 0) + UnrealizeObject((HGDIOBJ)_afxHatchBrush); + + // hatch inside + if ((m_nStyle & hatchInside) != 0) + { + pTemp = SelectObject(hDC,(HGDIOBJ)NULL_PEN); + if (pOldPen == NULL) + pOldPen = (HPEN)pTemp; + pTemp = SelectObject(hDC,(HGDIOBJ)_afxHatchBrush); + if (pOldBrush == NULL) + pOldBrush = (HBRUSH)pTemp; + SetBkMode(hDC,TRANSPARENT); + nOldROP = SetROP2(hDC,R2_MASKNOTPEN); + Rectangle(hDC,rect.left+1, rect.top+1, rect.right, rect.bottom); + SetROP2(hDC,nOldROP); + } + + // draw hatched border + if ((m_nStyle & hatchedBorder) != 0) + { + pTemp = SelectObject(hDC,(HGDIOBJ)_afxHatchBrush); + if (pOldBrush == NULL) + pOldBrush = (HBRUSH)pTemp; + SetBkMode(hDC,OPAQUE); + RECT rectTrue; + GetTrueRect(&rectTrue); + PatBlt(hDC,rectTrue.left, rectTrue.top, rectTrue.right-rectTrue.left, + rect.top-rectTrue.top, 0x000F0001 /* Pn */); + PatBlt(hDC,rectTrue.left, rect.bottom, + rectTrue.right-rectTrue.left, + rectTrue.bottom-rect.bottom, 0x000F0001 /* Pn */); + PatBlt(hDC,rectTrue.left, rect.top, rect.left-rectTrue.left, + rect.bottom-rect.top, 0x000F0001 /* Pn */); + PatBlt(hDC,rect.right, rect.top, rectTrue.right-rect.right, + rect.bottom-rect.top, 0x000F0001 /* Pn */); + } + + // draw resize handles + if ((m_nStyle & (resizeInside|resizeOutside)) != 0) + { + UINT mask = GetHandleMask(); + HBRUSH hbrush = CreateSolidBrush(RGB(0,0,0)); + for (int i = 0; i < 8; ++i) + { + if (mask & (1<<i)) + { + GetHandleRect((TrackerHit)i, &rect); + // FillSolidRect(hDC,rect, RGB(0, 0, 0)); + FillRect(hDC,&rect,hbrush); + } + } + DeleteObject(hbrush); + } + + // cleanup pDC state + if (pOldPen != NULL) + SelectObject(hDC,pOldPen); + if (pOldBrush != NULL) + SelectObject(hDC,pOldBrush); + RestoreDC(hDC,-1); +} + + +void Tracker::GetHandleRect(int nHandle,RECT* pHandleRect) const +{ + // get normalized rectangle of the tracker + RECT rectT = m_rect; + NormalizeRect(&rectT); + if ((m_nStyle & (solidLine|dottedLine)) != 0) + InflateRect(&rectT,+1, +1); + + // since the rectangle itself was normalized, we also have to invert the + // resize handles. + nHandle = NormalizeHit(nHandle); + + // handle case of resize handles outside the tracker + int size = GetHandleSize(); + if (m_nStyle & resizeOutside) + InflateRect(&rectT,size-1, size-1); + + // calculate position of the resize handle + int nWidth = rectT.right - rectT.left; + int nHeight = rectT.bottom - rectT.top; + RECT rect; + const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle]; + rect.left = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetX); + rect.top = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetY); + rect.left += size * pHandleInfo->nHandleX; + rect.top += size * pHandleInfo->nHandleY; + rect.left += pHandleInfo->nCenterX * (nWidth - size) / 2; + rect.top += pHandleInfo->nCenterY * (nHeight - size) / 2; + rect.right = rect.left + size; + rect.bottom = rect.top + size; + + *pHandleRect = rect; +} + + +int Tracker::GetHandleSize(LPRECT lpRect) const +{ + if (lpRect == NULL) + lpRect = (LPRECT)&m_rect; + + int size = m_nHandleSize; + if (!(m_nStyle & resizeOutside)) + { + // make sure size is small enough for the size of the rect + int sizeMax = min(abs(lpRect->right - lpRect->left), + abs(lpRect->bottom - lpRect->top)); + if (size * 2 > sizeMax) + size = sizeMax / 2; + } + return size; +} + + +UINT Tracker::GetHandleMask() const +{ + UINT mask = 0x0F; // always have 4 corner handles + int size = m_nHandleSize*3; + if (abs(m_rect.right - m_rect.left) - size > 4) + mask |= 0x50; + if (abs(m_rect.bottom - m_rect.top) - size > 4) + mask |= 0xA0; + return mask; +} + + +void Tracker::GetTrueRect(LPRECT lpTrueRect) const +{ + RECT rect = m_rect; + NormalizeRect(&rect); + int nInflateBy = 0; + if ((m_nStyle & (resizeOutside|hatchedBorder)) != 0) + nInflateBy += GetHandleSize() - 1; + if ((m_nStyle & (solidLine|dottedLine)) != 0) + ++nInflateBy; + InflateRect(&rect,nInflateBy, nInflateBy); + *lpTrueRect = rect; +} + + +int Tracker::NormalizeHit(int nHandle) const +{ + if (nHandle == hitMiddle || nHandle == hitNothing) + return nHandle; + const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle]; + if (m_rect.right - m_rect.left < 0) + { + nHandle = (TrackerHit)pHandleInfo->nInvertX; + pHandleInfo = &_afxHandleInfo[nHandle]; + } + if (m_rect.bottom - m_rect.top < 0) + nHandle = (TrackerHit)pHandleInfo->nInvertY; + return nHandle; +} + + +int Tracker::HitTestHandles(POINT point) const +{ + RECT rect; + UINT mask = GetHandleMask(); + + // see if hit anywhere inside the tracker + GetTrueRect(&rect); + if (!PtInRect(&rect,point)) + return hitNothing; // totally missed + + // see if we hit a handle + for (int i = 0; i < 8; ++i) + { + if (mask & (1<<i)) + { + GetHandleRect((TrackerHit)i, &rect); + if (PtInRect(&rect,point)) + return (TrackerHit)i; + } + } + + // last of all, check for non-hit outside of object, between resize handles + if ((m_nStyle & hatchedBorder) == 0) + { + RECT rect = m_rect; + NormalizeRect(&rect); + if ((m_nStyle & dottedLine|solidLine) != 0) + InflateRect(&rect,+1, +1); + if (!PtInRect(&rect,point)) + return hitNothing; // must have been between resize handles + } + return hitMiddle; // no handle hit, but hit object (or object border) +} + + + +void Tracker::GetModifyPointers( + int nHandle, int** ppx, int** ppy, int* px, int* py) +{ + if (nHandle == hitMiddle) + nHandle = hitTopLeft; // same as hitting top-left + + *ppx = NULL; + *ppy = NULL; + + // fill in the part of the rect that this handle modifies + // (Note: handles that map to themselves along a given axis when that + // axis is inverted don't modify the value on that axis) + + const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle]; + if (pHandleInfo->nInvertX != nHandle) + { + *ppx = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetX); + if (px != NULL) + *px = **ppx; + } + else + { + // middle handle on X axis + if (px != NULL) + *px = m_rect.left + (m_rect.left-m_rect.right) / 2; + } + if (pHandleInfo->nInvertY != nHandle) + { + *ppy = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetY); + if (py != NULL) + *py = **ppy; + } + else + { + // middle handle on Y axis + if (py != NULL) + *py = m_rect.top + (m_rect.top-m_rect.bottom) / 2; + } +} + +// Fix strange warnings about some +// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. +// warning C4505: 'xxx' : unreferenced local function has been removed +#if defined(_MSC_VER) +#pragma warning(disable: 4505) +#endif diff --git a/embedserv/source/embed/xwin.cxx b/embedserv/source/embed/xwin.cxx new file mode 100644 index 000000000000..37306e69fc3e --- /dev/null +++ b/embedserv/source/embed/xwin.cxx @@ -0,0 +1,349 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xwin.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "xwin.hxx" +#include <com/sun/star/lang/SystemDependent.hpp> + + +using namespace ::com::sun::star; + + +ContainerWindowWrapper::ContainerWindowWrapper(HWND aHwnd) + : m_aHwnd(aHwnd), + m_pDisposeEventListeners(0) +{ +} + +ContainerWindowWrapper::~ContainerWindowWrapper() +{ + delete m_pDisposeEventListeners; +} + + +void SAL_CALL +ContainerWindowWrapper::dispose( +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + cppu::OInterfaceContainerHelper *pDisposeEventListeners(0); + + { + osl::MutexGuard aGuard(m_aMutex); + pDisposeEventListeners = m_pDisposeEventListeners; + } + + if(pDisposeEventListeners) { + lang::EventObject aEvt; + aEvt.Source = static_cast< awt::XWindow* >(this); + + pDisposeEventListeners->disposeAndClear(aEvt); + } +} + + +void SAL_CALL +ContainerWindowWrapper::addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& Listener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + cppu::OInterfaceContainerHelper *pDisposeEventListeners(0); + { + osl::MutexGuard aGuard(m_aMutex); + pDisposeEventListeners = m_pDisposeEventListeners; + } + + if(! pDisposeEventListeners) + { + osl::MutexGuard aGuard(m_aMutex); + pDisposeEventListeners = m_pDisposeEventListeners = + new cppu::OInterfaceContainerHelper(m_aMutex); + } + + pDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +ContainerWindowWrapper::removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& Listener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + cppu::OInterfaceContainerHelper *pDisposeEventListeners(0); + { + osl::MutexGuard aGuard(m_aMutex); + pDisposeEventListeners = m_pDisposeEventListeners; + } + if( pDisposeEventListeners ) + pDisposeEventListeners->removeInterface( Listener ); +} + + + +// XSystemDependentWindowPeer + +::com::sun::star::uno::Any SAL_CALL +ContainerWindowWrapper::getWindowHandle( + const ::com::sun::star::uno::Sequence< sal_Int8 >& ProcessId, + sal_Int16 SystemType +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + if(SystemType == lang::SystemDependent::SYSTEM_WIN32 || + SystemType == lang::SystemDependent::SYSTEM_WIN16) + { + uno::Any aAny; + sal_Int32 nHwnd = sal_Int32(m_aHwnd); + aAny <<= nHwnd; + return aAny; + } + else + return uno::Any(); +} + + + +void SAL_CALL +ContainerWindowWrapper::setPosSize( + sal_Int32 X, + sal_Int32 Y, + sal_Int32 Width, + sal_Int32 Height, + sal_Int16 Flags +) + throw ( + ::com::sun::star::uno::RuntimeException) +{ + +} + +::com::sun::star::awt::Rectangle SAL_CALL +ContainerWindowWrapper::getPosSize( +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + return awt::Rectangle(); +} + + +void SAL_CALL +ContainerWindowWrapper::setVisible( + sal_Bool Visible +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + + +void SAL_CALL +ContainerWindowWrapper::setEnable( + sal_Bool Enable +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::setFocus( +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::addWindowListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XWindowListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::removeWindowListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XWindowListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + + +void SAL_CALL +ContainerWindowWrapper::addFocusListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XFocusListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + + +void SAL_CALL +ContainerWindowWrapper::removeFocusListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XFocusListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::addKeyListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XKeyListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::removeKeyListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XKeyListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + + +void SAL_CALL +ContainerWindowWrapper::addMouseListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + + +void SAL_CALL +ContainerWindowWrapper::removeMouseListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + + +void SAL_CALL +ContainerWindowWrapper::addMouseMotionListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseMotionListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::removeMouseMotionListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseMotionListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::addPaintListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XPaintListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} + +void SAL_CALL +ContainerWindowWrapper::removePaintListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XPaintListener >& xListener +) + throw ( + ::com::sun::star::uno::RuntimeException + ) +{ + +} diff --git a/embedserv/source/inc/common.h b/embedserv/source/inc/common.h new file mode 100755 index 000000000000..a2d5707b8e3f --- /dev/null +++ b/embedserv/source/inc/common.h @@ -0,0 +1,59 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: common.h,v $ + * $Revision: 1.6.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include "stdafx.h" +#include <initguid.h> + +#include <rtl/ustring.hxx> +#include <osl/interlck.h> +#include <comphelper/classids.hxx> + +#include "embservconst.h" + +namespace com { namespace sun { namespace star { + namespace lang { + class XMultiServiceFactory; + } + namespace frame { + class XModel; + } + namespace beans { + struct PropertyValue; + } + namespace io { + class XInputStream; + class XOutputStream; + } +} } } + +#endif diff --git a/embedserv/source/inc/docholder.hxx b/embedserv/source/inc/docholder.hxx new file mode 100644 index 000000000000..83aad107502a --- /dev/null +++ b/embedserv/source/inc/docholder.hxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: docholder.hxx,v $ + * $Revision: 1.21.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DOCHOLDER_HXX_ +#define _DOCHOLDER_HXX_ + +#include "common.h" +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/util/XCloseListener.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/util/XModifyListener.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp> +#include <cppuhelper/implbase4.hxx> + +#include <rtl/ref.hxx> + +#include "embeddocaccess.hxx" + +class EmbedDocument_Impl; +class Interceptor; +class CIIAObj; + +namespace winwrap { + class CHatchWin; +} + + +class DocumentHolder : + public ::cppu::WeakImplHelper4< + ::com::sun::star::util::XCloseListener, + ::com::sun::star::frame::XTerminateListener, + ::com::sun::star::util::XModifyListener, + ::com::sun::star::ui::XDockingAreaAcceptor> +{ +private: + ::osl::Mutex m_aMutex; + + BOOL m_bAllowInPlace; + LPOLEINPLACESITE m_pIOleIPSite; + LPOLEINPLACEFRAME m_pIOleIPFrame; + LPOLEINPLACEUIWINDOW m_pIOleIPUIWindow; + winwrap::CHatchWin* m_pCHatchWin; + + ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > m_xOleAccess; + + ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XDispatchProviderInterceptor > m_xInterceptorLocker; + Interceptor* m_pInterceptor; + + ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + + RECT m_aBorder; + + // contains top level system window data + bool m_bOnDeactivate; + HWND m_hWndxWinParent; + HWND m_hWndxWinCont; + HMENU m_nMenuHandle; + HMENU m_nMenuShared; + HOLEMENU m_nOLEMenu; + com::sun::star::uno::Reference< + com::sun::star::awt::XWindow> m_xEditWindow; + + com::sun::star::uno::Reference< + com::sun::star::awt::XWindow> m_xContainerWindow; + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > m_xDocument; + sal_Int16 m_nMacroExecMode; + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XLayoutManager> m_xLayoutManager; + + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XFrame > m_xFrame; + + ::rtl::OUString m_aContainerName,m_aDocumentNamePart,m_aFilterName; + + CComPtr< IDispatch > m_pIDispatch; + + sal_Bool m_bLink; + + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XFrame > DocumentFrame(); + + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > + CreateNewInterceptor(); + + void ClearInterceptorInternally(); + + void LoadDocInFrame( sal_Bool bPluginMode ); +public: + + + // the instance to which we belong + static HINSTANCE m_hInstance; + + HWND GetEditWindowParentHandle() const + { + return m_hWndxWinParent; + } + + void SetContainerWindowHandle(HWND hWndxWinCont) + { + m_hWndxWinCont = hWndxWinCont; + } + + DocumentHolder( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory >& xFactory, + const ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl >& xOleAccess ); + + ~DocumentHolder(); + + // Methods for inplace activation + + + BOOL isActive() const; + void DisableInplaceActivation(BOOL); + HRESULT InPlaceActivate(LPOLECLIENTSITE,BOOL); + void InPlaceDeactivate(void); + HRESULT UIActivate(); + void UIDeactivate(); + BOOL InPlaceMenuCreate(void); + BOOL InPlaceMenuDestroy(void); + + void OpenIntoWindow(void); + BOOL Undo(void); + + // further methods + + void SetDocument( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel >& xDoc, + sal_Bool bLink = sal_False + ); + + sal_Bool ExecuteSuspendCloseFrame(); + + void DisconnectFrameDocument( sal_Bool bComplete = sal_False ); + void CloseDocument(); + void CloseFrame(); + void ClearInterceptor(); + void FreeOffice(); + + void resizeWin( const SIZEL& rNewSize ); + + void setTitle(const rtl::OUString& aDocumentName); + rtl::OUString getTitle() const { return m_aDocumentNamePart; } + + void setContainerName(const rtl::OUString& aContainerName); + rtl::OUString getContainerName() const { return m_aContainerName; } + void OnPosRectChanged(LPRECT lpRect) const; + void show(); + + sal_Bool HasFrame() { return m_xFrame.is(); } + sal_Bool IsLink() { return m_bLink; } + + /** hides the document window, even in case of an external container + * side managed window. + */ + + void hide(); + + IDispatch* GetIDispatch(); + + HRESULT GetDocumentBorder( RECT *pRect ); + // HRESULT SetVisArea( const RECTL *pRect ); + // HRESULT GetVisArea( RECTL *pRect ); + HRESULT SetExtent( const SIZEL *pSize ); + HRESULT GetExtent( SIZEL *pSize ); + // sets extension on the hatchwindow + HRESULT SetContRects(LPCRECT pRect); + HRESULT SetObjectRects(LPCRECT aRect, LPCRECT aClip); + + HWND GetTopMostWinHandle() const + { + return m_hWndxWinParent; + } + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > + GetDocument() const + { + return m_xDocument; + } + + // XEventListener + virtual void SAL_CALL + disposing( const com::sun::star::lang::EventObject& aSource ) + throw( ::com::sun::star::uno::RuntimeException ); + + // XCloseListener + virtual void SAL_CALL + queryClosing( + const com::sun::star::lang::EventObject& aSource, + sal_Bool bGetsOwnership + ) + throw( + ::com::sun::star::util::CloseVetoException + ); + + virtual void SAL_CALL + notifyClosing( + const com::sun::star::lang::EventObject& aSource + ) + throw( ::com::sun::star::uno::RuntimeException ); + + // XTerminateListener + virtual void SAL_CALL + queryTermination( + const com::sun::star::lang::EventObject& aSource + ) + throw( + ::com::sun::star::frame::TerminationVetoException + ); + + virtual void SAL_CALL + notifyTermination( + const com::sun::star::lang::EventObject& aSource + ) + throw( ::com::sun::star::uno::RuntimeException ); + + + // XModifyListener + virtual void SAL_CALL + modified( + const ::com::sun::star::lang::EventObject& aEvent + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + // XDockingAreaAcceptor + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XWindow> SAL_CALL + getContainerWindow( + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual sal_Bool SAL_CALL + requestDockingAreaSpace( + const ::com::sun::star::awt::Rectangle& RequestedSpace + ) + throw( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + setDockingAreaSpace( + const ::com::sun::star::awt::Rectangle& BorderSpace + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); +}; + +#endif + diff --git a/embedserv/source/inc/embeddoc.hxx b/embedserv/source/inc/embeddoc.hxx new file mode 100755 index 000000000000..b6998aef8e1e --- /dev/null +++ b/embedserv/source/inc/embeddoc.hxx @@ -0,0 +1,213 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: embeddoc.hxx,v $ + * $Revision: 1.18.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _EMBEDDOC_HXX_ +#define _EMBEDDOC_HXX_ +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +#undef _DEBUG +#endif +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "common.h" +#include <oleidl.h> +#include <objidl.h> + +#include <hash_map> +#include <com/sun/star/uno/Reference.h> +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_ +#include <com/sun/star/uno/SEQUENCE.h> +#endif + +#include "embeddocaccess.hxx" +#include "docholder.hxx" + +typedef ::std::hash_map< DWORD, IAdviseSink* > AdviseSinkHashMap; +typedef ::std::hash_map< DWORD, IAdviseSink* >::iterator AdviseSinkHashMapIterator; + +class GDIMetaFile; +class CIIAObj; + +class EmbedDocument_Impl + : public IPersistStorage, + public IDataObject, + public IOleObject, + public IOleInPlaceObject, + public IPersistFile, + public IDispatch, + public IExternalConnection +{ +protected: + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > + fillArgsForLoading_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream, + DWORD nStreamMode, + LPCOLESTR pFilePath = NULL ); + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > + fillArgsForStoring_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xStream ); + + HRESULT SaveTo_Impl( IStorage* pStg ); + + sal_uInt64 getMetaFileHandle_Impl( sal_Bool isEnhMeta ); + +public: + EmbedDocument_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& smgr, + const GUID* guid ); + virtual ~EmbedDocument_Impl(); + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + /* IPersistMethod */ + STDMETHOD(GetClassID)(CLSID *pClassID); + + /* IPersistStorage methods */ + STDMETHOD(IsDirty) (); + STDMETHOD(InitNew) ( IStorage *pStg ); + STDMETHOD(Load) ( IStorage* pStr ); + STDMETHOD(Save) ( IStorage *pStgSave, BOOL fSameAsLoad ); + STDMETHOD(SaveCompleted) ( IStorage *pStgNew ); + STDMETHOD(HandsOffStorage) (void); + + /* IDataObject methods */ + STDMETHOD(GetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium ); + STDMETHOD(GetDataHere) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium ); + STDMETHOD(QueryGetData) ( FORMATETC * pFormatetc ); + STDMETHOD(GetCanonicalFormatEtc) ( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ); + STDMETHOD(SetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease ); + STDMETHOD(EnumFormatEtc) ( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc ); + STDMETHOD(DAdvise) ( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ); + STDMETHOD(DUnadvise) ( DWORD dwConnection ); + STDMETHOD(EnumDAdvise) ( IEnumSTATDATA ** ppenumAdvise ); + + /* IOleObject methods */ + STDMETHOD(SetClientSite) ( IOleClientSite* pSite ); + STDMETHOD(GetClientSite) ( IOleClientSite** pSite ); + STDMETHOD(SetHostNames) ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj ); + STDMETHOD(Close) ( DWORD dwSaveOption); + STDMETHOD(SetMoniker) ( DWORD dwWhichMoniker, IMoniker *pmk ); + STDMETHOD(GetMoniker) ( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk ); + STDMETHOD(InitFromData) ( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved ); + STDMETHOD(GetClipboardData) ( DWORD dwReserved, IDataObject **ppDataObject ); + STDMETHOD(DoVerb) ( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect ); + STDMETHOD(EnumVerbs) ( IEnumOLEVERB **ppEnumOleVerb ); + STDMETHOD(Update) (); + STDMETHOD(IsUpToDate) (); + STDMETHOD(GetUserClassID) ( CLSID *pClsid ); + STDMETHOD(GetUserType) ( DWORD dwFormOfType, LPOLESTR *pszUserType ); + STDMETHOD(SetExtent) ( DWORD dwDrawAspect, SIZEL *psizel ); + STDMETHOD(GetExtent) ( DWORD dwDrawAspect, SIZEL *psizel ); + STDMETHOD(Advise) ( IAdviseSink *pAdvSink, DWORD *pdwConnection ); + STDMETHOD(Unadvise) ( DWORD dwConnection ); + STDMETHOD(EnumAdvise) ( IEnumSTATDATA **ppenumAdvise ); + STDMETHOD(GetMiscStatus) ( DWORD dwAspect, DWORD *pdwStatus ); + STDMETHOD(SetColorScheme) ( LOGPALETTE *pLogpal ); + + /* IOleInPlaceObject methods */ + STDMETHOD(GetWindow)(HWND *); + STDMETHOD(ContextSensitiveHelp)(BOOL); + STDMETHOD(InPlaceDeactivate)(); + STDMETHOD(UIDeactivate)(); + STDMETHOD(SetObjectRects)(LPCRECT, LPCRECT); + STDMETHOD(ReactivateAndUndo)(); + + /* IPersistFile methods */ + STDMETHOD(Load) ( LPCOLESTR pszFileName, DWORD dwMode ); + STDMETHOD(Save) ( LPCOLESTR pszFileName, BOOL fRemember ); + STDMETHOD(SaveCompleted) ( LPCOLESTR pszFileName ); + STDMETHOD(GetCurFile) ( LPOLESTR *ppszFileName ); + + /* IDispatch methods */ + STDMETHOD(GetTypeInfoCount) ( unsigned int FAR* pctinfo ); + STDMETHOD(GetTypeInfo) ( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo ); + STDMETHOD(GetIDsOfNames) ( REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId ); + STDMETHOD(Invoke) ( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr ); + + /* IExternalConnection methods */ + virtual DWORD STDMETHODCALLTYPE AddConnection( DWORD extconn, DWORD reserved); + virtual DWORD STDMETHODCALLTYPE ReleaseConnection( DWORD extconn, DWORD reserved, BOOL fLastReleaseCloses); + + // c++ - methods + + void notify( bool bDataChanged = true ); + HRESULT SaveObject(); + HRESULT ShowObject(); + GUID GetGUID() const { return m_guid; } + HRESULT OLENotifyClosing(); + + void Deactivate(); + HRESULT OLENotifyDeactivation(); + +protected: + oslInterlockedCount m_refCount; + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + + DocumentHolder* m_pDocHolder; + ::rtl::OUString m_aFileName; + + CComPtr< IStorage > m_pMasterStorage; + CComPtr< IStream > m_pOwnStream; + CComPtr< IStream > m_pExtStream; + GUID m_guid; + + sal_Bool m_bIsDirty; + + CComPtr< IOleClientSite > m_pClientSite; + CComPtr< IDataAdviseHolder > m_pDAdviseHolder; + + AdviseSinkHashMap m_aAdviseHashMap; + DWORD m_nAdviseNum; + + ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > m_xOwnAccess; + + sal_Bool m_bIsInVerbHandling; +}; + +class BooleanGuard_Impl +{ + sal_Bool& m_bValue; + +public: + BooleanGuard_Impl( sal_Bool& bValue ) + : m_bValue( bValue ) + { + m_bValue = sal_True; + } + + ~BooleanGuard_Impl() + { + m_bValue = sal_False; + } +}; + +#endif //_EMBEDDOC_HXX_ diff --git a/embedserv/source/inc/embeddocaccess.hxx b/embedserv/source/inc/embeddocaccess.hxx new file mode 100644 index 000000000000..7794af29b585 --- /dev/null +++ b/embedserv/source/inc/embeddocaccess.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: embeddocaccess.hxx,v $ + * $Revision: 1.5.10.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _EMBEDDOCACCESS_HXX_ +#define _EMBEDDOCACCESS_HXX_ + +#include <cppuhelper/weak.hxx> + +#define OLESERV_SAVEOBJECT 1 +#define OLESERV_CLOSE 2 +#define OLESERV_NOTIFY 3 +#define OLESERV_NOTIFYCLOSING 4 +#define OLESERV_SHOWOBJECT 5 +#define OLESERV_DEACTIVATE 6 + +#include <oleidl.h> +#ifndef __MINGW32__ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4265) +#include <atldbcli.h> +#else +#include <atlcomcli.h> +#endif +#endif +#include <cppuhelper/weak.hxx> + +class EmbedDocument_Impl; +struct LockedEmbedDocument_Impl +{ +private: + EmbedDocument_Impl* m_pEmbedDocument; + +public: + LockedEmbedDocument_Impl(); + LockedEmbedDocument_Impl( EmbedDocument_Impl* pEmbedDocument ); + LockedEmbedDocument_Impl( const LockedEmbedDocument_Impl& aDocLock ); + + ~LockedEmbedDocument_Impl(); + + LockedEmbedDocument_Impl& operator=( const LockedEmbedDocument_Impl& aDocLock ); + + EmbedDocument_Impl* GetEmbedDocument() { return m_pEmbedDocument; } + + void ExecuteMethod( sal_Int16 nId ); +}; + +class EmbeddedDocumentInstanceAccess_Impl : public ::cppu::OWeakObject +{ + ::osl::Mutex m_aMutex; + EmbedDocument_Impl* m_pEmbedDocument; + + public: + EmbeddedDocumentInstanceAccess_Impl( EmbedDocument_Impl* pDoc ) + : m_pEmbedDocument( pDoc ) + {} + + LockedEmbedDocument_Impl GetEmbedDocument(); + void ClearEmbedDocument(); +}; + +#endif diff --git a/embedserv/source/inc/embservconst.h b/embedserv/source/inc/embservconst.h new file mode 100644 index 000000000000..3328e31e318f --- /dev/null +++ b/embedserv/source/inc/embservconst.h @@ -0,0 +1,89 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: embservconst.h,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _EMBSERVCONST_H_ +#define _EMBSERVCONST_H_ + +#include <initguid.h> + +#ifndef _COMPHELPER_CLASSIDS_HXX +#include <comphelper/classids.hxx> +#endif + +#ifndef _SAL_TYPES_H_ +#include <sal/types.h> +#endif + +const sal_Int32 nConstBufferSize = 32000; + +#define SUPPORTED_FACTORIES_NUM 10 + +#ifdef __MINGW32__ +#define DECLSPEC_SELECTANY +#endif +#if defined(__MINGW32__) && !defined(INITGUID) +EXTERN_C const GUID DECLSPEC_SELECTANY OID_WriterTextServer; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_WriterOASISTextServer; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_CalcServer; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_CalcOASISServer; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_DrawingServer; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_DrawingOASISServer; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_PresentationServer; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_PresentationOASISServer; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_MathServer; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_MathOASISServer; +#else +EXTERN_C const GUID DECLSPEC_SELECTANY OID_WriterTextServer = { SO3_SW_OLE_EMBED_CLASSID_60 }; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_WriterOASISTextServer = { SO3_SW_OLE_EMBED_CLASSID_8 }; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_CalcServer = { SO3_SC_OLE_EMBED_CLASSID_60 }; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_CalcOASISServer = { SO3_SC_OLE_EMBED_CLASSID_8 }; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_DrawingServer = { SO3_SDRAW_OLE_EMBED_CLASSID_60 }; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_DrawingOASISServer = { SO3_SDRAW_OLE_EMBED_CLASSID_8 }; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_PresentationServer = { SO3_SIMPRESS_OLE_EMBED_CLASSID_60 }; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_PresentationOASISServer = { SO3_SIMPRESS_OLE_EMBED_CLASSID_8 }; + +EXTERN_C const GUID DECLSPEC_SELECTANY OID_MathServer = { SO3_SM_OLE_EMBED_CLASSID_60 }; +EXTERN_C const GUID DECLSPEC_SELECTANY OID_MathOASISServer = { SO3_SM_OLE_EMBED_CLASSID_8 }; +#endif + +#endif + diff --git a/embedserv/source/inc/iipaobj.hxx b/embedserv/source/inc/iipaobj.hxx new file mode 100644 index 000000000000..097b5621f2ef --- /dev/null +++ b/embedserv/source/inc/iipaobj.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: iipaobj.hxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _IIPAOBJ_HXX_ +#define _IIPAOBJ_HXX_ +#if defined(_MSC_VER) && (_MSC_VER > 1310) +#pragma warning(disable : 4917 4555) +#endif + +#include "stdafx.h" +#include <oleidl.h> + +#include <osl/interlck.h> +#include <rtl/ref.hxx> +class EmbedDocument_Impl; +class DocumentHolder; + +class CIIAObj + : public IOleInPlaceActiveObject +{ + +public: + + CIIAObj( DocumentHolder * ); + virtual ~CIIAObj(); + + /* IUnknown methods */ + STDMETHODIMP QueryInterface(REFIID, LPVOID FAR * ppvObj); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + /* IOleInPlaceActiveObject methods */ + STDMETHODIMP GetWindow(HWND *); + STDMETHODIMP ContextSensitiveHelp(BOOL); + STDMETHODIMP TranslateAccelerator(LPMSG); + STDMETHODIMP OnFrameWindowActivate(BOOL); + STDMETHODIMP OnDocWindowActivate(BOOL); + STDMETHODIMP ResizeBorder(LPCRECT, LPOLEINPLACEUIWINDOW + , BOOL); + STDMETHODIMP EnableModeless(BOOL); + + +private: + + oslInterlockedCount m_refCount; + ::rtl::Reference< DocumentHolder > m_rDocHolder; +}; + + +#endif
\ No newline at end of file diff --git a/embedserv/source/inc/intercept.hxx b/embedserv/source/inc/intercept.hxx new file mode 100644 index 000000000000..164ce2009139 --- /dev/null +++ b/embedserv/source/inc/intercept.hxx @@ -0,0 +1,198 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: intercept.hxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _INTERCEPT_HXX_ +#define _INTERCEPT_HXX_ + +#include <osl/mutex.hxx> +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp> +#include <com/sun/star/frame/XInterceptorInfo.hpp> +#include <com/sun/star/frame/XDispatch.hpp> + +#include <rtl/ref.hxx> +#include "embeddocaccess.hxx" + + +class StatusChangeListenerContainer; +class EmbedDocument_Impl; +class DocumentHolder; + +class Interceptor + : public ::cppu::WeakImplHelper3< + ::com::sun::star::frame::XDispatchProviderInterceptor, + ::com::sun::star::frame::XInterceptorInfo, + ::com::sun::star::frame::XDispatch> +{ +public: + + Interceptor( + const ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl >& xOleAccess, + DocumentHolder* pDocH, + sal_Bool bLink ); + + ~Interceptor(); + + void DisconnectDocHolder(); + + void generateFeatureStateEvent(); + + // overwritten to release the statuslistner. + + + // XComponent + virtual void SAL_CALL + addEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ); + + void SAL_CALL + dispose() throw(::com::sun::star::uno::RuntimeException); + + + + //XDispatch + virtual void SAL_CALL + dispatch( + const ::com::sun::star::util::URL& URL, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& Arguments ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addStatusListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XStatusListener >& Control, + const ::com::sun::star::util::URL& URL ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeStatusListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XStatusListener >& Control, + const ::com::sun::star::util::URL& URL ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + //XInterceptorInfo + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > + SAL_CALL getInterceptedURLs( ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + + //XDispatchProvider ( inherited by XDispatchProviderInterceptor ) + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatch > SAL_CALL + queryDispatch( + const ::com::sun::star::util::URL& URL, + const ::rtl::OUString& TargetFrameName, + sal_Int32 SearchFlags ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatch > > SAL_CALL + queryDispatches( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::frame::DispatchDescriptor >& Requests ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + + //XDispatchProviderInterceptor + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatchProvider > SAL_CALL + getSlaveDispatchProvider( ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + setSlaveDispatchProvider( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatchProvider >& NewDispatchProvider ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatchProvider > SAL_CALL + getMasterDispatchProvider( ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + setMasterDispatchProvider( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatchProvider >& NewSupplier ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + +private: + + osl::Mutex m_aMutex; + + ::rtl::Reference< EmbeddedDocumentInstanceAccess_Impl > m_xOleAccess; + + ::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface > m_xDocHLocker; + DocumentHolder* m_pDocH; + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatchProvider > m_xSlaveDispatchProvider; + + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatchProvider > m_xMasterDispatchProvider; + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > + m_aInterceptedURL; + + cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; + StatusChangeListenerContainer* m_pStatCL; + + sal_Bool m_bLink; +}; + +#endif diff --git a/embedserv/source/inc/servprov.hxx b/embedserv/source/inc/servprov.hxx new file mode 100755 index 000000000000..b978bf9f999e --- /dev/null +++ b/embedserv/source/inc/servprov.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: servprov.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SERVPROV_HXX +#define _SERVPROV_HXX + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +#undef _DEBUG +#endif + +#include "common.h" +#include <oleidl.h> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/uno/XInterface.hpp> +#ifndef __COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_ +#include <com/sun/star/lang/XTypeProvider.hpp> +#endif +#include <cppuhelper/weak.hxx> + + +class EmbedProviderFactory_Impl; + +class EmbedServer_Impl : public ::cppu::OWeakObject, ::com::sun::star::lang::XTypeProvider +{ +public: + EmbedServer_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &xFactory ); + virtual ~EmbedServer_Impl(); + + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XTypeProvider + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() + throw(::com::sun::star::uno::RuntimeException); + +protected: + + CComPtr< EmbedProviderFactory_Impl > m_pOLEFactories[ SUPPORTED_FACTORIES_NUM ]; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; +}; + +class EmbedProviderFactory_Impl : public IClassFactory +{ +public: + + EmbedProviderFactory_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory, const GUID* pGuid); + virtual ~EmbedProviderFactory_Impl(); + + sal_Bool registerClass(); + sal_Bool deregisterClass(); + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + /* IClassFactory methods */ + STDMETHOD(CreateInstance)(IUnknown FAR* punkOuter, REFIID riid, void FAR* FAR* ppv); + STDMETHOD(LockServer)(int fLock); + +protected: + + oslInterlockedCount m_refCount; + GUID m_guid; + DWORD m_factoryHandle; + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; +}; + +#endif diff --git a/embedserv/source/inc/stdafx.h b/embedserv/source/inc/stdafx.h new file mode 100755 index 000000000000..d20cb068be8f --- /dev/null +++ b/embedserv/source/inc/stdafx.h @@ -0,0 +1,42 @@ +#if !defined(AFX_STDAFX_H_) +#define AFX_STDAFX_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define STRICT +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#define _ATL_APARTMENT_THREADED +// #define _ATL_STATIC_REGISTRY + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(push, 1) +#pragma warning(disable: 4548) +#pragma warning(disable: 4505) +#endif +#include <atlbase.h> +//You may derive a class from CComModule and use it if you want to override +//something, but do not change the name of _Module +extern CComModule _Module; +#ifdef __MINGW32__ +#include <algorithm> +using ::std::min; +using ::std::max; +#endif +#include <atlcom.h> +#include <atlctl.h> + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#ifdef _MSC_VER +#pragma warning(pop) +#pragma warning(pop) +#endif + +#endif + diff --git a/embedserv/source/inc/syswinwrapper.hxx b/embedserv/source/inc/syswinwrapper.hxx new file mode 100644 index 000000000000..db6e2f6721ae --- /dev/null +++ b/embedserv/source/inc/syswinwrapper.hxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: syswinwrapper.hxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#include <windows.h> + +/** + ** CWindow: Our basic window class. + **/ + + +class DocumentHolder; + + +namespace winwrap { + + + void TransformRect(LPRECT rect,HWND pWnd,HWND pWndClipTo); + + + LRESULT APIENTRY HatchWndProc( + HWND hWnd, UINT iMsg + , WPARAM wParam, LPARAM lParam); + + + BOOL HatchWindowRegister(HINSTANCE hInst); + + class CWindow + { + protected: + HINSTANCE m_hInst; //Task instance + HWND m_hWnd; //Window handle of the window + + public: + //Standard Class Functions + CWindow(HINSTANCE); + ~CWindow(void); + + //Just returns members. No need to modify + HWND Window(void); + HINSTANCE Instance(void); + }; + + + + class Tracker { + public: + // Constructors + Tracker(); + Tracker(LPCRECT lpSrcRect, UINT nStyle); + + // Style Flags + enum StyleFlags + { + solidLine = 1, dottedLine = 2, hatchedBorder = 4, + resizeInside = 8, resizeOutside = 16, hatchInside = 32, + }; + + // Hit-Test codes + enum TrackerHit + { + hitNothing = -1, + hitTopLeft = 0, hitTopRight = 1, + hitBottomRight = 2, hitBottomLeft = 3, + hitTop = 4, hitRight = 5, hitBottom = 6, + hitLeft = 7, hitMiddle = 8 + }; + + // Attributes + UINT m_nStyle; // current state + RECT m_rect; // current position (always in pixels) + SIZE m_sizeMin; // minimum X and Y size during track operation + int m_nHandleSize; // size of resize handles (default from WIN.INI) + + // Operations + void Draw(HDC hDC) const; + void GetTrueRect(LPRECT lpTrueRect) const; + BOOL SetCursor(HWND hWnd,UINT nHitTest) const; + BOOL Track(HWND hWnd,POINT point,BOOL bAllowInvert = FALSE, + HWND hWndClipTo = NULL); +// BOOL TrackRubberBand(HWND hWnd,POINT point,BOOL bAllowInvert = TRUE); + int HitTest(POINT point) const; + int NormalizeHit(int nHandle) const; + + // Overridables + virtual void DrawTrackerRect( + LPRECT lpRect, HWND hWndClipTo, + HDC hDC, HWND hWnd); + virtual void AdjustRect(int nHandle, LPRECT lpRect); + virtual void OnChangedRect(const RECT& rectOld); + virtual UINT GetHandleMask() const; + +// Implementation + public: + virtual ~Tracker(); + +protected: + BOOL m_bAllowInvert; // flag passed to Track or TrackRubberBand + RECT m_rectLast; + SIZE m_sizeLast; + BOOL m_bErase; // TRUE if DrawTrackerRect is called for erasing + BOOL m_bFinalErase; // TRUE if DragTrackerRect called for final erase + + // implementation helpers + int HitTestHandles(POINT point) const; + void GetHandleRect(int nHandle,RECT* pHandleRect) const; + void GetModifyPointers( + int nHandle,int**ppx, int**ppy, int* px, int*py); + virtual int GetHandleSize(LPRECT lpRect = NULL) const; + BOOL TrackHandle(int nHandle,HWND hWnd,POINT point,HWND hWndClipTo); + void Construct(); + }; + + + +//Width of the border +#define HATCHWIN_BORDERWIDTHDEFAULT 4 + + + class CHatchWin : public CWindow + { + friend LRESULT APIENTRY HatchWndProc(HWND, UINT, WPARAM, LPARAM); + + public: + + const DocumentHolder* m_pDocHolder; + Tracker m_aTracker; + + int m_dBorder; + int m_dBorderOrg; + UINT m_uID; + HWND m_hWndParent; + HWND m_hWndKid; + HWND m_hWndAssociate; + RECT m_rcPos; + RECT m_rcClip; + + public: + CHatchWin(HINSTANCE,const DocumentHolder*); + ~CHatchWin(void); + + BOOL Init(HWND, UINT, HWND); + + HWND HwndAssociateSet(HWND); + HWND HwndAssociateGet(void); + + void RectsSet(LPRECT, LPRECT); + void ChildSet(HWND); + void ShowHatch(BOOL); + void SetTrans(); + }; + +} diff --git a/embedserv/source/inc/xwin.hxx b/embedserv/source/inc/xwin.hxx new file mode 100644 index 000000000000..6370579eca87 --- /dev/null +++ b/embedserv/source/inc/xwin.hxx @@ -0,0 +1,255 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xwin.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XWIN_HXX_ +#define _XWIN_HXX_ + + +#include "common.h" +#include <osl/mutex.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> + + +class ContainerWindowWrapper: + public ::cppu::WeakImplHelper2< + ::com::sun::star::awt::XWindow, + ::com::sun::star::awt::XSystemDependentWindowPeer> +{ +public: + + ContainerWindowWrapper(HWND aHwnd); + + ~ ContainerWindowWrapper(); + + + // XComponent + + virtual void SAL_CALL + dispose( + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XEventListener >& aListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + + // XSystemDependentWindowPeer + + virtual ::com::sun::star::uno::Any SAL_CALL + getWindowHandle( + const ::com::sun::star::uno::Sequence< sal_Int8 >& ProcessId, + sal_Int16 SystemType + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + // XWindow + + virtual void SAL_CALL + setPosSize( + sal_Int32 X, + sal_Int32 Y, + sal_Int32 Width, + sal_Int32 Height, + sal_Int16 Flags + ) + throw ( + ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::awt::Rectangle SAL_CALL + getPosSize( + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + setVisible( + sal_Bool Visible + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + setEnable( + sal_Bool Enable + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + setFocus( + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addWindowListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XWindowListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeWindowListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XWindowListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addFocusListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XFocusListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeFocusListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XFocusListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addKeyListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XKeyListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeKeyListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XKeyListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addMouseListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeMouseListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addMouseMotionListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseMotionListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removeMouseMotionListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XMouseMotionListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + addPaintListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XPaintListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + virtual void SAL_CALL + removePaintListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::awt::XPaintListener >& xListener + ) + throw ( + ::com::sun::star::uno::RuntimeException + ); + + +private: + + osl::Mutex m_aMutex; + cppu::OInterfaceContainerHelper *m_pDisposeEventListeners; + + HWND m_aHwnd; +}; + + +#endif diff --git a/embedserv/source/inprocserv/advisesink.cxx b/embedserv/source/inprocserv/advisesink.cxx new file mode 100644 index 000000000000..ea61f866c372 --- /dev/null +++ b/embedserv/source/inprocserv/advisesink.cxx @@ -0,0 +1,195 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: advisesink.cxx,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#pragma warning(disable : 4668) + +#include <advisesink.hxx> + +namespace inprocserv +{ + +OleWrapperAdviseSink::OleWrapperAdviseSink() +: m_nRefCount( 0 ) +, m_pFormatEtc( NULL ) +, m_nAspect( DVASPECT_CONTENT ) +, m_nRegID( 0 ) +, m_bObjectAdvise( TRUE ) +, m_nDataRegFlag( 0 ) +, m_nViewRegFlag( 0 ) +, m_bHandleClosed( TRUE ) +, m_bClosed( FALSE ) +{ +} + +OleWrapperAdviseSink::OleWrapperAdviseSink( const ComSmart< IAdviseSink >& pListener ) +: m_nRefCount( 0 ) +, m_pListener( pListener ) +, m_pFormatEtc( NULL ) +, m_nAspect( DVASPECT_CONTENT ) +, m_nRegID( 0 ) +, m_bObjectAdvise( TRUE ) +, m_nDataRegFlag( 0 ) +, m_nViewRegFlag( 0 ) +, m_bHandleClosed( FALSE ) +, m_bClosed( FALSE ) +{ +} + +OleWrapperAdviseSink::OleWrapperAdviseSink( const ComSmart< IAdviseSink >& pListener, FORMATETC* pFormatEtc, DWORD nDataRegFlag ) +: m_nRefCount( 0 ) +, m_pListener( pListener ) +, m_pFormatEtc( NULL ) +, m_nAspect( DVASPECT_CONTENT ) +, m_nRegID( 0 ) +, m_bObjectAdvise( FALSE ) +, m_nDataRegFlag( nDataRegFlag ) +, m_nViewRegFlag( 0 ) +, m_bHandleClosed( FALSE ) +, m_bClosed( FALSE ) +{ + if ( pFormatEtc ) + { + m_pFormatEtc = new FORMATETC; + m_pFormatEtc->cfFormat = pFormatEtc->cfFormat; + m_pFormatEtc->ptd = NULL; + m_pFormatEtc->dwAspect = pFormatEtc->dwAspect; + m_pFormatEtc->lindex = pFormatEtc->lindex; + m_pFormatEtc->tymed = pFormatEtc->tymed; + } +} + +OleWrapperAdviseSink::OleWrapperAdviseSink( const ComSmart< IAdviseSink >& pListener, DWORD nAspect, DWORD nViewRegFlag ) +: m_nRefCount( 0 ) +, m_pListener( pListener ) +, m_pFormatEtc( NULL ) +, m_nAspect( nAspect ) +, m_nRegID( 0 ) +, m_bObjectAdvise( TRUE ) +, m_nDataRegFlag( 0 ) +, m_nViewRegFlag( nViewRegFlag ) +, m_bHandleClosed( FALSE ) +, m_bClosed( FALSE ) +{ +} + +OleWrapperAdviseSink::~OleWrapperAdviseSink() +{ + if ( m_pFormatEtc ) + delete m_pFormatEtc; +} + +STDMETHODIMP OleWrapperAdviseSink::QueryInterface( REFIID riid , void** ppv ) +{ + *ppv=NULL; + + if ( riid == IID_IUnknown ) + *ppv = (IUnknown*)this; + + if ( riid == IID_IAdviseSink ) + *ppv = (IAdviseSink*)this; + + if ( *ppv != NULL ) + { + ((IUnknown*)*ppv)->AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) OleWrapperAdviseSink::AddRef() +{ + return ++m_nRefCount; +} + +STDMETHODIMP_(ULONG) OleWrapperAdviseSink::Release() +{ + ULONG nReturn = --m_nRefCount; + if ( m_nRefCount == 0 ) + delete this; + + return nReturn; +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnDataChange( LPFORMATETC pFetc, LPSTGMEDIUM pMedium ) +{ + if ( m_pListener ) + { + WRITEDEBUGINFO( "OleWrapperAdviseSink::OnDataChange():" ); + m_pListener->OnDataChange( pFetc, pMedium ); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnViewChange( DWORD dwAspect, LONG lindex ) +{ + if ( m_pListener ) + { + WRITEDEBUGINFO( "OleWrapperAdviseSink::OnViewChange():" ); + m_pListener->OnViewChange( dwAspect, lindex ); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnRename( LPMONIKER pMoniker ) +{ + if ( m_pListener ) + { + WRITEDEBUGINFO( "OleWrapperAdviseSink::OnRename():" ); + m_pListener->OnRename( pMoniker ); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnSave(void) +{ + if ( m_pListener ) + { + WRITEDEBUGINFO( "OleWrapperAdviseSink::OnSave():" ); + m_pListener->OnSave(); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnClose(void) +{ + if ( m_pListener ) + { + WRITEDEBUGINFO( "OleWrapperAdviseSink::OnClose():" ); + m_pListener->OnClose(); + } + + if ( m_bHandleClosed ) + m_bClosed = TRUE; +} + +} // namespace inprocserv + diff --git a/embedserv/source/inprocserv/advisesink.hxx b/embedserv/source/inprocserv/advisesink.hxx new file mode 100644 index 000000000000..c7ef75d0c028 --- /dev/null +++ b/embedserv/source/inprocserv/advisesink.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: advisesink.hxx,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <windows.h> +#include "smartpointer.hxx" + +namespace inprocserv { + +class OleWrapperAdviseSink : public IAdviseSink +{ +protected: + ULONG m_nRefCount; + + ComSmart< IAdviseSink > m_pListener; + DWORD m_nListenerID; + + FORMATETC* m_pFormatEtc; + DWORD m_nAspect; + + DWORD m_nRegID; + DWORD m_bObjectAdvise; + DWORD m_nDataRegFlag; + DWORD m_nViewRegFlag; + + BOOL m_bHandleClosed; + BOOL m_bClosed; + +public: + // an AdviseSink for own needs, should be created always + OleWrapperAdviseSink(); + + // an AdviseSink for IOleObject interface + OleWrapperAdviseSink( const ComSmart< IAdviseSink >& pListener ); + + // an AdviseSink for IDataObject interface + OleWrapperAdviseSink( const ComSmart< IAdviseSink >& pListener, FORMATETC* pFormatEtc, DWORD nDataRegFlag ); + + // an AdviseSink for IViewObject interface + OleWrapperAdviseSink( const ComSmart< IAdviseSink >& pListener, DWORD nAspect, DWORD nViewRegFlag ); + + virtual ~OleWrapperAdviseSink(); + + void SetRegID( DWORD nRegID ) { m_nRegID = nRegID; } + DWORD GetRegID() { return m_nRegID; } + + BOOL IsOleAdvise() { return m_bObjectAdvise; } + DWORD GetDataAdviseFlag() { return m_nDataRegFlag; } + DWORD GetViewAdviseFlag() { return m_nViewRegFlag; } + + FORMATETC* GetFormatEtc() { return m_pFormatEtc; } + DWORD GetAspect() { return m_nAspect; } + ComSmart< IAdviseSink >& GetOrigAdvise() { return m_pListener; } + void DisconnectOrigAdvise() { m_pListener = NULL; } + + void SetClosed() { m_bClosed = TRUE; } + void UnsetClosed() { m_bClosed = FALSE; } + BOOL IsClosed() { return m_bClosed; } + + STDMETHODIMP QueryInterface(REFIID, void**); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + STDMETHODIMP_(void) OnDataChange(LPFORMATETC, LPSTGMEDIUM); + STDMETHODIMP_(void) OnViewChange(DWORD, LONG); + STDMETHODIMP_(void) OnRename(LPMONIKER); + STDMETHODIMP_(void) OnSave(void); + STDMETHODIMP_(void) OnClose(void); +}; + +}; // namespace advisesink + diff --git a/embedserv/source/inprocserv/dllentry.cxx b/embedserv/source/inprocserv/dllentry.cxx new file mode 100644 index 000000000000..e8d327bc9e84 --- /dev/null +++ b/embedserv/source/inprocserv/dllentry.cxx @@ -0,0 +1,357 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dllentry.cxx,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <stdio.h> +#include <inprocembobj.h> +#ifdef __MINGW32__ +#define INITGUID +#endif +#include <embservconst.h> + +static const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = { + &OID_WriterTextServer, + &OID_WriterOASISTextServer, + &OID_CalcServer, + &OID_CalcOASISServer, + &OID_DrawingServer, + &OID_DrawingOASISServer, + &OID_PresentationServer, + &OID_PresentationOASISServer, + &OID_MathServer, + &OID_MathOASISServer +}; + +static HINSTANCE g_hInstance = NULL; +static ULONG g_nObj = 0; +static ULONG g_nLock = 0; + + +namespace { + void FillCharFromInt( int nValue, char* pBuf, int nLen ) + { + int nInd = 0; + while( nInd < nLen ) + { + char nSign = ( nValue / ( 1 << ( ( nLen - nInd ) * 4 ) ) ) % 16; + if ( nSign >= 0 && nSign <= 9 ) + pBuf[nInd] = nSign + '0'; + else if ( nSign >= 10 && nSign <= 15 ) + pBuf[nInd] = nSign - 10 + 'a'; + + nInd++; + } + } + + int GetStringFromClassID( const GUID& guid, char* pBuf, int nLen ) + { + // is not allowed to insert + if ( nLen < 38 ) + return 0; + + pBuf[0] = '{'; + FillCharFromInt( guid.Data1, &pBuf[1], 8 ); + pBuf[9] = '-'; + FillCharFromInt( guid.Data2, &pBuf[10], 4 ); + pBuf[14] = '-'; + FillCharFromInt( guid.Data3, &pBuf[15], 4 ); + pBuf[19] = '-'; + + int nInd = 0; + for ( nInd = 0; nInd < 2 ; nInd++ ) + FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 2*nInd], 2 ); + pBuf[24] = '-'; + for ( nInd = 2; nInd < 8 ; nInd++ ) + FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 1 + 2*nInd], 2 ); + pBuf[37] = '}'; + + return 38; + } + + HRESULT WriteLibraryToRegistry( char* pLibrary, DWORD nLen ) + { + HRESULT hRes = E_FAIL; + if ( pLibrary && nLen ) + { + HKEY hKey = NULL; + + hRes = S_OK; + for ( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ ) + { + char* pSubKey = "Software\\Classes\\CLSID\\.....................................\\InprocHandler32"; + + int nGuidLen = GetStringFromClassID( *guidList[nInd], &pSubKey[23], 38 ); + + BOOL bLocalSuccess = FALSE; + if ( nGuidLen && nGuidLen == 38 ) + { + if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, pSubKey, &hKey ) ) + { + if ( ERROR_SUCCESS == RegSetValueEx( hKey, "", 0, REG_SZ, (const BYTE*)pLibrary, nLen ) ) + bLocalSuccess = TRUE; + } + + if ( hKey ) + { + RegCloseKey( hKey ); + hKey = NULL; + } + } + + if ( !bLocalSuccess ) + hRes = E_FAIL; + } + } + + return hRes; + } +}; + +// =========================== +// InprocEmbedProvider_Impl declaration +// =========================== + +namespace inprocserv +{ + +class InprocEmbedProvider_Impl : public IClassFactory, public InprocCountedObject_Impl +{ +public: + + InprocEmbedProvider_Impl( const GUID& guid ); + virtual ~InprocEmbedProvider_Impl(); + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + /* IClassFactory methods */ + STDMETHOD(CreateInstance)(IUnknown FAR* punkOuter, REFIID riid, void FAR* FAR* ppv); + STDMETHOD(LockServer)(int fLock); + +protected: + + ULONG m_refCount; + GUID m_guid; +}; +}; // namespace inprocserv + + +// =========================== +// Entry points +// =========================== + +// ------------------------------------------------------------------------------- +extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/ ) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + } + else if (dwReason == DLL_PROCESS_DETACH) + { + } + + return TRUE; // ok +} + +// ------------------------------------------------------------------------------- +extern "C" STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv ) +{ + for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ ) + if ( *guidList[nInd] == rclsid ) + { + if ( !IsEqualIID( riid, IID_IUnknown ) && !IsEqualIID( riid, IID_IClassFactory ) ) + return E_NOINTERFACE; + + *ppv = new inprocserv::InprocEmbedProvider_Impl( rclsid ); + if ( *ppv == NULL ) + return E_OUTOFMEMORY; + + ((LPUNKNOWN)*ppv)->AddRef(); + return S_OK; + } + + return E_FAIL; +} + +// ------------------------------------------------------------------------------- +extern "C" STDAPI DllCanUnloadNow() +{ + if ( !g_nObj && !g_nLock ) + return S_OK; + + return S_FALSE; +} + +// ------------------------------------------------------------------------------- +STDAPI DllRegisterServer( void ) +{ + char aLibPath[1024]; + HMODULE aCurModule = GetModuleHandleA( "inprocserv.dll" ); + if( aCurModule ) + { + DWORD nLen = GetModuleFileNameA( aCurModule, aLibPath, 1019 ); + if ( nLen && nLen < 1019 ) + { + aLibPath[nLen++] = 0; + return WriteLibraryToRegistry( aLibPath, nLen ); + } + } + + return E_FAIL; +} + +// ------------------------------------------------------------------------------- +STDAPI DllUnregisterServer( void ) +{ + return WriteLibraryToRegistry( "ole32.dll", 10 ); +} + +// =========================== +// End of entry points +// =========================== + +namespace inprocserv +{ + +// =========================== +// InprocCountedObject_Impl implementation +// =========================== + +// ------------------------------------------------------------------------------- +InprocCountedObject_Impl::InprocCountedObject_Impl() +{ + g_nObj++; +} + +// ------------------------------------------------------------------------------- +InprocCountedObject_Impl::~InprocCountedObject_Impl() +{ + g_nObj--; +} + +// =========================== +// InprocEmbedProvider_Impl implementation +// =========================== + +// ------------------------------------------------------------------------------- +InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID& guid ) +: m_refCount( 0 ) +, m_guid( guid ) +{ +} + +// ------------------------------------------------------------------------------- +InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl() +{ +} + +// IUnknown +// ------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedProvider_Impl::QueryInterface( REFIID riid, void FAR* FAR* ppv ) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + AddRef(); + *ppv = (IUnknown*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IClassFactory)) + { + AddRef(); + *ppv = (IClassFactory*) this; + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +// ------------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::AddRef() +{ + return ++m_refCount; +} + +// ------------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::Release() +{ + sal_Int32 nCount = --m_refCount; + if ( nCount == 0 ) + delete this; + return nCount; +} + +// ------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedProvider_Impl::CreateInstance(IUnknown FAR* punkOuter, + REFIID riid, + void FAR* FAR* ppv) +{ + // TODO/LATER: should the aggregation be supported? + // if ( punkOuter != NULL && riid != IID_IUnknown ) + // return E_NOINTERFACE; + if ( punkOuter != NULL ) + return CLASS_E_NOAGGREGATION; + + InprocEmbedDocument_Impl* pEmbedDocument = new InprocEmbedDocument_Impl( m_guid ); + if ( !pEmbedDocument ) + return E_OUTOFMEMORY; + + pEmbedDocument->AddRef(); + HRESULT hr = pEmbedDocument->Init(); + if ( SUCCEEDED( hr ) ) + hr = pEmbedDocument->QueryInterface( riid, ppv ); + pEmbedDocument->Release(); + + if ( !SUCCEEDED( hr ) ) + *ppv = NULL; + + return hr; +} + +// ------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedProvider_Impl::LockServer( int fLock ) +{ + if ( fLock ) + g_nLock++; + else + g_nLock--; + + return S_OK; +} + +}; // namespace inprocserv + diff --git a/embedserv/source/inprocserv/exports.dxp b/embedserv/source/inprocserv/exports.dxp new file mode 100644 index 000000000000..65a5126f162e --- /dev/null +++ b/embedserv/source/inprocserv/exports.dxp @@ -0,0 +1,5 @@ +DllGetClassObject +DllCanUnloadNow +DllMain +DllRegisterServer +DllUnregisterServer diff --git a/embedserv/source/inprocserv/inprocembobj.cxx b/embedserv/source/inprocserv/inprocembobj.cxx new file mode 100644 index 000000000000..474f707d86f1 --- /dev/null +++ b/embedserv/source/inprocserv/inprocembobj.cxx @@ -0,0 +1,1990 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: inprocembobj.cxx,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <embservconst.h> +#include "inprocembobj.h" + +namespace inprocserv +{ + +#ifdef OWNDEBUG +//------------------------------------------------------------------------------- +void WriteDebugInfo( DWORD pThis, char* pString, DWORD nToWrite ) +{ + if ( nToWrite ) + { + char pNumber[12]; + pNumber[0] = '0'; + pNumber[1] = 'x'; + for ( int nInd = 0; nInd < 8; nInd++ ) + pNumber[nInd+2] = (char)( ( pThis / ( 1 << ( 7 - nInd ) ) ) % 16 ) + 48; + pNumber[10] = ' '; + pNumber[11] = 0; + + HANDLE pFile = CreateFileA( "h:\\inproc.log", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL ); + if ( pFile ) + { + DWORD dwWritten = 0; + SetFilePointer( pFile, 0, 0, FILE_END ); + WriteFile( pFile, pNumber, 11, &dwWritten, NULL ); + WriteFile( pFile, pString, nToWrite - 1, &dwWritten, NULL ); + CloseHandle( pFile ); + } + } +} +#endif + +//------------------------------------------------------------------------------- +BOOL StringsEqual( LPCOLESTR pszNameFromOutside, wchar_t* pOwnName ) +{ + BOOL bResult = TRUE; + + if ( pszNameFromOutside && pOwnName ) + { + for ( int nInd = 0; pszNameFromOutside[nInd] != 0 || pOwnName[nInd] != 0; nInd++ ) + { + if ( pszNameFromOutside[nInd] != pOwnName[nInd] ) + { + bResult = FALSE; + break; + } + } + } + else if ( pszNameFromOutside || pOwnName ) + bResult = FALSE; + + return bResult; +} + +//------------------------------------------------------------------------------- +HRESULT InprocEmbedDocument_Impl::Init() +{ + return S_OK; +} + +//------------------------------------------------------------------------------- +void InprocEmbedDocument_Impl::SetName( LPCOLESTR pszNameFromOutside, wchar_t*& pOwnName ) +{ + if ( !pszNameFromOutside ) + return; + + // copy the string + size_t nLen = 0; + while( pszNameFromOutside[nLen] != 0 ) + nLen++; + + if ( pOwnName ) + { + delete[] pOwnName; + pOwnName = NULL; + } + + pOwnName = new wchar_t[nLen+1]; + for ( size_t nInd = 0; nInd < nLen; nInd++ ) + pOwnName[nInd] = pszNameFromOutside[nInd]; + pOwnName[nLen] = 0; +} + +//------------------------------------------------------------------------------- +BOOL InprocEmbedDocument_Impl::CheckDefHandler() +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + // set the own listener + if ( m_pOleAdvises[0] == NULL ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + m_pOleAdvises[0] = new OleWrapperAdviseSink(); + } + else + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( m_pOleAdvises[0]->IsClosed() ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( m_pDefHandler ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + // deregister all the listeners + + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + if ( SUCCEEDED( hr ) && pOleObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pOleAdvises[nInd] ) + { + DWORD nID = m_pOleAdvises[nInd]->GetRegID(); + pOleObject->Unadvise( nID ); + m_pOleAdvises[nInd]->SetRegID( 0 ); + } + + pOleObject->SetClientSite( NULL ); + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IDataObject > pIDataObject; + hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + if ( SUCCEEDED( hr ) && pIDataObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pDataAdvises[nInd] ) + { + DWORD nID = m_pDataAdvises[nInd]->GetRegID(); + pIDataObject->DUnadvise( nID ); + m_pDataAdvises[nInd]->SetRegID( 0 ); + } + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IViewObject > pIViewObject; + hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + if ( SUCCEEDED( hr ) && pIViewObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( m_pViewAdvise ) + pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), NULL ); + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + } + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + + ComSmart< IPersistStorage > pPersist; + hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + if ( SUCCEEDED( hr ) && pPersist ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + // disconnect the old wrapper from the storage + pPersist->HandsOffStorage(); + } + + m_pDefHandler = NULL; + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + m_pOleAdvises[0]->UnsetClosed(); + } + } + + if ( m_nCallsOnStack ) + return FALSE; + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( !m_pDefHandler ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + // create a new default inprocess handler + HRESULT hr = OleCreateDefaultHandler( m_guid, NULL, IID_IUnknown, (void**)&m_pDefHandler ); + if ( SUCCEEDED( hr ) ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); +// // reinit the handler +// ComSmart< IRunnableObject > pIRunObj; +// hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, (void**)&pIRunObj ); +// +// if ( SUCCEEDED( hr ) && pIRunObj ) + { +// { +// ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem +// hr = pIRunObj->Run( NULL ); +// } +// +// if ( SUCCEEDED( hr ) ) + { + if ( m_nInitMode == INIT_FROM_STORAGE ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IPersistStorage > pPersist; + hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist && m_pStorage ) + hr = pPersist->InitNew( m_pStorage ); + } + else if ( m_nInitMode == LOAD_FROM_STORAGE ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IPersistStorage > pPersist; + hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist && m_pStorage ) + hr = pPersist->Load( m_pStorage ); + } + else if ( m_nInitMode == LOAD_FROM_FILE ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IPersistFile > pPersistFile; + hr = m_pDefHandler->QueryInterface( IID_IPersistFile, (void**)&pPersistFile ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersistFile && m_pFileName ) + hr = pPersistFile->Load( m_pFileName, m_nFileOpenMode ); + } + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + } + } + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( !SUCCEEDED( hr ) || !m_pDefHandler ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + m_pDefHandler = NULL; + return FALSE; + } + + // register all the listeners new + + ComSmart< IOleObject > pOleObject; + hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + if ( SUCCEEDED( hr ) && pOleObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( m_pClientSite ) + pOleObject->SetClientSite( m_pClientSite ); + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pOleAdvises[nInd] ) + { + DWORD nRegID = 0; + if ( SUCCEEDED( pOleObject->Advise( m_pOleAdvises[nInd], &nRegID ) ) && nRegID > 0 ) + m_pOleAdvises[nInd]->SetRegID( nRegID ); + } + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IDataObject > pIDataObject; + hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + if ( SUCCEEDED( hr ) && pIDataObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pDataAdvises[nInd] ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + DWORD nRegID = 0; + if ( SUCCEEDED( pIDataObject->DAdvise( m_pDataAdvises[nInd]->GetFormatEtc(), m_pDataAdvises[nInd]->GetDataAdviseFlag(), m_pDataAdvises[nInd], &nRegID ) ) && nRegID > 0 ) + m_pDataAdvises[nInd]->SetRegID( nRegID ); + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + } + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + ComSmart< IViewObject > pIViewObject; + hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + if ( SUCCEEDED( hr ) && pIViewObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + if ( m_pViewAdvise ) + pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), m_pViewAdvise ); + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + } + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::CheckDefHandler()" ); + + return TRUE; +} + +//------------------------------------------------------------------------------- +DWORD InprocEmbedDocument_Impl::InsertAdviseLinkToList( const ComSmart<OleWrapperAdviseSink>& pOwnAdvise, ComSmart< OleWrapperAdviseSink > pAdvises[] ) +{ + // the result should start from 1 in case of success, the element 0 can be used for own needs + DWORD nResult = 0; + + if ( pOwnAdvise ) + { + for ( DWORD nInd = 1; nInd < DEFAULT_ARRAY_LEN && nResult == 0; nInd++ ) + { + if ( pAdvises[nInd] == pOwnAdvise ) + { + nResult = nInd; + } + else if ( pAdvises[nInd] == NULL ) + { + pAdvises[nInd] = pOwnAdvise; + nResult = nInd; + } + } + } + + return nResult; +} + +//------------------------------------------------------------------------------- +void InprocEmbedDocument_Impl::Clean() +{ + m_pDefHandler = (IUnknown*)NULL; + + // no DisconnectOrigAdvise() call here, since it is no explicit disconnection + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + { + if ( m_pOleAdvises[nInd] ) + { + ComSmart< OleWrapperAdviseSink > pAdvise = m_pOleAdvises[nInd]; + m_pOleAdvises[nInd] = NULL; + } + + if ( m_pDataAdvises[nInd] ) + { + ComSmart< OleWrapperAdviseSink > pAdvise = m_pDataAdvises[nInd]; + m_pDataAdvises[nInd] = NULL; + } + } + + m_pViewAdvise = NULL; + + m_nInitMode = NOINIT; + m_pStorage = NULL; + + if ( m_pOleContainer ) + { + m_pOleContainer->LockContainer( FALSE ); + m_pOleContainer = NULL; + } + + m_pClientSite = NULL; + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete m_pFileName; + m_pFileName = NULL; + } +} + +// IUnknown +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::QueryInterface( REFIID riid, void FAR* FAR* ppv ) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + AddRef(); + *ppv = (IUnknown*) (IPersistStorage*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersist)) + { + AddRef(); + *ppv = (IPersist*) (IPersistStorage*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersistStorage)) + { + AddRef(); + *ppv = (IPersistStorage*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IDataObject)) + { + AddRef(); + *ppv = (IDataObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleObject)) + { + AddRef(); + *ppv = (IOleObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersistFile)) + { + AddRef(); + *ppv = (IPersistFile*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IRunnableObject)) + { + AddRef(); + *ppv = (IRunnableObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IViewObject)) + { + AddRef(); + *ppv = (IViewObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IViewObject2)) + { + AddRef(); + *ppv = (IViewObject2*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleCache)) + { + AddRef(); + *ppv = (IOleCache*) &m_aInternalCache; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleCache2)) + { + AddRef(); + *ppv = (IOleCache2*) &m_aInternalCache; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleWindow)) + { + AddRef(); + *ppv = (IOleWindow*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleInPlaceObject)) + { + AddRef(); + *ppv = (IOleInPlaceObject*) this; + return S_OK; + } + else if (IsEqualIID(riid, IID_IDispatch)) + { + AddRef(); + *ppv = (IDispatch*) this; + return S_OK; + } + + *ppv = NULL; + return ResultFromScode(E_NOINTERFACE); +} + +//------------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::AddRef() +{ + return ++m_refCount; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::Release() +{ + // unfortunately there are reentrance problems in mfc that have to be workarounded + sal_Int32 nCount = m_refCount > 0 ? --m_refCount : 0; + if ( nCount == 0 && !m_bDeleted ) + { + // deleting of this object can trigger deleting of mfc objects that will try to delete this object one more time + m_bDeleted = TRUE; + + Clean(); + delete this; + } + return nCount; +} + +// IPersist +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetClassID( CLSID* pClassId ) +{ + *pClassId = *&m_guid; + return S_OK; +} + +// IPersistStorage +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::IsDirty() +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::IsDirty()1" ); + if ( m_pDefHandler == NULL || m_pOleAdvises[0] == NULL || m_pOleAdvises[0]->IsClosed() ) + return S_FALSE; + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::IsDirty()2" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistStorage > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + return pPersist->IsDirty(); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InitNew( IStorage *pStg ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InitNew( IStorage *pStg )" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistStorage > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + { + hr = pPersist->InitNew( pStg ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = INIT_FROM_STORAGE; + m_pStorage = pStg; + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete[] m_pFileName; + m_pFileName = NULL; + } + } + + return hr; + } + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Load( IStorage *pStg ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Load( IStorage *pStg )" ); + if ( CheckDefHandler() ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Load( IStorage *pStg )" ); + ComSmart< IPersistStorage > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Load( IStorage *pStg )" ); + hr = pPersist->Load( pStg ); + if ( SUCCEEDED( hr ) ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Load( IStorage *pStg )" ); + m_nInitMode = LOAD_FROM_STORAGE; + m_pStorage = pStg; + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Load( IStorage *pStg )" ); + delete[] m_pFileName; + m_pFileName = NULL; + } + } + + return hr; + } + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Save( IStorage *pStgSave, BOOL fSameAsLoad ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Save( IStorage *pStgSave, BOOL fSameAsLoad )" ); + if ( fSameAsLoad && ( m_pDefHandler == NULL || m_pOleAdvises[0] == NULL || m_pOleAdvises[0]->IsClosed() ) ) + return S_OK; + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Save( IStorage *pStgSave, BOOL fSameAsLoad )" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistStorage > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + return pPersist->Save( pStgSave, fSameAsLoad ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew )" ); + if ( m_pDefHandler == NULL || m_pOleAdvises[0] == NULL || m_pOleAdvises[0]->IsClosed() ) + { + if ( pStgNew ) + m_pStorage = pStgNew; + + return S_OK; + } + + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew )" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistStorage > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + { + hr = pPersist->SaveCompleted( pStgNew ); + if ( SUCCEEDED( hr ) ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew )" ); + m_nInitMode = LOAD_FROM_STORAGE; + if ( pStgNew ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew )" ); + m_pStorage = pStgNew; + } + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete[] m_pFileName; + m_pFileName = NULL; + } + } + + return hr; + } + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::HandsOffStorage() +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::HandsOffStorage()" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistStorage > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + { + hr = pPersist->HandsOffStorage(); + if ( SUCCEEDED( hr ) ) + { + m_pStorage = NULL; + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::HandsOffStorage()" ); + } + + return hr; + } + } + + return E_FAIL; +} + +// IPersistFile +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Load( LPCOLESTR pszFileName, DWORD dwMode ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Load( LPCOLESTR pszFileName, DWORD dwMode )" ); + if ( CheckDefHandler() && pszFileName ) + { + ComSmart< IPersistFile > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + { + hr = pPersist->Load( pszFileName, dwMode ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = LOAD_FROM_FILE; + if ( m_pStorage ) + m_pStorage = NULL; + + m_nFileOpenMode = dwMode; + // copy the string + SetName( pszFileName, m_pFileName ); + } + + return hr; + } + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Save( LPCOLESTR pszFileName, BOOL fRemember ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Save( LPCOLESTR pszFileName, BOOL fRemember )" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistFile > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + return pPersist->Save( pszFileName, fRemember ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName )" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistFile > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + { + hr = pPersist->SaveCompleted( pszFileName ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = LOAD_FROM_STORAGE; + if ( m_pStorage ) + m_pStorage = NULL; + + m_nFileOpenMode = STGM_READWRITE; // was just written + // copy the string + SetName( pszFileName, m_pFileName ); + } + } + + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetCurFile( LPOLESTR *ppszFileName ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetCurFile( LPOLESTR *ppszFileName )" ); + if ( CheckDefHandler() ) + { + ComSmart< IPersistFile > pPersist; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, (void**)&pPersist ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pPersist ) + return pPersist->GetCurFile( ppszFileName ); + } + + return E_FAIL; +} + +// IOleObject +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetClientSite( IOleClientSite* pSite ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetClientSite( IOleClientSite* pSite )" ); + if ( pSite == m_pClientSite ) + return S_OK; + + if ( !pSite ) + { + m_pClientSite = NULL; + if ( m_pOleContainer ) + { + m_pOleContainer->LockContainer( FALSE ); + m_pOleContainer = NULL; + } + } + + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + { + HRESULT hr = pOleObject->SetClientSite( pSite ); + if ( SUCCEEDED( hr ) ) + { + m_pClientSite = pSite; + + if ( m_pOleContainer ) + { + m_pOleContainer->LockContainer( FALSE ); + m_pOleContainer = NULL; + } + + m_pClientSite->GetContainer( &m_pOleContainer ); + if ( m_pOleContainer ) + m_pOleContainer->LockContainer( TRUE ); + } + + return hr; + } + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetClientSite( IOleClientSite** pSite ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetClientSite( IOleClientSite** pSite )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->GetClientSite( pSite ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )" ); + + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + { + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )" ); + hr = pOleObject->SetHostNames( szContainerApp, szContainerObj ); + } + } + + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Close( DWORD dwSaveOption ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Close( DWORD dwSaveOption )" ); + if ( m_pDefHandler && CheckDefHandler() ) + { + // no need to close if there is no default handler. + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + { + hr = pOleObject->Close( dwSaveOption ); + hr = CoDisconnectObject( (IUnknown*)(IPersistStorage*)this, 0 ); + } + } + + // if the object is closed from outside that means that it should go to uninitialized state + Clean(); + + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetMoniker( DWORD dwWhichMoniker, IMoniker * pmk ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetMoniker( DWORD dwWhichMoniker, IMoniker * pmk )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->SetMoniker( dwWhichMoniker, pmk ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->GetMoniker( dwAssign, dwWhichMoniker, ppmk ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InitFromData( IDataObject * pDataObject, BOOL fCreation, DWORD dwReserved ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InitFromData( IDataObject * pDataObject, BOOL fCreation, DWORD dwReserved )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->InitFromData( pDataObject, fCreation, dwReserved ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetClipboardData( DWORD dwReserved, IDataObject ** ppDataObject ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetClipboardData( DWORD dwReserved, IDataObject ** ppDataObject )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->GetClipboardData( dwReserved, ppDataObject ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::DoVerb( + LONG iVerb, + LPMSG pMsg, + IOleClientSite *pActiveSite, + LONG nLong, + HWND hWin, + LPCRECT pRect ) +{ + WRITEDEBUGINFO( "DoVerb" ); + if ( CheckDefHandler() ) + { + WRITEDEBUGINFO( "DoVerb" MY_STRING_LINE "n" ); + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + WRITEDEBUGINFO( "DoVerb" ); + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + WRITEDEBUGINFO( "DoVerb" ); + if ( SUCCEEDED( hr ) && pOleObject ) + { + WRITEDEBUGINFO( "DoVerb" ); + hr = pOleObject->DoVerb( iVerb, pMsg, pActiveSite, nLong, hWin, pRect ); + if ( SUCCEEDED( hr ) ) + { + WRITEDEBUGINFO( "DoVerb" ); + } + + return hr; + } + + WRITEDEBUGINFO( "DoVerb" ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** ppEnumOleVerb ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** ppEnumOleVerb )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->EnumVerbs( ppEnumOleVerb ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Update() +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Update()" ); + + if ( m_pDefHandler && CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->Update(); + } + + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::IsUpToDate() +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::IsUpToDate()" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->IsUpToDate(); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetUserClassID( CLSID *pClsid ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetUserClassID( CLSID *pClsid )" ); + if ( pClsid ) + *pClsid = m_guid; + + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetUserType( DWORD dwFormOfType, LPOLESTR * pszUserType ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetUserType( DWORD dwFormOfType, LPOLESTR * pszUserType )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->GetUserType( dwFormOfType, pszUserType ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetExtent( DWORD dwDrawAspect, SIZEL *psizel ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetExtent( DWORD dwDrawAspect, SIZEL *psizel )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->SetExtent( dwDrawAspect, psizel ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, SIZEL * psizel ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, SIZEL * psizel )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->GetExtent( dwDrawAspect, psizel ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )" ); + + if ( !pdwConnection ) + return E_FAIL; + + // CheckDefHandler will set the listener, avoid reusing of old listener + if ( DEFAULT_ARRAY_LEN > *pdwConnection && *pdwConnection > 0 && m_pOleAdvises[*pdwConnection] ) + { + m_pOleAdvises[*pdwConnection]->DisconnectOrigAdvise(); + m_pOleAdvises[*pdwConnection] = NULL; + } + + if ( pAdvSink && CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + { + ComSmart< OleWrapperAdviseSink > pOwnAdvise( new OleWrapperAdviseSink( pAdvSink ) ); + DWORD nRegID = 0; + + if ( SUCCEEDED( pOleObject->Advise( pOwnAdvise, &nRegID ) ) && nRegID > 0 ) + { + pOwnAdvise->SetRegID( nRegID ); + *pdwConnection = InsertAdviseLinkToList( pOwnAdvise, m_pOleAdvises ); + if ( *pdwConnection ) + return S_OK; + else + pOleObject->Unadvise( nRegID ); + } + } + } + + // return success always for now + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Unadvise( DWORD dwConnection ) +{ + if ( DEFAULT_ARRAY_LEN > dwConnection && dwConnection > 0 && m_pOleAdvises[dwConnection] ) + { + if ( m_pDefHandler ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + { + DWORD nID = m_pOleAdvises[dwConnection]->GetRegID(); + pOleObject->Unadvise( nID ); + } + } + + m_pOleAdvises[dwConnection]->DisconnectOrigAdvise(); + m_pOleAdvises[dwConnection] = NULL; + + return S_OK; + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ ) +{ + return E_NOTIMPL; + +// if ( CheckDefHandler() ) +// { +// ComSmart< IOleObject > pOleObject; +// HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); +// +// ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem +// if ( SUCCEEDED( hr ) && pOleObject ) +// return pOleObject->EnumAdvise( ppenumAdvise ); +// } +// +// return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetMiscStatus( DWORD dwAspect, DWORD * pdwStatus ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetMiscStatus( DWORD dwAspect, DWORD * pdwStatus )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->GetMiscStatus( dwAspect, pdwStatus ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetColorScheme( LOGPALETTE * pLogpal ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetColorScheme( LOGPALETTE * pLogpal )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleObject > pOleObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, (void**)&pOleObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pOleObject ) + return pOleObject->SetColorScheme( pLogpal ); + } + + return E_FAIL; +} + +//IDataObject +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->GetData( pFormatetc, pMedium ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->GetDataHere( pFormatetc, pMedium ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->QueryGetData( pFormatetc ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->GetCanonicalFormatEtc( pFormatetcIn, pFormatetcOut ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->SetData( pFormatetc, pMedium, fRelease ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->EnumFormatEtc( dwDirection, ppFormatetc ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection )" ); + + if ( !pdwConnection ) + return E_FAIL; + + // avoid reusing of the old listener + if ( m_pDefHandler && DEFAULT_ARRAY_LEN > *pdwConnection && *pdwConnection > 0 && m_pDataAdvises[*pdwConnection] ) + { + m_pDataAdvises[*pdwConnection]->DisconnectOrigAdvise(); + m_pDataAdvises[*pdwConnection] = NULL; + } + + if ( pAdvSink && CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + { + ComSmart< OleWrapperAdviseSink > pOwnAdvise( new OleWrapperAdviseSink( ComSmart<IAdviseSink>( pAdvSink ), pFormatetc, advf ) ); + DWORD nRegID = 0; + + if ( SUCCEEDED( pIDataObject->DAdvise( pFormatetc, advf, pOwnAdvise, &nRegID ) ) && nRegID > 0 ) + { + pOwnAdvise->SetRegID( nRegID ); + *pdwConnection = InsertAdviseLinkToList( pOwnAdvise, m_pDataAdvises ); + if ( *pdwConnection ) + return S_OK; + else + pIDataObject->DUnadvise( nRegID ); + } + } + } + + // return success always for now + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::DUnadvise( DWORD dwConnection ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::DUnadvise( DWORD dwConnection )" ); + if ( m_pDefHandler && DEFAULT_ARRAY_LEN > dwConnection && dwConnection > 0 && m_pDataAdvises[dwConnection] ) + { + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + { + DWORD nID = m_pDataAdvises[dwConnection]->GetRegID(); + pIDataObject->DUnadvise( nID ); + } + } + + m_pDataAdvises[dwConnection]->DisconnectOrigAdvise(); + m_pDataAdvises[dwConnection] = NULL; + + return S_OK; + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDataObject > pIDataObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, (void**)&pIDataObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDataObject ) + return pIDataObject->EnumDAdvise( ppenumAdvise ); + } + + return E_FAIL; +} + +// IRunnableObject +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetRunningClass( LPCLSID lpClsid ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetRunningClass( LPCLSID lpClsid )" ); + if ( CheckDefHandler() ) + { + ComSmart< IRunnableObject > pIRunObj; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, (void**)&pIRunObj ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIRunObj ) + return pIRunObj->GetRunningClass( lpClsid ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Run( LPBINDCTX pbc ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Run( LPBINDCTX pbc )" ); + if ( CheckDefHandler() ) + { + ComSmart< IRunnableObject > pIRunObj; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, (void**)&pIRunObj ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIRunObj ) + return pIRunObj->Run( pbc ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +BOOL STDMETHODCALLTYPE InprocEmbedDocument_Impl::IsRunning() +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::IsRunning()" ); + if ( CheckDefHandler() ) + { + ComSmart< IRunnableObject > pIRunObj; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, (void**)&pIRunObj ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIRunObj ) + return pIRunObj->IsRunning(); + } + + return E_FAIL; + +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::LockRunning( BOOL fLock, BOOL fLastUnlockCloses ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::LockRunning( BOOL fLock, BOOL fLastUnlockCloses )" ); + if ( CheckDefHandler() ) + { + ComSmart< IRunnableObject > pIRunObj; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, (void**)&pIRunObj ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIRunObj ) + return pIRunObj->LockRunning( fLock, fLastUnlockCloses ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetContainedObject( BOOL fContained) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetContainedObject( BOOL fContained)" ); + if ( CheckDefHandler() ) + { + ComSmart< IRunnableObject > pIRunObj; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, (void**)&pIRunObj ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIRunObj ) + return pIRunObj->SetContainedObject( fContained ); + } + + return E_FAIL; +} + + +// IViewObject methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Draw( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue ), ULONG_PTR dwContinue ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Draw( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue ), ULONG_PTR dwContinue )" ); + if ( CheckDefHandler() ) + { + ComSmart< IViewObject > pIViewObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIViewObject ) + return pIViewObject->Draw( dwDrawAspect, lindex, pvAspect, ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetColorSet( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetColorSet( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet )" ); + if ( CheckDefHandler() ) + { + ComSmart< IViewObject > pIViewObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIViewObject ) + return pIViewObject->GetColorSet( dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Freeze( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Freeze( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze )" ); + if ( CheckDefHandler() ) + { + ComSmart< IViewObject > pIViewObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIViewObject ) + return pIViewObject->Freeze( dwDrawAspect, lindex, pvAspect, pdwFreeze ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Unfreeze( DWORD dwFreeze ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Unfreeze( DWORD dwFreeze )" ); + if ( CheckDefHandler() ) + { + ComSmart< IViewObject > pIViewObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIViewObject ) + return pIViewObject->Unfreeze( dwFreeze ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetAdvise( DWORD aspects, DWORD advf, IAdviseSink *pAdvSink ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetAdvise( DWORD aspects, DWORD advf, IAdviseSink *pAdvSink )" ); + + // CheckDefHandler will set the listener, avoid reusing of old listener + if ( m_pViewAdvise ) + { + m_pViewAdvise->DisconnectOrigAdvise(); + m_pViewAdvise = NULL; + } + + if ( pAdvSink && CheckDefHandler() ) + { + ComSmart< IViewObject > pIViewObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, (void**)&pIViewObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIViewObject ) + { + ComSmart< OleWrapperAdviseSink > pOwnAdvise( new OleWrapperAdviseSink( pAdvSink, aspects, advf ) ); + + if ( SUCCEEDED( pIViewObject->SetAdvise( aspects, advf, pOwnAdvise ) ) ) + { + m_pViewAdvise = pOwnAdvise; + return S_OK; + } + } + } + + return S_OK; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetAdvise( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink ) +{ + if ( !ppAdvSink ) + return E_INVALIDARG; + + if ( m_pViewAdvise ) + { + if ( pAspects ) + *pAspects = m_pViewAdvise->GetAspect(); + + if ( pAdvf ) + *pAdvf = m_pViewAdvise->GetViewAdviseFlag(); + + *ppAdvSink = m_pViewAdvise->GetOrigAdvise(); + if ( *ppAdvSink ) + (*ppAdvSink)->AddRef(); + } + else + *ppAdvSink = NULL; + + return S_OK; +} + +// IViewObject2 methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel )" ); + if ( CheckDefHandler() ) + { + ComSmart< IViewObject2 > pIViewObject2; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject2, (void**)&pIViewObject2 ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIViewObject2 ) + return pIViewObject2->GetExtent( dwDrawAspect, lindex, ptd, lpsizel ); + } + + return E_FAIL; +} + + + +// IOleWindow methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetWindow( HWND *phwnd ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetWindow( HWND *phwnd )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleWindow > pIOleWindow; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleWindow, (void**)&pIOleWindow ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleWindow ) + return pIOleWindow->GetWindow( phwnd ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::ContextSensitiveHelp( BOOL fEnterMode ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::ContextSensitiveHelp( BOOL fEnterMode )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleWindow > pIOleWindow; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleWindow, (void**)&pIOleWindow ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleWindow ) + return pIOleWindow->ContextSensitiveHelp( fEnterMode ); + } + + return E_FAIL; +} + + +// IOleInPlaceObject methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InPlaceDeactivate( void ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InPlaceDeactivate( void )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleInPlaceObject > pIOleInPlaceObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, (void**)&pIOleInPlaceObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleInPlaceObject ) + return pIOleInPlaceObject->InPlaceDeactivate(); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::UIDeactivate( void ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::UIDeactivate( void )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleInPlaceObject > pIOleInPlaceObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, (void**)&pIOleInPlaceObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleInPlaceObject ) + return pIOleInPlaceObject->UIDeactivate(); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleInPlaceObject > pIOleInPlaceObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, (void**)&pIOleInPlaceObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleInPlaceObject ) + return pIOleInPlaceObject->SetObjectRects( lprcPosRect, lprcClipRect ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::ReactivateAndUndo( void ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::ReactivateAndUndo( void )" ); + if ( CheckDefHandler() ) + { + ComSmart< IOleInPlaceObject > pIOleInPlaceObject; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, (void**)&pIOleInPlaceObject ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleInPlaceObject ) + return pIOleInPlaceObject->ReactivateAndUndo(); + } + + return E_FAIL; +} + + +// IDispatch methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfoCount( UINT *pctinfo ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetTypeInfoCount( UINT *pctinfo )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDispatch > pIDispatch; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, (void**)&pIDispatch ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDispatch ) + return pIDispatch->GetTypeInfoCount( pctinfo ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDispatch > pIDispatch; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, (void**)&pIDispatch ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDispatch ) + return pIDispatch->GetTypeInfo( iTInfo, lcid, ppTInfo ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDispatch > pIDispatch; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, (void**)&pIDispatch ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDispatch ) + return pIDispatch->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )" ); + if ( CheckDefHandler() ) + { + ComSmart< IDispatch > pIDispatch; + HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, (void**)&pIDispatch ); + + ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIDispatch ) + return pIDispatch->Invoke( dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr ); + } + + return E_FAIL; +} + + +// ==== +// InternalCacheWrapper +// ==== + +// IUnknown +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::QueryInterface( REFIID riid, void FAR* FAR* ppv ) +{ + return m_rOwnDocument.QueryInterface( riid, ppv ); +} + +//------------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::InternalCacheWrapper::AddRef() +{ + return m_rOwnDocument.AddRef(); +} + +//------------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::InternalCacheWrapper::Release() +{ + return m_rOwnDocument.Release(); +} + +// IOleCache methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Cache( FORMATETC *pformatetc, DWORD advf, DWORD *pdwConnection ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::Cache( FORMATETC *pformatetc, DWORD advf, DWORD *pdwConnection )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache > pIOleCache; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, (void**)&pIOleCache ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache ) + return pIOleCache->Cache( pformatetc, advf, pdwConnection ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Uncache( DWORD dwConnection ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::Uncache( DWORD dwConnection )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache > pIOleCache; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, (void**)&pIOleCache ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache ) + return pIOleCache->Uncache( dwConnection ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::EnumCache( IEnumSTATDATA **ppenumSTATDATA ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::EnumCache( IEnumSTATDATA **ppenumSTATDATA )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache > pIOleCache; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, (void**)&pIOleCache ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache ) + return pIOleCache->EnumCache( ppenumSTATDATA ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::InitCache( IDataObject *pDataObject ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::InitCache( IDataObject *pDataObject )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache > pIOleCache; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, (void**)&pIOleCache ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache ) + return pIOleCache->InitCache( pDataObject ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache > pIOleCache; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, (void**)&pIOleCache ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache ) + return pIOleCache->SetData( pformatetc, pmedium, fRelease ); + } + + return E_FAIL; +} + +// IOleCache2 methods +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::UpdateCache( LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::UpdateCache( LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache2 > pIOleCache2; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache2, (void**)&pIOleCache2 ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache2 ) + return pIOleCache2->UpdateCache( pDataObject, grfUpdf, pReserved ); + } + + return E_FAIL; +} + +//------------------------------------------------------------------------------- +STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::DiscardCache( DWORD dwDiscardOptions ) +{ + WRITEDEBUGINFO( "InprocEmbedDocument_Impl::InternalCacheWrapper::DiscardCache( DWORD dwDiscardOptions )" ); + if ( m_rOwnDocument.CheckDefHandler() ) + { + ComSmart< IOleCache2 > pIOleCache2; + HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache2, (void**)&pIOleCache2 ); + + ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( SUCCEEDED( hr ) && pIOleCache2 ) + return pIOleCache2->DiscardCache( dwDiscardOptions ); + } + + return E_FAIL; +} + +}; // namespace inprocserv + diff --git a/embedserv/source/inprocserv/inprocembobj.h b/embedserv/source/inprocserv/inprocembobj.h new file mode 100644 index 000000000000..97e789dfbcd4 --- /dev/null +++ b/embedserv/source/inprocserv/inprocembobj.h @@ -0,0 +1,250 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: inprocembobj.h,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _INPROCEMBOBJ_HXX_ +#define _INPROCEMBOBJ_HXX_ + +#pragma warning(disable : 4668) + +#include <windows.h> +#include <oleidl.h> + +#include "smartpointer.hxx" +#include "advisesink.hxx" + +#define DEFAULT_ARRAY_LEN 256 + +namespace inprocserv { + +enum InitModes { + NOINIT, + INIT_FROM_STORAGE, + LOAD_FROM_STORAGE, + LOAD_FROM_FILE +}; + +// ================================== +// this is a common baseclass that is used to count the objects +// ================================== +class InprocCountedObject_Impl +{ +public: + InprocCountedObject_Impl(); + ~InprocCountedObject_Impl(); +}; + +// ================================== +// this is the inprocess embedded object implementation class +// ================================== +class InprocEmbedDocument_Impl : public InprocCountedObject_Impl + , public IOleObject + , public IDataObject + , public IPersistStorage + , public IPersistFile + , public IRunnableObject + , public IViewObject2 + // , public IExternalConnection + , public IOleInPlaceObject + , public IDispatch +{ + ULONG m_refCount; + BOOLEAN m_bDeleted; + + GUID m_guid; + + ComSmart< IUnknown > m_pDefHandler; + InitModes m_nInitMode; + + DWORD m_nFileOpenMode; + wchar_t* m_pFileName; + + ComSmart< IStorage > m_pStorage; + + ComSmart< IOleClientSite > m_pClientSite; + ComSmart< IOleContainer > m_pOleContainer; + + ULONG m_nCallsOnStack; + + // the listeners have wrappers that are directly connected to the object and call the listeners, + // the wrappers will be reconnected correctly to the new default inprocess holder object + ComSmart< OleWrapperAdviseSink > m_pOleAdvises[DEFAULT_ARRAY_LEN]; + ComSmart< OleWrapperAdviseSink > m_pDataAdvises[DEFAULT_ARRAY_LEN]; + ComSmart< OleWrapperAdviseSink > m_pViewAdvise; + + class InternalCacheWrapper : public IOleCache2 + { + InprocEmbedDocument_Impl& m_rOwnDocument; + + public: + InternalCacheWrapper( InprocEmbedDocument_Impl& rOwnDocument ) + : m_rOwnDocument( rOwnDocument ) + {} + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + /* IOleCache2 methods */ + STDMETHOD(Cache)( FORMATETC *pformatetc, DWORD advf, DWORD *pdwConnection); + STDMETHOD(Uncache)( DWORD dwConnection); + STDMETHOD(EnumCache)( IEnumSTATDATA **ppenumSTATDATA); + STDMETHOD(InitCache)( IDataObject *pDataObject); + STDMETHOD(SetData)( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease); + STDMETHOD(UpdateCache)( LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved); + STDMETHOD(DiscardCache)( DWORD dwDiscardOptions); + } m_aInternalCache; + + + DWORD InsertAdviseLinkToList( const ComSmart<OleWrapperAdviseSink>& pOwnAdvise, ComSmart< OleWrapperAdviseSink > pAdvises[] ); + void Clean(); + + +public: + + InprocEmbedDocument_Impl( const GUID& guid ) + : m_refCount( 0 ) + , m_bDeleted( FALSE ) + , m_guid( guid ) + , m_nInitMode( NOINIT ) + , m_nFileOpenMode( 0 ) + , m_pFileName( NULL ) + , m_nCallsOnStack( 0 ) + , m_aInternalCache( *this ) + {} + + virtual ~InprocEmbedDocument_Impl() + {} + + HRESULT Init(); + void SetName( LPCOLESTR pszNameFromOutside, wchar_t*& pOwnName ); + + BOOL CheckDefHandler(); + ComSmart< IUnknown >& GetDefHandler() { return m_pDefHandler; } + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + /* IOleObject methods */ + STDMETHOD(SetClientSite) ( IOleClientSite* pSite ); + STDMETHOD(GetClientSite) ( IOleClientSite** pSite ); + STDMETHOD(SetHostNames) ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj ); + STDMETHOD(Close) ( DWORD dwSaveOption); + STDMETHOD(SetMoniker) ( DWORD dwWhichMoniker, IMoniker *pmk ); + STDMETHOD(GetMoniker) ( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk ); + STDMETHOD(InitFromData) ( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved ); + STDMETHOD(GetClipboardData) ( DWORD dwReserved, IDataObject **ppDataObject ); + STDMETHOD(DoVerb) ( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect ); + STDMETHOD(EnumVerbs) ( IEnumOLEVERB **ppEnumOleVerb ); + STDMETHOD(Update) (); + STDMETHOD(IsUpToDate) (); + STDMETHOD(GetUserClassID) ( CLSID *pClsid ); + STDMETHOD(GetUserType) ( DWORD dwFormOfType, LPOLESTR *pszUserType ); + STDMETHOD(SetExtent) ( DWORD dwDrawAspect, SIZEL *psizel ); + STDMETHOD(GetExtent) ( DWORD dwDrawAspect, SIZEL *psizel ); + STDMETHOD(Advise) ( IAdviseSink *pAdvSink, DWORD *pdwConnection ); + STDMETHOD(Unadvise) ( DWORD dwConnection ); + STDMETHOD(EnumAdvise) ( IEnumSTATDATA **ppenumAdvise ); + STDMETHOD(GetMiscStatus) ( DWORD dwAspect, DWORD *pdwStatus ); + STDMETHOD(SetColorScheme) ( LOGPALETTE *pLogpal ); + + /* IDataObject methods */ + STDMETHOD(GetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium ); + STDMETHOD(GetDataHere) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium ); + STDMETHOD(QueryGetData) ( FORMATETC * pFormatetc ); + STDMETHOD(GetCanonicalFormatEtc) ( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ); + STDMETHOD(SetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease ); + STDMETHOD(EnumFormatEtc) ( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc ); + STDMETHOD(DAdvise) ( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ); + STDMETHOD(DUnadvise) ( DWORD dwConnection ); + STDMETHOD(EnumDAdvise) ( IEnumSTATDATA ** ppenumAdvise ); + + /* IPersistMethod */ + STDMETHOD(GetClassID)(CLSID *pClassID); + + /* IPersistStorage methods */ + STDMETHOD(IsDirty) (); + STDMETHOD(InitNew) ( IStorage *pStg ); + STDMETHOD(Load) ( IStorage* pStr ); + STDMETHOD(Save) ( IStorage *pStgSave, BOOL fSameAsLoad ); + STDMETHOD(SaveCompleted) ( IStorage *pStgNew ); + STDMETHOD(HandsOffStorage) (void); + + /* IPersistFile methods */ + STDMETHOD(Load) ( LPCOLESTR pszFileName, DWORD dwMode ); + STDMETHOD(Save) ( LPCOLESTR pszFileName, BOOL fRemember ); + STDMETHOD(SaveCompleted) ( LPCOLESTR pszFileName ); + STDMETHOD(GetCurFile) ( LPOLESTR *ppszFileName ); + + /* IRunnableObject methods */ + STDMETHOD(GetRunningClass) ( LPCLSID lpClsid); + STDMETHOD(Run) ( LPBINDCTX pbc); + virtual BOOL STDMETHODCALLTYPE IsRunning( void); + STDMETHOD(LockRunning) ( BOOL fLock, BOOL fLastUnlockCloses ); + STDMETHOD(SetContainedObject) ( BOOL fContained); + + /* IViewObject2 methods */ + STDMETHOD(Draw)( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue ), ULONG_PTR dwContinue); + STDMETHOD(GetColorSet)( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet); + STDMETHOD(Freeze)( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze); + STDMETHOD(Unfreeze)( DWORD dwFreeze); + STDMETHOD(SetAdvise)( DWORD aspects, DWORD advf, IAdviseSink *pAdvSink); + STDMETHOD(GetAdvise)( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink); + STDMETHOD(GetExtent)( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel); + + /* IOleWindow methods */ + STDMETHOD(GetWindow)( HWND *phwnd); + STDMETHOD(ContextSensitiveHelp)( BOOL fEnterMode); + + /* IOleInPlaceObject methods */ + STDMETHOD(InPlaceDeactivate)( void); + STDMETHOD(UIDeactivate)( void); + STDMETHOD(SetObjectRects)( LPCRECT lprcPosRect, LPCRECT lprcClipRect); + STDMETHOD(ReactivateAndUndo)( void); + + /*IDispatch methods*/ + STDMETHOD(GetTypeInfoCount)( UINT *pctinfo); + STDMETHOD(GetTypeInfo)( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); + STDMETHOD(GetIDsOfNames)( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); + STDMETHOD(Invoke)( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); + +}; + +} // namespace inprocserv + +#endif + diff --git a/embedserv/source/inprocserv/makefile.mk b/embedserv/source/inprocserv/makefile.mk new file mode 100644 index 000000000000..1928b1ec42ac --- /dev/null +++ b/embedserv/source/inprocserv/makefile.mk @@ -0,0 +1,88 @@ +#************************************************************************* +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.8.2 $ +# +# last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ +# +# The Contents of this file are made available subject to +# the terms of GNU Lesser General Public License Version 2.1. +# +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2005 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=embedserv +TARGET=inprocserv + +use_shl_versions= + +# --- Settings ---------------------------------- +.INCLUDE : settings.mk + +.IF "$(GUI)" == "WNT" + +LIBTARGET=NO +USE_DEFFILE=YES +LIBCMT=libcmt.lib +UWINAPILIB= + +# --- Files ------------------------------------- + +SLOFILES=\ + $(SLO)$/dllentry.obj \ + $(SLO)$/advisesink.obj \ + $(SLO)$/inprocembobj.obj + +SHL1TARGET=$(TARGET) +.IF "$(COM)"=="GCC" +SHL1STDLIBS += -lstdc++ +.IF "$(MINGW_GCCLIB_EH)"=="YES" +SHL1STDLIBS += -lgcc_eh +.ENDIF +SHL1STDLIBS += -lgcc -lmingw32 -lmoldname -lmsvcrt +.ELSE +SHL1STDLIBS= +.ENDIF + +SHL1STDLIBS+=\ + $(UUIDLIB)\ + $(OLE32LIB)\ + $(GDI32LIB)\ + $(ADVAPI32LIB) + +SHL1OBJS=$(SLOFILES) + +SHL1DEF=$(MISC)$/$(TARGET).def + +DEF1NAME= $(TARGET) +DEF1EXPORTFILE= exports.dxp + +.ENDIF + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/embedserv/source/inprocserv/smartpointer.hxx b/embedserv/source/inprocserv/smartpointer.hxx new file mode 100644 index 000000000000..ff40cedc30bf --- /dev/null +++ b/embedserv/source/inprocserv/smartpointer.hxx @@ -0,0 +1,205 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: smartpointer.hxx,v $ + * + * $Revision: 1.1.8.2 $ + * + * last change: $Author: mav $ $Date: 2008/10/30 11:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _INPROCSERV_SMARTPOINTER_HXX_ +#define _INPROCSERV_SMARTPOINTER_HXX_ + +// #define OWNDEBUG + +#ifdef OWNDEBUG +#define WRITEDEBUGINFOINTERN( x ) WriteDebugInfo( (DWORD)this, x, sizeof( x ) ) +#define WRITEDEBUGINFO( x ) WRITEDEBUGINFOINTERN( x ":" MY_STRING_LINE "\n" ) +#define TO_STRING( x ) #x +#define MACRO_VALUE_TO_STRING( x ) TO_STRING( x ) +#define MY_STRING_LINE MACRO_VALUE_TO_STRING( __LINE__ ) +#else +#define WRITEDEBUGINFO( x ) void() +#define MY_STRING_LINE +#endif + + +namespace inprocserv{ + +void WriteDebugInfo( DWORD pThis, char* pString, DWORD nToWrite ); + +template< class T > class ComSmart +{ + T* m_pInterface; + + void OwnRelease() + { + if ( m_pInterface ) + { + T* pInterface = m_pInterface; + m_pInterface = NULL; + pInterface->Release(); + } + } + +public: + ComSmart() + : m_pInterface( NULL ) + {} + + ComSmart( const ComSmart<T>& rObj ) + : m_pInterface( rObj.m_pInterface ) + { + if ( m_pInterface != NULL ) + m_pInterface->AddRef(); + } + + ComSmart( T* pInterface ) + : m_pInterface( pInterface ) + { + if ( m_pInterface != NULL ) + m_pInterface->AddRef(); + } + + ~ComSmart() + { + OwnRelease(); + } + + ComSmart& operator=( const ComSmart<T>& rObj ) + { + OwnRelease(); + + m_pInterface = rObj.m_pInterface; + + if ( m_pInterface != NULL ) + m_pInterface->AddRef(); + + return *this; + } + + ComSmart<T>& operator=( T* pInterface ) + { + OwnRelease(); + + m_pInterface = pInterface; + + if ( m_pInterface != NULL ) + m_pInterface->AddRef(); + + return *this; + } + + operator T*() const + { + return m_pInterface; + } + + T& operator*() const + { + return *m_pInterface; + } + + T** operator&() + { + OwnRelease(); + + m_pInterface = NULL; + + return &m_pInterface; + } + + T* operator->() const + { + return m_pInterface; + } + + BOOL operator==( const ComSmart<T>& rObj ) const + { + return ( m_pInterface == rObj.m_pInterface ); + } + + BOOL operator!=( const ComSmart<T>& rObj ) const + { + return ( m_pInterface != rObj.m_pInterface ); + } + + BOOL operator==( const T* pInterface ) const + { + return ( m_pInterface == pInterface ); + } + + BOOL operator!=( const T* pInterface ) const + { + return ( m_pInterface != pInterface ); + } +}; + +class CSGuard +{ + CRITICAL_SECTION* m_pCriticalSection; + +public: + CSGuard( CRITICAL_SECTION* pCS ) + : m_pCriticalSection( pCS ) + { + if ( m_pCriticalSection ) + EnterCriticalSection( m_pCriticalSection ); + } + + ~CSGuard() + { + if ( m_pCriticalSection ) + LeaveCriticalSection( m_pCriticalSection ); + } +}; + +class ULONGGuard +{ + ULONG* m_pValue; + +public: + ULONGGuard( ULONG* pValue ) + : m_pValue( pValue ) + { + if ( m_pValue ) + (*m_pValue)++; + } + + ~ULONGGuard() + { + if ( m_pValue ) + (*m_pValue)--; + } +}; + +} // namespace inprocserv + +#endif + |