1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <embeddoc.hxx>
21 #include <osl/diagnose.h>
22 #include <o3tl/char16_t2wchar_t.hxx>
23 #include <com/sun/star/beans/PropertyValue.hpp>
26 using namespace ::com::sun::star
;
31 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::SetClientSite( IOleClientSite
* pSite
)
33 m_pClientSite
= pSite
;
37 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetClientSite( IOleClientSite
** pSite
)
39 *pSite
= m_pClientSite
;
43 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp
, LPCOLESTR szContainerObj
)
45 // the code should be ignored for links
46 if ( !m_aFileName
.getLength() )
48 m_pDocHolder
->setTitle(OUString(o3tl::toU(szContainerObj
)));
49 m_pDocHolder
->setContainerName(OUString(o3tl::toU(szContainerApp
)));
55 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::Close( DWORD dwSaveOption
)
59 if ( m_pDocHolder
->HasFrame() )
61 if ( dwSaveOption
== 2 && m_aFileName
.getLength() )
63 // ask the user about saving
64 if ( m_pDocHolder
->ExecuteSuspendCloseFrame() )
66 m_pDocHolder
->CloseDocument();
70 return OLE_E_PROMPTSAVECANCELLED
;
73 if ( dwSaveOption
!= 1 )
74 hr
= SaveObject(); // ADVF_DATAONSTOP);
76 m_pDocHolder
->CloseFrame();
77 OLENotifyDeactivation();
80 m_pDocHolder
->FreeOffice();
81 m_pDocHolder
->CloseDocument();
89 HRESULT
EmbedDocument_Impl::OLENotifyClosing()
91 AdviseSinkHashMap
aAHM(m_aAdviseHashMap
);
93 for (auto const& advise
: aAHM
)
96 advise
.second
->OnClose();
103 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::SetMoniker( DWORD
/*dwWhichMoniker*/, IMoniker
* /*pmk*/ )
108 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetMoniker( DWORD
/*dwAssign*/, DWORD
/*dwWhichMoniker*/, IMoniker
** /*ppmk*/ )
113 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::InitFromData( IDataObject
* /*pDataObject*/, BOOL
/*fCreation*/, DWORD
/*dwReserved*/ )
118 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetClipboardData( DWORD
/*dwReserved*/, IDataObject
** /*ppDataObject*/ )
124 * Well, this is a not so very inefficient way to deliver
128 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::DoVerb(
131 IOleClientSite
*pActiveSite
,
136 // no locking is used since the OLE must use the same thread always
137 if ( m_bIsInVerbHandling
)
138 return OLEOBJ_S_CANNOT_DOVERB_NOW
;
140 // an object can not handle any Verbs in Hands off mode
141 if ( m_pMasterStorage
== nullptr || m_pOwnStream
== nullptr )
142 return OLE_E_CANT_BINDTOSOURCE
;
145 BooleanGuard_Impl
aGuard( m_bIsInVerbHandling
);
147 if ( iVerb
== OLEIVERB_PRIMARY
)
149 if ( m_aFileName
.getLength() )
151 // that should be a link
152 iVerb
= OLEIVERB_OPEN
;
155 iVerb
= OLEIVERB_SHOW
;
161 case OLEIVERB_DISCARDUNDOSTATE
:
162 // free any undostate?
164 case OLEIVERB_INPLACEACTIVATE
:
165 OSL_ENSURE(m_pDocHolder
,"no document for inplace activation");
167 return m_pDocHolder
->InPlaceActivate(pActiveSite
,FALSE
);
168 case OLEIVERB_UIACTIVATE
:
169 OSL_ENSURE(m_pDocHolder
,"no document for inplace activation");
171 return m_pDocHolder
->InPlaceActivate(pActiveSite
,TRUE
);
172 case OLEIVERB_PRIMARY
:
174 OSL_ENSURE(m_pDocHolder
,"no document for inplace activation");
176 if(m_pDocHolder
->isActive())
177 return NOERROR
; //Already active
180 m_pDocHolder
->InPlaceActivate(
186 OSL_ENSURE(m_pDocHolder
,"no document to open");
188 // the commented code could be useful in case
189 // outer window would be resized depending from inner one
191 // m_pDocHolder->GetVisArea( &aEmbArea );
192 // m_pDocHolder->show();
193 // m_pDocHolder->SetVisArea( &aEmbArea );
195 if(m_pDocHolder
->isActive())
197 m_pDocHolder
->InPlaceDeactivate();
198 m_pDocHolder
->DisableInplaceActivation(true);
202 m_pDocHolder
->GetExtent( &aEmbSize
);
203 m_pDocHolder
->show();
204 m_pDocHolder
->resizeWin( aEmbSize
);
207 m_pClientSite
->OnShowWindow( TRUE
);
212 OSL_ENSURE(m_pDocHolder
,"no document to hide");
214 if(m_pDocHolder
->isActive())
215 m_pDocHolder
->InPlaceDeactivate();
217 m_pDocHolder
->hide();
220 m_pClientSite
->OnShowWindow(FALSE
);
227 catch( const uno::Exception
& )
229 return OLEOBJ_S_CANNOT_DOVERB_NOW
;
236 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB
** /*ppEnumOleVerb*/ )
241 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::Update()
244 // HRESULT hr = CACHE_E_NOCACHE_UPDATED;
248 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::IsUpToDate()
253 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetUserClassID( CLSID
*pClsid
)
255 return GetClassID( pClsid
);
258 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetUserType( DWORD
/*dwFormOfTypeUe*/, LPOLESTR
* /*pszUserType*/ )
263 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::SetExtent( DWORD
/*dwDrawAspect*/, SIZEL
*psizel
)
268 m_pDocHolder
->SetExtent( psizel
);
273 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetExtent( DWORD
/*dwDrawAspect*/, SIZEL
* psizel
)
278 if ( FAILED( m_pDocHolder
->GetExtent( psizel
) ) )
280 // return default values
288 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::Advise( IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
290 if ( m_nAdviseNum
== 0xFFFFFFFF )
291 return E_OUTOFMEMORY
;
294 m_aAdviseHashMap
.insert( std::pair
< DWORD
, IAdviseSink
* >( m_nAdviseNum
, pAdvSink
) );
295 *pdwConnection
= m_nAdviseNum
++;
300 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::Unadvise( DWORD dwConnection
)
302 auto iAdvise
= m_aAdviseHashMap
.find( dwConnection
);
303 if ( iAdvise
!= m_aAdviseHashMap
.end() )
305 iAdvise
->second
->Release();
306 m_aAdviseHashMap
.erase( iAdvise
);
309 return OLE_E_NOCONNECTION
;
314 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA
** /*ppenumAdvise*/ )
319 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetMiscStatus( DWORD
/*dwAspect*/, DWORD
* /*pdwStatus*/ )
324 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::SetColorScheme( LOGPALETTE
* /*pLogpal*/ )
332 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetTypeInfoCount(unsigned int* pctinfo
)
334 if ( m_pDocHolder
->GetIDispatch() )
335 return m_pDocHolder
->GetIDispatch()->GetTypeInfoCount( pctinfo
);
340 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetTypeInfo(unsigned int iTInfo
, LCID lcid
,
343 if ( m_pDocHolder
->GetIDispatch() )
344 return m_pDocHolder
->GetIDispatch()->GetTypeInfo( iTInfo
, lcid
, ppTInfo
);
346 return DISP_E_BADINDEX
; // the only error that can be returned
349 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::GetIDsOfNames( REFIID riid
,
355 if ( m_pDocHolder
->GetIDispatch() )
356 return m_pDocHolder
->GetIDispatch()->GetIDsOfNames( riid
, rgszNames
, cNames
, lcid
, rgDispId
);
358 for ( unsigned int ind
= 0; ind
< cNames
; ind
++ )
359 rgDispId
[ind
] = DISPID_UNKNOWN
;
361 return DISP_E_UNKNOWNNAME
;
364 COM_DECLSPEC_NOTHROW STDMETHODIMP
EmbedDocument_Impl::Invoke( DISPID dispIdMember
,
368 DISPPARAMS
* pDispParams
,
370 EXCEPINFO
* pExcepInfo
,
371 unsigned int* puArgErr
)
373 if ( m_pDocHolder
->GetIDispatch() )
374 return m_pDocHolder
->GetIDispatch()->Invoke( dispIdMember
,
383 return DISP_E_MEMBERNOTFOUND
;
387 // IExternalConnection
389 DWORD STDMETHODCALLTYPE
EmbedDocument_Impl::AddConnection( DWORD
, DWORD
)
394 DWORD STDMETHODCALLTYPE
EmbedDocument_Impl::ReleaseConnection( DWORD
, DWORD
, BOOL
)
401 HRESULT
EmbedDocument_Impl::SaveObject()
406 hr
= m_pClientSite
->SaveObject();
408 for (auto const& advise
: m_aAdviseHashMap
)
410 advise
.second
->OnSave();
412 else if ( m_aFileName
.getLength() && IsDirty() == S_OK
)
414 OUString aPreservFileName
= m_aFileName
;
416 // in case of links the containers does not provide client site sometimes
417 hr
= Save( static_cast<LPCOLESTR
>(nullptr), FALSE
); // triggers saving to the link location
418 SaveCompleted(o3tl::toW(aPreservFileName
.getStr()));
427 HRESULT
EmbedDocument_Impl::ShowObject()
432 hr
= m_pClientSite
->ShowObject();
438 void EmbedDocument_Impl::notify( bool bDataChanged
)
440 for (auto const& advise
: m_aAdviseHashMap
)
442 advise
.second
->OnViewChange( DVASPECT_CONTENT
, -1 );
444 if ( m_pDAdviseHolder
&& bDataChanged
)
445 m_pDAdviseHolder
->SendOnDataChange( static_cast<IDataObject
*>(this), 0, 0 );
448 void EmbedDocument_Impl::Deactivate()
450 if ( m_pDocHolder
->HasFrame() )
453 m_pDocHolder
->CloseFrame();
454 OLENotifyDeactivation();
458 HRESULT
EmbedDocument_Impl::OLENotifyDeactivation()
463 hr
= m_pClientSite
->OnShowWindow( FALSE
);
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */