ead7290449
Fixes #fdo30794 Based on bin/add-modelines script (originally posted in mail 1286706307.1871.1399280959@webmail.messagingengine.com) Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
506 lines
14 KiB
C++
506 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* 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
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|