Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / embedserv / source / embed / ed_ioleobject.cxx
blobf51ebda3ddc3462b9f737efb4ab5a5e1f4a1cda0
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 ::rtl::OUString getFilterNameFromGUID_Impl( GUID* );
31 //-------------------------------------------------------------------------------
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 rtl::OUString(
54 (sal_Unicode*)szContainerObj));
55 m_pDocHolder->setContainerName(
56 rtl::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 break;
180 case OLEIVERB_UIACTIVATE:
181 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
183 return m_pDocHolder->InPlaceActivate(pActiveSite,TRUE);
184 break;
185 case OLEIVERB_PRIMARY:
186 case OLEIVERB_SHOW:
187 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
189 if(m_pDocHolder->isActive())
190 return NOERROR; //Already active
192 if(SUCCEEDED(
193 m_pDocHolder->InPlaceActivate(
194 pActiveSite,TRUE)))
195 return NOERROR;
197 // intended fall trough
198 case OLEIVERB_OPEN:
199 OSL_ENSURE(m_pDocHolder,"no document to open");
201 // the commented code could be usefull in case
202 // outer window would be resized depending from inner one
203 // RECTL aEmbArea;
204 // m_pDocHolder->GetVisArea( &aEmbArea );
205 // m_pDocHolder->show();
206 // m_pDocHolder->SetVisArea( &aEmbArea );
208 if(m_pDocHolder->isActive())
210 m_pDocHolder->InPlaceDeactivate();
211 m_pDocHolder->DisableInplaceActivation(true);
214 SIZEL aEmbSize;
215 m_pDocHolder->GetExtent( &aEmbSize );
216 m_pDocHolder->show();
217 m_pDocHolder->resizeWin( aEmbSize );
219 if ( m_pClientSite )
220 m_pClientSite->OnShowWindow( TRUE );
222 notify();
223 break;
224 case OLEIVERB_HIDE:
225 OSL_ENSURE(m_pDocHolder,"no document to hide");
227 if(m_pDocHolder->isActive())
228 m_pDocHolder->InPlaceDeactivate();
229 else {
230 m_pDocHolder->hide();
232 if( m_pClientSite )
233 m_pClientSite->OnShowWindow(FALSE);
235 break;
236 default:
237 break;
240 catch( const uno::Exception& )
242 return OLEOBJ_S_CANNOT_DOVERB_NOW;
245 return NOERROR;
250 STDMETHODIMP EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** /*ppEnumOleVerb*/ )
252 return OLE_S_USEREG;
255 STDMETHODIMP EmbedDocument_Impl::Update()
257 return S_OK;
258 // HRESULT hr = CACHE_E_NOCACHE_UPDATED;
259 // return hr;
262 STDMETHODIMP EmbedDocument_Impl::IsUpToDate()
264 return S_OK;
267 STDMETHODIMP EmbedDocument_Impl::GetUserClassID( CLSID *pClsid )
269 return GetClassID( pClsid );
272 STDMETHODIMP EmbedDocument_Impl::GetUserType( DWORD /*dwFormOfTypeUe*/, LPOLESTR * /*pszUserType*/ )
274 return OLE_S_USEREG;
277 STDMETHODIMP EmbedDocument_Impl::SetExtent( DWORD /*dwDrawAspect*/, SIZEL *psizel )
279 if ( !psizel )
280 return E_FAIL;
282 m_pDocHolder->SetExtent( psizel );
284 return S_OK;
287 STDMETHODIMP EmbedDocument_Impl::GetExtent( DWORD /*dwDrawAspect*/, SIZEL * psizel )
289 if ( !psizel )
290 return E_INVALIDARG;
292 if ( FAILED( m_pDocHolder->GetExtent( psizel ) ) )
294 // return default values
295 psizel->cx = 500;
296 psizel->cy = 500;
299 return S_OK;
302 STDMETHODIMP EmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )
304 if ( m_nAdviseNum == 0xFFFFFFFF )
305 return E_OUTOFMEMORY;
307 pAdvSink->AddRef();
308 m_aAdviseHashMap.insert( ::std::pair< DWORD, IAdviseSink* >( m_nAdviseNum, pAdvSink ) );
309 *pdwConnection = m_nAdviseNum++;
311 return S_OK;
314 STDMETHODIMP EmbedDocument_Impl::Unadvise( DWORD dwConnection )
316 AdviseSinkHashMapIterator iAdvise = m_aAdviseHashMap.find( dwConnection );
317 if ( iAdvise != m_aAdviseHashMap.end() )
319 iAdvise->second->Release();
320 m_aAdviseHashMap.erase( iAdvise );
322 else
323 return OLE_E_NOCONNECTION;
325 return S_OK;
328 STDMETHODIMP EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ )
330 return E_NOTIMPL;
333 STDMETHODIMP EmbedDocument_Impl::GetMiscStatus( DWORD /*dwAspect*/, DWORD * /*pdwStatus*/ )
335 return OLE_S_USEREG;
338 STDMETHODIMP EmbedDocument_Impl::SetColorScheme( LOGPALETTE * /*pLogpal*/ )
340 return E_NOTIMPL;
343 //-------------------------------------------------------------------------------
344 // IDispatch
346 STDMETHODIMP EmbedDocument_Impl::GetTypeInfoCount( unsigned int FAR* pctinfo )
348 if ( m_pDocHolder->GetIDispatch() )
349 return m_pDocHolder->GetIDispatch()->GetTypeInfoCount( pctinfo );
351 return E_NOTIMPL;
354 STDMETHODIMP EmbedDocument_Impl::GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo )
356 if ( m_pDocHolder->GetIDispatch() )
357 return m_pDocHolder->GetIDispatch()->GetTypeInfo( iTInfo, lcid, ppTInfo );
359 return DISP_E_BADINDEX; // the only error that can be returned
362 STDMETHODIMP EmbedDocument_Impl::GetIDsOfNames( REFIID riid,
363 OLECHAR FAR* FAR* rgszNames,
364 unsigned int cNames,
365 LCID lcid,
366 DISPID FAR* rgDispId )
368 if ( m_pDocHolder->GetIDispatch() )
369 return m_pDocHolder->GetIDispatch()->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
371 for ( unsigned int ind = 0; ind < cNames; ind++ )
372 rgDispId[ind] = DISPID_UNKNOWN;
374 return DISP_E_UNKNOWNNAME;
377 STDMETHODIMP EmbedDocument_Impl::Invoke( DISPID dispIdMember,
378 REFIID riid,
379 LCID lcid,
380 WORD wFlags,
381 DISPPARAMS FAR* pDispParams,
382 VARIANT FAR* pVarResult,
383 EXCEPINFO FAR* pExcepInfo,
384 unsigned int FAR* puArgErr )
386 if ( m_pDocHolder->GetIDispatch() )
387 return m_pDocHolder->GetIDispatch()->Invoke( dispIdMember,
388 riid,
389 lcid,
390 wFlags,
391 pDispParams,
392 pVarResult,
393 pExcepInfo,
394 puArgErr );
396 return DISP_E_MEMBERNOTFOUND;
399 //-------------------------------------------------------------------------------
400 // IExternalConnection
402 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::AddConnection( DWORD , DWORD )
404 return AddRef();
407 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::ReleaseConnection( DWORD , DWORD , BOOL )
409 return Release();
412 // C++ - methods
414 HRESULT EmbedDocument_Impl::SaveObject()
416 HRESULT hr = S_OK;
418 if(m_pClientSite) {
419 hr = m_pClientSite->SaveObject();
421 for ( AdviseSinkHashMapIterator iAdvise =
422 m_aAdviseHashMap.begin();
423 iAdvise != m_aAdviseHashMap.end();
424 iAdvise++ )
425 if ( iAdvise->second )
426 iAdvise->second->OnSave( );
428 else if ( m_aFileName.getLength() && IsDirty() == S_OK )
430 ::rtl::OUString aPreservFileName = m_aFileName;
432 // in case of links the containers does not provide client site sometimes
433 hr = Save( (LPCOLESTR)NULL, FALSE ); // triggers saving to the link location
434 SaveCompleted( (LPCOLESTR)aPreservFileName.getStr() );
437 notify( false );
439 return hr;
443 HRESULT EmbedDocument_Impl::ShowObject()
445 HRESULT hr = S_OK;
447 if(m_pClientSite)
448 hr = m_pClientSite->ShowObject();
450 return hr;
454 void EmbedDocument_Impl::notify( bool bDataChanged )
456 for ( AdviseSinkHashMapIterator iAdvise =
457 m_aAdviseHashMap.begin();
458 iAdvise != m_aAdviseHashMap.end();
459 iAdvise++ )
460 if ( iAdvise->second )
461 iAdvise->second->OnViewChange( DVASPECT_CONTENT, -1 );
463 if ( m_pDAdviseHolder && bDataChanged )
464 m_pDAdviseHolder->SendOnDataChange( (IDataObject*)this, 0, 0 );
467 void EmbedDocument_Impl::Deactivate()
469 HRESULT hr = S_OK;
471 if ( m_pDocHolder->HasFrame() )
473 hr = SaveObject();
474 m_pDocHolder->CloseFrame();
475 OLENotifyDeactivation();
479 HRESULT EmbedDocument_Impl::OLENotifyDeactivation()
481 HRESULT hr = S_OK;
483 if ( m_pClientSite )
484 hr = m_pClientSite->OnShowWindow( FALSE );
486 return hr;
490 // Fix strange warnings about some
491 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
492 // warning C4505: 'xxx' : unreferenced local function has been removed
493 #if defined(_MSC_VER)
494 #pragma warning(disable: 4505)
495 #endif
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */