LibreOffice Module embedserv (master) 1
ed_ioleobject.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <embeddoc.hxx>
21#include <osl/diagnose.h>
23#include <com/sun/star/beans/PropertyValue.hpp>
24
25
26using namespace ::com::sun::star;
27
28// IOleObject
29
30
31COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::SetClientSite( IOleClientSite* pSite )
32{
33 m_pClientSite = pSite;
34 return S_OK;
35}
36
37COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetClientSite( IOleClientSite** pSite )
38{
39 *pSite = m_pClientSite;
40 return S_OK;
41}
42
43COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )
44{
45 // the code should be ignored for links
46 if ( !m_aFileName.getLength() )
47 {
48 m_pDocHolder->setTitle(OUString(o3tl::toU(szContainerObj)));
49 m_pDocHolder->setContainerName(OUString(o3tl::toU(szContainerApp)));
50 }
51
52 return S_OK;
53}
54
55COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::Close( DWORD dwSaveOption )
56{
57 HRESULT hr = S_OK;
58
59 if ( m_pDocHolder->HasFrame() )
60 {
61 if ( dwSaveOption == 2 && m_aFileName.getLength() )
62 {
63 // ask the user about saving
64 if ( m_pDocHolder->ExecuteSuspendCloseFrame() )
65 {
66 m_pDocHolder->CloseDocument();
67 return S_OK;
68 }
69 else
70 return OLE_E_PROMPTSAVECANCELLED;
71 }
72
73 if ( dwSaveOption != 1 )
74 hr = SaveObject(); // ADVF_DATAONSTOP);
75
76 m_pDocHolder->CloseFrame();
78 }
79
80 m_pDocHolder->FreeOffice();
81 m_pDocHolder->CloseDocument();
82
84
85 return hr;
86}
87
88
90{
92
93 for (auto const& advise : aAHM)
94 {
95 if (advise.second)
96 advise.second->OnClose();
97 }
98
99 return S_OK;
100
101}
102
103COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::SetMoniker( DWORD /*dwWhichMoniker*/, IMoniker * /*pmk*/ )
104{
105 return E_NOTIMPL;
106}
107
108COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetMoniker( DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker ** /*ppmk*/ )
109{
110 return E_NOTIMPL;
111}
112
113COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::InitFromData( IDataObject * /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/ )
114{
115 return E_NOTIMPL;
116}
117
118COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetClipboardData( DWORD /*dwReserved*/, IDataObject ** /*ppDataObject*/ )
119{
120 return E_NOTIMPL;
121}
122
128COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::DoVerb(
129 LONG iVerb,
130 LPMSG,
131 IOleClientSite *pActiveSite,
132 LONG,
133 HWND,
134 LPCRECT )
135{
136 // no locking is used since the OLE must use the same thread always
138 return OLEOBJ_S_CANNOT_DOVERB_NOW;
139
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;
143
144
146
147 if ( iVerb == OLEIVERB_PRIMARY )
148 {
149 if ( m_aFileName.getLength() )
150 {
151 // that should be a link
152 iVerb = OLEIVERB_OPEN;
153 }
154 else
155 iVerb = OLEIVERB_SHOW;
156 }
157
158 try
159 {
160 switch(iVerb) {
161 case OLEIVERB_DISCARDUNDOSTATE:
162 // free any undostate?
163 break;
164 case OLEIVERB_INPLACEACTIVATE:
165 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
166
167 return m_pDocHolder->InPlaceActivate(pActiveSite,FALSE);
168 case OLEIVERB_UIACTIVATE:
169 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
170
171 return m_pDocHolder->InPlaceActivate(pActiveSite,TRUE);
172 case OLEIVERB_PRIMARY:
173 case OLEIVERB_SHOW:
174 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
175
176 if(m_pDocHolder->isActive())
177 return NOERROR; //Already active
178
179 if(SUCCEEDED(
180 m_pDocHolder->InPlaceActivate(
181 pActiveSite,TRUE)))
182 return NOERROR;
183
184 [[fallthrough]];
185 case OLEIVERB_OPEN:
186 OSL_ENSURE(m_pDocHolder,"no document to open");
187
188 // the commented code could be useful in case
189 // outer window would be resized depending from inner one
190 // RECTL aEmbArea;
191 // m_pDocHolder->GetVisArea( &aEmbArea );
192 // m_pDocHolder->show();
193 // m_pDocHolder->SetVisArea( &aEmbArea );
194
195 if(m_pDocHolder->isActive())
196 {
197 m_pDocHolder->InPlaceDeactivate();
198 m_pDocHolder->DisableInplaceActivation(true);
199 }
200
201 SIZEL aEmbSize;
202 m_pDocHolder->GetExtent( &aEmbSize );
203 m_pDocHolder->show();
204 m_pDocHolder->resizeWin( aEmbSize );
205
206 if ( m_pClientSite )
207 m_pClientSite->OnShowWindow( TRUE );
208
209 notify();
210 break;
211 case OLEIVERB_HIDE:
212 OSL_ENSURE(m_pDocHolder,"no document to hide");
213
214 if(m_pDocHolder->isActive())
215 m_pDocHolder->InPlaceDeactivate();
216 else {
217 m_pDocHolder->hide();
218
219 if( m_pClientSite )
220 m_pClientSite->OnShowWindow(FALSE);
221 }
222 break;
223 default:
224 break;
225 }
226 }
227 catch( const uno::Exception& )
228 {
229 return OLEOBJ_S_CANNOT_DOVERB_NOW;
230 }
231
232 return NOERROR;
233}
234
235
236COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** /*ppEnumOleVerb*/ )
237{
238 return OLE_S_USEREG;
239}
240
241COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::Update()
242{
243 return S_OK;
244// HRESULT hr = CACHE_E_NOCACHE_UPDATED;
245// return hr;
246}
247
248COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::IsUpToDate()
249{
250 return S_OK;
251}
252
253COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetUserClassID( CLSID *pClsid )
254{
255 return GetClassID( pClsid );
256}
257
258COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetUserType( DWORD /*dwFormOfTypeUe*/, LPOLESTR * /*pszUserType*/ )
259{
260 return OLE_S_USEREG;
261}
262
263COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::SetExtent( DWORD /*dwDrawAspect*/, SIZEL *psizel )
264{
265 if ( !psizel )
266 return E_FAIL;
267
268 m_pDocHolder->SetExtent( psizel );
269
270 return S_OK;
271}
272
273COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetExtent( DWORD /*dwDrawAspect*/, SIZEL * psizel )
274{
275 if ( !psizel )
276 return E_INVALIDARG;
277
278 if ( FAILED( m_pDocHolder->GetExtent( psizel ) ) )
279 {
280 // return default values
281 psizel->cx = 500;
282 psizel->cy = 500;
283 }
284
285 return S_OK;
286}
287
288COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )
289{
290 if ( m_nAdviseNum == 0xFFFFFFFF )
291 return E_OUTOFMEMORY;
292
293 pAdvSink->AddRef();
294 m_aAdviseHashMap.insert( std::pair< DWORD, IAdviseSink* >( m_nAdviseNum, pAdvSink ) );
295 *pdwConnection = m_nAdviseNum++;
296
297 return S_OK;
298}
299
300COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::Unadvise( DWORD dwConnection )
301{
302 auto iAdvise = m_aAdviseHashMap.find( dwConnection );
303 if ( iAdvise != m_aAdviseHashMap.end() )
304 {
305 iAdvise->second->Release();
306 m_aAdviseHashMap.erase( iAdvise );
307 }
308 else
309 return OLE_E_NOCONNECTION;
310
311 return S_OK;
312}
313
314COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ )
315{
316 return E_NOTIMPL;
317}
318
319COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetMiscStatus( DWORD /*dwAspect*/, DWORD * /*pdwStatus*/ )
320{
321 return OLE_S_USEREG;
322}
323
324COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::SetColorScheme( LOGPALETTE * /*pLogpal*/ )
325{
326 return E_NOTIMPL;
327}
328
329
330// IDispatch
331
332COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetTypeInfoCount(unsigned int* pctinfo)
333{
334 if ( m_pDocHolder->GetIDispatch() )
335 return m_pDocHolder->GetIDispatch()->GetTypeInfoCount( pctinfo );
336
337 return E_NOTIMPL;
338}
339
340COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetTypeInfo(unsigned int iTInfo, LCID lcid,
341 ITypeInfo** ppTInfo)
342{
343 if ( m_pDocHolder->GetIDispatch() )
344 return m_pDocHolder->GetIDispatch()->GetTypeInfo( iTInfo, lcid, ppTInfo );
345
346 return DISP_E_BADINDEX; // the only error that can be returned
347}
348
349COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::GetIDsOfNames( REFIID riid,
350 OLECHAR** rgszNames,
351 unsigned int cNames,
352 LCID lcid,
353 DISPID* rgDispId )
354{
355 if ( m_pDocHolder->GetIDispatch() )
356 return m_pDocHolder->GetIDispatch()->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
357
358 for ( unsigned int ind = 0; ind < cNames; ind++ )
359 rgDispId[ind] = DISPID_UNKNOWN;
360
361 return DISP_E_UNKNOWNNAME;
362}
363
364COM_DECLSPEC_NOTHROW STDMETHODIMP EmbedDocument_Impl::Invoke( DISPID dispIdMember,
365 REFIID riid,
366 LCID lcid,
367 WORD wFlags,
368 DISPPARAMS* pDispParams,
369 VARIANT* pVarResult,
370 EXCEPINFO* pExcepInfo,
371 unsigned int* puArgErr )
372{
373 if ( m_pDocHolder->GetIDispatch() )
374 return m_pDocHolder->GetIDispatch()->Invoke( dispIdMember,
375 riid,
376 lcid,
377 wFlags,
378 pDispParams,
379 pVarResult,
380 pExcepInfo,
381 puArgErr );
382
383 return DISP_E_MEMBERNOTFOUND;
384}
385
386
387// IExternalConnection
388
389DWORD STDMETHODCALLTYPE EmbedDocument_Impl::AddConnection( DWORD , DWORD )
390{
391 return AddRef();
392}
393
394DWORD STDMETHODCALLTYPE EmbedDocument_Impl::ReleaseConnection( DWORD , DWORD , BOOL )
395{
396 return Release();
397}
398
399// C++ - methods
400
402{
403 HRESULT hr = S_OK;
404
405 if(m_pClientSite) {
406 hr = m_pClientSite->SaveObject();
407
408 for (auto const& advise : m_aAdviseHashMap)
409 if (advise.second)
410 advise.second->OnSave();
411 }
412 else if ( m_aFileName.getLength() && IsDirty() == S_OK )
413 {
414 OUString aPreservFileName = m_aFileName;
415
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()));
419 }
420
421 notify( false );
422
423 return hr;
424}
425
426
428{
429 HRESULT hr = S_OK;
430
431 if(m_pClientSite)
432 hr = m_pClientSite->ShowObject();
433
434 return hr;
435}
436
437
438void EmbedDocument_Impl::notify( bool bDataChanged )
439{
440 for (auto const& advise : m_aAdviseHashMap)
441 if (advise.second)
442 advise.second->OnViewChange( DVASPECT_CONTENT, -1 );
443
444 if ( m_pDAdviseHolder && bDataChanged )
445 m_pDAdviseHolder->SendOnDataChange( static_cast<IDataObject*>(this), 0, 0 );
446}
447
449{
450 if ( m_pDocHolder->HasFrame() )
451 {
452 SaveObject();
453 m_pDocHolder->CloseFrame();
455 }
456}
457
459{
460 HRESULT hr = S_OK;
461
462 if ( m_pClientSite )
463 hr = m_pClientSite->OnShowWindow( FALSE );
464
465 return hr;
466
467}
468
469/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
HRESULT OLENotifyClosing()
STDMETHOD() GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType) override
CComPtr< IStream > m_pOwnStream
Definition: embeddoc.hxx:159
STDMETHOD() GetClassID(CLSID *pClassID) override
STDMETHOD() DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) override
Well, this is a not so very inefficient way to deliver.
STDMETHOD() Save(IStorage *pStgSave, BOOL fSameAsLoad) override
STDMETHOD() GetClientSite(IOleClientSite **pSite) override
STDMETHOD() EnumVerbs(IEnumOLEVERB **ppEnumOleVerb) override
STDMETHOD() GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk) override
STDMETHOD() EnumAdvise(IEnumSTATDATA **ppenumAdvise) override
OUString m_aFileName
Definition: embeddoc.hxx:156
STDMETHOD() SetClientSite(IOleClientSite *pSite) override
STDMETHOD() IsDirty() override
void notify(bool bDataChanged=true)
STDMETHOD() SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj) override
HRESULT OLENotifyDeactivation()
STDMETHOD() GetIDsOfNames(REFIID riid, OLECHAR **rgszNames, unsigned int cNames, LCID lcid, DISPID *rgDispId) override
CComPtr< IOleClientSite > m_pClientSite
Definition: embeddoc.hxx:165
STDMETHOD() GetUserClassID(CLSID *pClsid) override
STDMETHOD() GetExtent(DWORD dwDrawAspect, SIZEL *psizel) override
STDMETHOD() GetTypeInfoCount(unsigned int *pctinfo) override
virtual DWORD STDMETHODCALLTYPE AddConnection(DWORD extconn, DWORD reserved) override
STDMETHOD() Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, unsigned int *puArgErr) override
STDMETHOD() Unadvise(DWORD dwConnection) override
AdviseSinkHashMap m_aAdviseHashMap
Definition: embeddoc.hxx:168
rtl::Reference< DocumentHolder > m_pDocHolder
Definition: embeddoc.hxx:155
virtual DWORD STDMETHODCALLTYPE ReleaseConnection(DWORD extconn, DWORD reserved, BOOL fLastReleaseCloses) override
STDMETHOD() SaveCompleted(IStorage *pStgNew) override
STDMETHOD() SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk) override
STDMETHOD() Update() override
STDMETHOD() GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo **ppTInfo) override
STDMETHOD() GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus) override
STDMETHOD() GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject) override
STDMETHOD() SetExtent(DWORD dwDrawAspect, SIZEL *psizel) override
CComPtr< IDataAdviseHolder > m_pDAdviseHolder
Definition: embeddoc.hxx:166
STDMETHOD() IsUpToDate() override
STDMETHOD() Close(DWORD dwSaveOption) override
STDMETHOD() SetColorScheme(LOGPALETTE *pLogpal) override
STDMETHOD() InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved) override
STDMETHOD() Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection) override
CComPtr< IStorage > m_pMasterStorage
Definition: embeddoc.hxx:158
std::unordered_map< DWORD, IAdviseSink * > AdviseSinkHashMap
Definition: embeddoc.hxx:34
#define TRUE
#define FALSE
unsigned short WORD
const wchar_t *typedef BOOL
return hr