update dev300-m57
[ooovba.git] / embedserv / source / embed / ed_ioleobject.cxx
blob9234e53fcb47530be54172b2382d8397b973d15d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ed_ioleobject.cxx,v $
10 * $Revision: 1.20.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "embeddoc.hxx"
32 #include <osl/diagnose.h>
33 #include <com/sun/star/frame/XController.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
37 using namespace ::com::sun::star;
40 extern ::rtl::OUString getFilterNameFromGUID_Impl( GUID* );
42 //-------------------------------------------------------------------------------
43 // IOleObject
46 STDMETHODIMP EmbedDocument_Impl::SetClientSite( IOleClientSite* pSite )
48 m_pClientSite = pSite;
49 return S_OK;
52 STDMETHODIMP EmbedDocument_Impl::GetClientSite( IOleClientSite** pSite )
54 *pSite = m_pClientSite;
55 return S_OK;
58 STDMETHODIMP EmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )
60 // the code should be ignored for links
61 if ( !m_aFileName.getLength() )
63 m_pDocHolder->setTitle(
64 rtl::OUString(
65 (sal_Unicode*)szContainerObj));
66 m_pDocHolder->setContainerName(
67 rtl::OUString(
68 (sal_Unicode*)szContainerApp));
71 return S_OK;
74 STDMETHODIMP EmbedDocument_Impl::Close( DWORD dwSaveOption )
76 HRESULT hr = S_OK;
78 if ( m_pDocHolder->HasFrame() )
80 if ( dwSaveOption == 2 && m_aFileName.getLength() )
82 // ask the user about saving
83 if ( m_pDocHolder->ExecuteSuspendCloseFrame() )
85 m_pDocHolder->CloseDocument();
86 return S_OK;
88 else
89 return OLE_E_PROMPTSAVECANCELLED;
92 if ( dwSaveOption != 1 )
93 hr = SaveObject(); // ADVF_DATAONSTOP);
95 m_pDocHolder->CloseFrame();
96 OLENotifyDeactivation();
99 m_pDocHolder->FreeOffice();
100 m_pDocHolder->CloseDocument();
102 OLENotifyClosing();
104 return hr;
108 HRESULT EmbedDocument_Impl::OLENotifyClosing()
110 HRESULT hr = S_OK;
112 AdviseSinkHashMap aAHM(m_aAdviseHashMap);
114 for ( AdviseSinkHashMapIterator iAdvise = aAHM.begin();
115 iAdvise != aAHM.end(); iAdvise++ )
117 if ( iAdvise->second )
118 iAdvise->second->OnClose();
121 return hr;
125 STDMETHODIMP EmbedDocument_Impl::SetMoniker( DWORD /*dwWhichMoniker*/, IMoniker * /*pmk*/ )
127 return E_NOTIMPL;
130 STDMETHODIMP EmbedDocument_Impl::GetMoniker( DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker ** /*ppmk*/ )
132 return E_NOTIMPL;
135 STDMETHODIMP EmbedDocument_Impl::InitFromData( IDataObject * /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/ )
137 return E_NOTIMPL;
140 STDMETHODIMP EmbedDocument_Impl::GetClipboardData( DWORD /*dwReserved*/, IDataObject ** /*ppDataObject*/ )
142 return E_NOTIMPL;
146 * Well, this is a not so very inefficient way to deliver
150 STDMETHODIMP EmbedDocument_Impl::DoVerb(
151 LONG iVerb,
152 LPMSG,
153 IOleClientSite *pActiveSite,
154 LONG,
155 HWND,
156 LPCRECT )
158 // no locking is used since the OLE must use the same thread always
159 if ( m_bIsInVerbHandling )
160 return OLEOBJ_S_CANNOT_DOVERB_NOW;
162 // an object can not handle any Verbs in Hands off mode
163 if ( m_pMasterStorage == NULL || m_pOwnStream == NULL )
164 return OLE_E_CANT_BINDTOSOURCE;
167 BooleanGuard_Impl aGuard( m_bIsInVerbHandling );
169 if ( iVerb == OLEIVERB_PRIMARY )
171 if ( m_aFileName.getLength() )
173 // that should be a link
174 iVerb = OLEIVERB_OPEN;
176 else
177 iVerb = OLEIVERB_SHOW;
182 switch(iVerb) {
183 case OLEIVERB_DISCARDUNDOSTATE:
184 // free any undostate?
185 break;
186 case OLEIVERB_INPLACEACTIVATE:
187 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
189 return m_pDocHolder->InPlaceActivate(pActiveSite,FALSE);
190 break;
191 case OLEIVERB_UIACTIVATE:
192 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
194 return m_pDocHolder->InPlaceActivate(pActiveSite,TRUE);
195 break;
196 case OLEIVERB_PRIMARY:
197 case OLEIVERB_SHOW:
198 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
200 if(m_pDocHolder->isActive())
201 return NOERROR; //Already active
203 if(SUCCEEDED(
204 m_pDocHolder->InPlaceActivate(
205 pActiveSite,TRUE)))
206 return NOERROR;
208 // intended fall trough
209 case OLEIVERB_OPEN:
210 OSL_ENSURE(m_pDocHolder,"no document to open");
212 // the commented code could be usefull in case
213 // outer window would be resized depending from inner one
214 // RECTL aEmbArea;
215 // m_pDocHolder->GetVisArea( &aEmbArea );
216 // m_pDocHolder->show();
217 // m_pDocHolder->SetVisArea( &aEmbArea );
219 if(m_pDocHolder->isActive())
221 m_pDocHolder->InPlaceDeactivate();
222 m_pDocHolder->DisableInplaceActivation(true);
225 SIZEL aEmbSize;
226 m_pDocHolder->GetExtent( &aEmbSize );
227 m_pDocHolder->show();
228 m_pDocHolder->resizeWin( aEmbSize );
230 if ( m_pClientSite )
231 m_pClientSite->OnShowWindow( TRUE );
233 notify();
234 break;
235 case OLEIVERB_HIDE:
236 OSL_ENSURE(m_pDocHolder,"no document to hide");
238 if(m_pDocHolder->isActive())
239 m_pDocHolder->InPlaceDeactivate();
240 else {
241 m_pDocHolder->hide();
243 if( m_pClientSite )
244 m_pClientSite->OnShowWindow(FALSE);
246 break;
247 default:
248 break;
251 catch( uno::Exception& )
253 return OLEOBJ_S_CANNOT_DOVERB_NOW;
256 return NOERROR;
261 STDMETHODIMP EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** /*ppEnumOleVerb*/ )
263 return OLE_S_USEREG;
266 STDMETHODIMP EmbedDocument_Impl::Update()
268 return S_OK;
269 // HRESULT hr = CACHE_E_NOCACHE_UPDATED;
270 // return hr;
273 STDMETHODIMP EmbedDocument_Impl::IsUpToDate()
275 return S_OK;
278 STDMETHODIMP EmbedDocument_Impl::GetUserClassID( CLSID *pClsid )
280 return GetClassID( pClsid );
283 STDMETHODIMP EmbedDocument_Impl::GetUserType( DWORD /*dwFormOfTypeUe*/, LPOLESTR * /*pszUserType*/ )
285 return OLE_S_USEREG;
288 STDMETHODIMP EmbedDocument_Impl::SetExtent( DWORD /*dwDrawAspect*/, SIZEL *psizel )
290 if ( !psizel )
291 return E_FAIL;
293 m_pDocHolder->SetExtent( psizel );
295 return S_OK;
298 STDMETHODIMP EmbedDocument_Impl::GetExtent( DWORD /*dwDrawAspect*/, SIZEL * psizel )
300 if ( !psizel )
301 return E_INVALIDARG;
303 if ( FAILED( m_pDocHolder->GetExtent( psizel ) ) )
305 // return default values
306 psizel->cx = 500;
307 psizel->cy = 500;
310 return S_OK;
313 STDMETHODIMP EmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )
315 if ( m_nAdviseNum == 0xFFFFFFFF )
316 return E_OUTOFMEMORY;
318 pAdvSink->AddRef();
319 m_aAdviseHashMap.insert( ::std::pair< DWORD, IAdviseSink* >( m_nAdviseNum, pAdvSink ) );
320 *pdwConnection = m_nAdviseNum++;
322 return S_OK;
325 STDMETHODIMP EmbedDocument_Impl::Unadvise( DWORD dwConnection )
327 AdviseSinkHashMapIterator iAdvise = m_aAdviseHashMap.find( dwConnection );
328 if ( iAdvise != m_aAdviseHashMap.end() )
330 iAdvise->second->Release();
331 m_aAdviseHashMap.erase( iAdvise );
333 else
334 return OLE_E_NOCONNECTION;
336 return S_OK;
339 STDMETHODIMP EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ )
341 return E_NOTIMPL;
344 STDMETHODIMP EmbedDocument_Impl::GetMiscStatus( DWORD /*dwAspect*/, DWORD * /*pdwStatus*/ )
346 return OLE_S_USEREG;
349 STDMETHODIMP EmbedDocument_Impl::SetColorScheme( LOGPALETTE * /*pLogpal*/ )
351 return E_NOTIMPL;
354 //-------------------------------------------------------------------------------
355 // IDispatch
357 STDMETHODIMP EmbedDocument_Impl::GetTypeInfoCount( unsigned int FAR* pctinfo )
359 if ( m_pDocHolder->GetIDispatch() )
360 return m_pDocHolder->GetIDispatch()->GetTypeInfoCount( pctinfo );
362 return E_NOTIMPL;
365 STDMETHODIMP EmbedDocument_Impl::GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo )
367 if ( m_pDocHolder->GetIDispatch() )
368 return m_pDocHolder->GetIDispatch()->GetTypeInfo( iTInfo, lcid, ppTInfo );
370 return DISP_E_BADINDEX; // the only error that can be returned
373 STDMETHODIMP EmbedDocument_Impl::GetIDsOfNames( REFIID riid,
374 OLECHAR FAR* FAR* rgszNames,
375 unsigned int cNames,
376 LCID lcid,
377 DISPID FAR* rgDispId )
379 if ( m_pDocHolder->GetIDispatch() )
380 return m_pDocHolder->GetIDispatch()->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
382 for ( unsigned int ind = 0; ind < cNames; ind++ )
383 rgDispId[ind] = DISPID_UNKNOWN;
385 return DISP_E_UNKNOWNNAME;
388 STDMETHODIMP EmbedDocument_Impl::Invoke( DISPID dispIdMember,
389 REFIID riid,
390 LCID lcid,
391 WORD wFlags,
392 DISPPARAMS FAR* pDispParams,
393 VARIANT FAR* pVarResult,
394 EXCEPINFO FAR* pExcepInfo,
395 unsigned int FAR* puArgErr )
397 if ( m_pDocHolder->GetIDispatch() )
398 return m_pDocHolder->GetIDispatch()->Invoke( dispIdMember,
399 riid,
400 lcid,
401 wFlags,
402 pDispParams,
403 pVarResult,
404 pExcepInfo,
405 puArgErr );
407 return DISP_E_MEMBERNOTFOUND;
410 //-------------------------------------------------------------------------------
411 // IExternalConnection
413 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::AddConnection( DWORD , DWORD )
415 return AddRef();
418 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::ReleaseConnection( DWORD , DWORD , BOOL )
420 return Release();
423 // C++ - methods
425 HRESULT EmbedDocument_Impl::SaveObject()
427 HRESULT hr = S_OK;
429 if(m_pClientSite) {
430 hr = m_pClientSite->SaveObject();
432 for ( AdviseSinkHashMapIterator iAdvise =
433 m_aAdviseHashMap.begin();
434 iAdvise != m_aAdviseHashMap.end();
435 iAdvise++ )
436 if ( iAdvise->second )
437 iAdvise->second->OnSave( );
439 else if ( m_aFileName.getLength() && IsDirty() == S_OK )
441 ::rtl::OUString aPreservFileName = m_aFileName;
443 // in case of links the containers does not provide client site sometimes
444 hr = Save( (LPCOLESTR)NULL, FALSE ); // triggers saving to the link location
445 SaveCompleted( (LPCOLESTR)aPreservFileName.getStr() );
448 notify( false );
450 return hr;
454 HRESULT EmbedDocument_Impl::ShowObject()
456 HRESULT hr = S_OK;
458 if(m_pClientSite)
459 hr = m_pClientSite->ShowObject();
461 return hr;
465 void EmbedDocument_Impl::notify( bool bDataChanged )
467 for ( AdviseSinkHashMapIterator iAdvise =
468 m_aAdviseHashMap.begin();
469 iAdvise != m_aAdviseHashMap.end();
470 iAdvise++ )
471 if ( iAdvise->second )
472 iAdvise->second->OnViewChange( DVASPECT_CONTENT, -1 );
474 if ( m_pDAdviseHolder && bDataChanged )
475 m_pDAdviseHolder->SendOnDataChange( (IDataObject*)this, 0, 0 );
478 void EmbedDocument_Impl::Deactivate()
480 HRESULT hr = S_OK;
482 if ( m_pDocHolder->HasFrame() )
484 hr = SaveObject();
485 m_pDocHolder->CloseFrame();
486 OLENotifyDeactivation();
490 HRESULT EmbedDocument_Impl::OLENotifyDeactivation()
492 HRESULT hr = S_OK;
494 if ( m_pClientSite )
495 hr = m_pClientSite->OnShowWindow( FALSE );
497 return hr;
501 // Fix strange warnings about some
502 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
503 // warning C4505: 'xxx' : unreferenced local function has been removed
504 #if defined(_MSC_VER)
505 #pragma warning(disable: 4505)
506 #endif