Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / embedserv / source / embed / ed_ioleobject.cxx
blob3a79799231df58583d1102e6fa95ddbf51e3355b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/frame/XController.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
26 using namespace ::com::sun::star;
29 extern OUString getFilterNameFromGUID_Impl( GUID* );
32 // IOleObject
35 STDMETHODIMP EmbedDocument_Impl::SetClientSite( IOleClientSite* pSite )
37 m_pClientSite = pSite;
38 return S_OK;
41 STDMETHODIMP EmbedDocument_Impl::GetClientSite( IOleClientSite** pSite )
43 *pSite = m_pClientSite;
44 return S_OK;
47 STDMETHODIMP EmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )
49 // the code should be ignored for links
50 if ( !m_aFileName.getLength() )
52 m_pDocHolder->setTitle(
53 OUString(
54 (sal_Unicode*)szContainerObj));
55 m_pDocHolder->setContainerName(
56 OUString(
57 (sal_Unicode*)szContainerApp));
60 return S_OK;
63 STDMETHODIMP EmbedDocument_Impl::Close( DWORD dwSaveOption )
65 HRESULT hr = S_OK;
67 if ( m_pDocHolder->HasFrame() )
69 if ( dwSaveOption == 2 && m_aFileName.getLength() )
71 // ask the user about saving
72 if ( m_pDocHolder->ExecuteSuspendCloseFrame() )
74 m_pDocHolder->CloseDocument();
75 return S_OK;
77 else
78 return OLE_E_PROMPTSAVECANCELLED;
81 if ( dwSaveOption != 1 )
82 hr = SaveObject(); // ADVF_DATAONSTOP);
84 m_pDocHolder->CloseFrame();
85 OLENotifyDeactivation();
88 m_pDocHolder->FreeOffice();
89 m_pDocHolder->CloseDocument();
91 OLENotifyClosing();
93 return hr;
97 HRESULT EmbedDocument_Impl::OLENotifyClosing()
99 HRESULT hr = S_OK;
101 AdviseSinkHashMap aAHM(m_aAdviseHashMap);
103 for ( AdviseSinkHashMapIterator iAdvise = aAHM.begin();
104 iAdvise != aAHM.end(); iAdvise++ )
106 if ( iAdvise->second )
107 iAdvise->second->OnClose();
110 return hr;
114 STDMETHODIMP EmbedDocument_Impl::SetMoniker( DWORD /*dwWhichMoniker*/, IMoniker * /*pmk*/ )
116 return E_NOTIMPL;
119 STDMETHODIMP EmbedDocument_Impl::GetMoniker( DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker ** /*ppmk*/ )
121 return E_NOTIMPL;
124 STDMETHODIMP EmbedDocument_Impl::InitFromData( IDataObject * /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/ )
126 return E_NOTIMPL;
129 STDMETHODIMP EmbedDocument_Impl::GetClipboardData( DWORD /*dwReserved*/, IDataObject ** /*ppDataObject*/ )
131 return E_NOTIMPL;
135 * Well, this is a not so very inefficient way to deliver
139 STDMETHODIMP EmbedDocument_Impl::DoVerb(
140 LONG iVerb,
141 LPMSG,
142 IOleClientSite *pActiveSite,
143 LONG,
144 HWND,
145 LPCRECT )
147 // no locking is used since the OLE must use the same thread always
148 if ( m_bIsInVerbHandling )
149 return OLEOBJ_S_CANNOT_DOVERB_NOW;
151 // an object can not handle any Verbs in Hands off mode
152 if ( m_pMasterStorage == NULL || m_pOwnStream == NULL )
153 return OLE_E_CANT_BINDTOSOURCE;
156 BooleanGuard_Impl aGuard( m_bIsInVerbHandling );
158 if ( iVerb == OLEIVERB_PRIMARY )
160 if ( m_aFileName.getLength() )
162 // that should be a link
163 iVerb = OLEIVERB_OPEN;
165 else
166 iVerb = OLEIVERB_SHOW;
171 switch(iVerb) {
172 case OLEIVERB_DISCARDUNDOSTATE:
173 // free any undostate?
174 break;
175 case OLEIVERB_INPLACEACTIVATE:
176 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
178 return m_pDocHolder->InPlaceActivate(pActiveSite,FALSE);
179 case OLEIVERB_UIACTIVATE:
180 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
182 return m_pDocHolder->InPlaceActivate(pActiveSite,TRUE);
183 case OLEIVERB_PRIMARY:
184 case OLEIVERB_SHOW:
185 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
187 if(m_pDocHolder->isActive())
188 return NOERROR; //Already active
190 if(SUCCEEDED(
191 m_pDocHolder->InPlaceActivate(
192 pActiveSite,TRUE)))
193 return NOERROR;
195 SAL_FALLTHROUGH;
196 case OLEIVERB_OPEN:
197 OSL_ENSURE(m_pDocHolder,"no document to open");
199 // the commented code could be useful in case
200 // outer window would be resized depending from inner one
201 // RECTL aEmbArea;
202 // m_pDocHolder->GetVisArea( &aEmbArea );
203 // m_pDocHolder->show();
204 // m_pDocHolder->SetVisArea( &aEmbArea );
206 if(m_pDocHolder->isActive())
208 m_pDocHolder->InPlaceDeactivate();
209 m_pDocHolder->DisableInplaceActivation(true);
212 SIZEL aEmbSize;
213 m_pDocHolder->GetExtent( &aEmbSize );
214 m_pDocHolder->show();
215 m_pDocHolder->resizeWin( aEmbSize );
217 if ( m_pClientSite )
218 m_pClientSite->OnShowWindow( TRUE );
220 notify();
221 break;
222 case OLEIVERB_HIDE:
223 OSL_ENSURE(m_pDocHolder,"no document to hide");
225 if(m_pDocHolder->isActive())
226 m_pDocHolder->InPlaceDeactivate();
227 else {
228 m_pDocHolder->hide();
230 if( m_pClientSite )
231 m_pClientSite->OnShowWindow(FALSE);
233 break;
234 default:
235 break;
238 catch( const uno::Exception& )
240 return OLEOBJ_S_CANNOT_DOVERB_NOW;
243 return NOERROR;
247 STDMETHODIMP EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** /*ppEnumOleVerb*/ )
249 return OLE_S_USEREG;
252 STDMETHODIMP EmbedDocument_Impl::Update()
254 return S_OK;
255 // HRESULT hr = CACHE_E_NOCACHE_UPDATED;
256 // return hr;
259 STDMETHODIMP EmbedDocument_Impl::IsUpToDate()
261 return S_OK;
264 STDMETHODIMP EmbedDocument_Impl::GetUserClassID( CLSID *pClsid )
266 return GetClassID( pClsid );
269 STDMETHODIMP EmbedDocument_Impl::GetUserType( DWORD /*dwFormOfTypeUe*/, LPOLESTR * /*pszUserType*/ )
271 return OLE_S_USEREG;
274 STDMETHODIMP EmbedDocument_Impl::SetExtent( DWORD /*dwDrawAspect*/, SIZEL *psizel )
276 if ( !psizel )
277 return E_FAIL;
279 m_pDocHolder->SetExtent( psizel );
281 return S_OK;
284 STDMETHODIMP EmbedDocument_Impl::GetExtent( DWORD /*dwDrawAspect*/, SIZEL * psizel )
286 if ( !psizel )
287 return E_INVALIDARG;
289 if ( FAILED( m_pDocHolder->GetExtent( psizel ) ) )
291 // return default values
292 psizel->cx = 500;
293 psizel->cy = 500;
296 return S_OK;
299 STDMETHODIMP EmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )
301 if ( m_nAdviseNum == 0xFFFFFFFF )
302 return E_OUTOFMEMORY;
304 pAdvSink->AddRef();
305 m_aAdviseHashMap.insert( ::std::pair< DWORD, IAdviseSink* >( m_nAdviseNum, pAdvSink ) );
306 *pdwConnection = m_nAdviseNum++;
308 return S_OK;
311 STDMETHODIMP EmbedDocument_Impl::Unadvise( DWORD dwConnection )
313 AdviseSinkHashMapIterator iAdvise = m_aAdviseHashMap.find( dwConnection );
314 if ( iAdvise != m_aAdviseHashMap.end() )
316 iAdvise->second->Release();
317 m_aAdviseHashMap.erase( iAdvise );
319 else
320 return OLE_E_NOCONNECTION;
322 return S_OK;
325 STDMETHODIMP EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ )
327 return E_NOTIMPL;
330 STDMETHODIMP EmbedDocument_Impl::GetMiscStatus( DWORD /*dwAspect*/, DWORD * /*pdwStatus*/ )
332 return OLE_S_USEREG;
335 STDMETHODIMP EmbedDocument_Impl::SetColorScheme( LOGPALETTE * /*pLogpal*/ )
337 return E_NOTIMPL;
341 // IDispatch
343 STDMETHODIMP EmbedDocument_Impl::GetTypeInfoCount( unsigned int FAR* pctinfo )
345 if ( m_pDocHolder->GetIDispatch() )
346 return m_pDocHolder->GetIDispatch()->GetTypeInfoCount( pctinfo );
348 return E_NOTIMPL;
351 STDMETHODIMP EmbedDocument_Impl::GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo )
353 if ( m_pDocHolder->GetIDispatch() )
354 return m_pDocHolder->GetIDispatch()->GetTypeInfo( iTInfo, lcid, ppTInfo );
356 return DISP_E_BADINDEX; // the only error that can be returned
359 STDMETHODIMP EmbedDocument_Impl::GetIDsOfNames( REFIID riid,
360 OLECHAR FAR* FAR* rgszNames,
361 unsigned int cNames,
362 LCID lcid,
363 DISPID FAR* rgDispId )
365 if ( m_pDocHolder->GetIDispatch() )
366 return m_pDocHolder->GetIDispatch()->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
368 for ( unsigned int ind = 0; ind < cNames; ind++ )
369 rgDispId[ind] = DISPID_UNKNOWN;
371 return DISP_E_UNKNOWNNAME;
374 STDMETHODIMP EmbedDocument_Impl::Invoke( DISPID dispIdMember,
375 REFIID riid,
376 LCID lcid,
377 WORD wFlags,
378 DISPPARAMS FAR* pDispParams,
379 VARIANT FAR* pVarResult,
380 EXCEPINFO FAR* pExcepInfo,
381 unsigned int FAR* puArgErr )
383 if ( m_pDocHolder->GetIDispatch() )
384 return m_pDocHolder->GetIDispatch()->Invoke( dispIdMember,
385 riid,
386 lcid,
387 wFlags,
388 pDispParams,
389 pVarResult,
390 pExcepInfo,
391 puArgErr );
393 return DISP_E_MEMBERNOTFOUND;
397 // IExternalConnection
399 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::AddConnection( DWORD , DWORD )
401 return AddRef();
404 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::ReleaseConnection( DWORD , DWORD , BOOL )
406 return Release();
409 // C++ - methods
411 HRESULT EmbedDocument_Impl::SaveObject()
413 HRESULT hr = S_OK;
415 if(m_pClientSite) {
416 hr = m_pClientSite->SaveObject();
418 for ( AdviseSinkHashMapIterator iAdvise =
419 m_aAdviseHashMap.begin();
420 iAdvise != m_aAdviseHashMap.end();
421 iAdvise++ )
422 if ( iAdvise->second )
423 iAdvise->second->OnSave( );
425 else if ( m_aFileName.getLength() && IsDirty() == S_OK )
427 OUString aPreservFileName = m_aFileName;
429 // in case of links the containers does not provide client site sometimes
430 hr = Save( (LPCOLESTR)NULL, FALSE ); // triggers saving to the link location
431 SaveCompleted( (LPCOLESTR)aPreservFileName.getStr() );
434 notify( false );
436 return hr;
440 HRESULT EmbedDocument_Impl::ShowObject()
442 HRESULT hr = S_OK;
444 if(m_pClientSite)
445 hr = m_pClientSite->ShowObject();
447 return hr;
451 void EmbedDocument_Impl::notify( bool bDataChanged )
453 for ( AdviseSinkHashMapIterator iAdvise =
454 m_aAdviseHashMap.begin();
455 iAdvise != m_aAdviseHashMap.end();
456 iAdvise++ )
457 if ( iAdvise->second )
458 iAdvise->second->OnViewChange( DVASPECT_CONTENT, -1 );
460 if ( m_pDAdviseHolder && bDataChanged )
461 m_pDAdviseHolder->SendOnDataChange( (IDataObject*)this, 0, 0 );
464 void EmbedDocument_Impl::Deactivate()
466 HRESULT hr = S_OK;
468 if ( m_pDocHolder->HasFrame() )
470 hr = SaveObject();
471 m_pDocHolder->CloseFrame();
472 OLENotifyDeactivation();
476 HRESULT EmbedDocument_Impl::OLENotifyDeactivation()
478 HRESULT hr = S_OK;
480 if ( m_pClientSite )
481 hr = m_pClientSite->OnShowWindow( FALSE );
483 return hr;
487 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */