1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 #include "embeddoc.hxx"
23 #include <osl/diagnose.h>
24 #include <com/sun/star/frame/XController.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26
27 using namespace ::com::sun::star;
28
29 extern ::rtl::OUString getFilterNameFromGUID_Impl( GUID* );
30
31 //-------------------------------------------------------------------------------
32 // IOleObject
33
SetClientSite(IOleClientSite * pSite)34 STDMETHODIMP EmbedDocument_Impl::SetClientSite( IOleClientSite* pSite )
35 {
36 m_pClientSite = pSite;
37 return S_OK;
38 }
39
GetClientSite(IOleClientSite ** pSite)40 STDMETHODIMP EmbedDocument_Impl::GetClientSite( IOleClientSite** pSite )
41 {
42 *pSite = m_pClientSite;
43 return S_OK;
44 }
45
SetHostNames(LPCOLESTR szContainerApp,LPCOLESTR szContainerObj)46 STDMETHODIMP EmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )
47 {
48 // the code should be ignored for links
49 if ( !m_aFileName.getLength() )
50 {
51 m_pDocHolder->setTitle(
52 rtl::OUString(
53 (sal_Unicode*)szContainerObj));
54 m_pDocHolder->setContainerName(
55 rtl::OUString(
56 (sal_Unicode*)szContainerApp));
57 }
58
59 return S_OK;
60 }
61
Close(DWORD dwSaveOption)62 STDMETHODIMP EmbedDocument_Impl::Close( DWORD dwSaveOption )
63 {
64 HRESULT hr = S_OK;
65
66 if ( m_pDocHolder->HasFrame() )
67 {
68 if ( dwSaveOption == 2 && m_aFileName.getLength() )
69 {
70 // ask the user about saving
71 if ( m_pDocHolder->ExecuteSuspendCloseFrame() )
72 {
73 m_pDocHolder->CloseDocument();
74 return S_OK;
75 }
76 else
77 return OLE_E_PROMPTSAVECANCELLED;
78 }
79
80 if ( dwSaveOption != 1 )
81 hr = SaveObject(); // ADVF_DATAONSTOP);
82
83 m_pDocHolder->CloseFrame();
84 OLENotifyDeactivation();
85 }
86
87 m_pDocHolder->FreeOffice();
88 m_pDocHolder->CloseDocument();
89
90 OLENotifyClosing();
91
92 return hr;
93 }
94
95
OLENotifyClosing()96 HRESULT EmbedDocument_Impl::OLENotifyClosing()
97 {
98 HRESULT hr = S_OK;
99
100 AdviseSinkHashMap aAHM(m_aAdviseHashMap);
101
102 for ( AdviseSinkHashMapIterator iAdvise = aAHM.begin();
103 iAdvise != aAHM.end(); iAdvise++ )
104 {
105 if ( iAdvise->second )
106 iAdvise->second->OnClose();
107 }
108
109 return hr;
110
111 }
112
SetMoniker(DWORD,IMoniker *)113 STDMETHODIMP EmbedDocument_Impl::SetMoniker( DWORD /*dwWhichMoniker*/, IMoniker * /*pmk*/ )
114 {
115 return E_NOTIMPL;
116 }
117
GetMoniker(DWORD,DWORD,IMoniker **)118 STDMETHODIMP EmbedDocument_Impl::GetMoniker( DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker ** /*ppmk*/ )
119 {
120 return E_NOTIMPL;
121 }
122
InitFromData(IDataObject *,BOOL,DWORD)123 STDMETHODIMP EmbedDocument_Impl::InitFromData( IDataObject * /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/ )
124 {
125 return E_NOTIMPL;
126 }
127
GetClipboardData(DWORD,IDataObject **)128 STDMETHODIMP EmbedDocument_Impl::GetClipboardData( DWORD /*dwReserved*/, IDataObject ** /*ppDataObject*/ )
129 {
130 return E_NOTIMPL;
131 }
132
133 /**
134 * Well, this is a not so very inefficient way to deliver
135 *
136 */
137
DoVerb(LONG iVerb,LPMSG,IOleClientSite * pActiveSite,LONG,HWND,LPCRECT)138 STDMETHODIMP EmbedDocument_Impl::DoVerb(
139 LONG iVerb,
140 LPMSG,
141 IOleClientSite *pActiveSite,
142 LONG,
143 HWND,
144 LPCRECT )
145 {
146 // no locking is used since the OLE must use the same thread always
147 if ( m_bIsInVerbHandling )
148 return OLEOBJ_S_CANNOT_DOVERB_NOW;
149
150 // an object can not handle any Verbs in Hands off mode
151 if ( m_pMasterStorage == NULL || m_pOwnStream == NULL )
152 return OLE_E_CANT_BINDTOSOURCE;
153
154
155 BooleanGuard_Impl aGuard( m_bIsInVerbHandling );
156
157 if ( iVerb == OLEIVERB_PRIMARY )
158 {
159 if ( m_aFileName.getLength() )
160 {
161 // that should be a link
162 iVerb = OLEIVERB_OPEN;
163 }
164 else
165 iVerb = OLEIVERB_SHOW;
166 }
167
168 try
169 {
170 switch(iVerb) {
171 case OLEIVERB_DISCARDUNDOSTATE:
172 // free any undostate?
173 break;
174 case OLEIVERB_INPLACEACTIVATE:
175 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
176
177 return m_pDocHolder->InPlaceActivate(pActiveSite,FALSE);
178 break;
179 case OLEIVERB_UIACTIVATE:
180 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
181
182 return m_pDocHolder->InPlaceActivate(pActiveSite,TRUE);
183 break;
184 case OLEIVERB_PRIMARY:
185 case OLEIVERB_SHOW:
186 OSL_ENSURE(m_pDocHolder,"no document for inplace activation");
187
188 if(m_pDocHolder->isActive())
189 return NOERROR; //Already active
190
191 if(SUCCEEDED(
192 m_pDocHolder->InPlaceActivate(
193 pActiveSite,TRUE)))
194 return NOERROR;
195
196 // intended fall through
197 case OLEIVERB_OPEN:
198 OSL_ENSURE(m_pDocHolder,"no document to open");
199
200 // the commented code could be useful in case
201 // outer window would be resized depending from inner one
202 // RECTL aEmbArea;
203 // m_pDocHolder->GetVisArea( &aEmbArea );
204 // m_pDocHolder->show();
205 // m_pDocHolder->SetVisArea( &aEmbArea );
206
207 if(m_pDocHolder->isActive())
208 {
209 m_pDocHolder->InPlaceDeactivate();
210 m_pDocHolder->DisableInplaceActivation(true);
211 }
212
213 SIZEL aEmbSize;
214 m_pDocHolder->GetExtent( &aEmbSize );
215 m_pDocHolder->show();
216 m_pDocHolder->resizeWin( aEmbSize );
217
218 if ( m_pClientSite )
219 m_pClientSite->OnShowWindow( TRUE );
220
221 notify();
222 break;
223 case OLEIVERB_HIDE:
224 OSL_ENSURE(m_pDocHolder,"no document to hide");
225
226 if(m_pDocHolder->isActive())
227 m_pDocHolder->InPlaceDeactivate();
228 else {
229 m_pDocHolder->hide();
230
231 if( m_pClientSite )
232 m_pClientSite->OnShowWindow(FALSE);
233 }
234 break;
235 default:
236 break;
237 }
238 }
239 catch( uno::Exception& )
240 {
241 return OLEOBJ_S_CANNOT_DOVERB_NOW;
242 }
243
244 return NOERROR;
245 }
246
247
248
EnumVerbs(IEnumOLEVERB **)249 STDMETHODIMP EmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** /*ppEnumOleVerb*/ )
250 {
251 return OLE_S_USEREG;
252 }
253
Update()254 STDMETHODIMP EmbedDocument_Impl::Update()
255 {
256 return S_OK;
257 // HRESULT hr = CACHE_E_NOCACHE_UPDATED;
258 // return hr;
259 }
260
IsUpToDate()261 STDMETHODIMP EmbedDocument_Impl::IsUpToDate()
262 {
263 return S_OK;
264 }
265
GetUserClassID(CLSID * pClsid)266 STDMETHODIMP EmbedDocument_Impl::GetUserClassID( CLSID *pClsid )
267 {
268 return GetClassID( pClsid );
269 }
270
GetUserType(DWORD,LPOLESTR *)271 STDMETHODIMP EmbedDocument_Impl::GetUserType( DWORD /*dwFormOfTypeUe*/, LPOLESTR * /*pszUserType*/ )
272 {
273 return OLE_S_USEREG;
274 }
275
SetExtent(DWORD,SIZEL * psizel)276 STDMETHODIMP EmbedDocument_Impl::SetExtent( DWORD /*dwDrawAspect*/, SIZEL *psizel )
277 {
278 if ( !psizel )
279 return E_FAIL;
280
281 m_pDocHolder->SetExtent( psizel );
282
283 return S_OK;
284 }
285
GetExtent(DWORD,SIZEL * psizel)286 STDMETHODIMP EmbedDocument_Impl::GetExtent( DWORD /*dwDrawAspect*/, SIZEL * psizel )
287 {
288 if ( !psizel )
289 return E_INVALIDARG;
290
291 if ( FAILED( m_pDocHolder->GetExtent( psizel ) ) )
292 {
293 // return default values
294 psizel->cx = 500;
295 psizel->cy = 500;
296 }
297
298 return S_OK;
299 }
300
Advise(IAdviseSink * pAdvSink,DWORD * pdwConnection)301 STDMETHODIMP EmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )
302 {
303 if ( m_nAdviseNum == 0xFFFFFFFF )
304 return E_OUTOFMEMORY;
305
306 pAdvSink->AddRef();
307 m_aAdviseHashMap.insert( ::std::pair< DWORD, IAdviseSink* >( m_nAdviseNum, pAdvSink ) );
308 *pdwConnection = m_nAdviseNum++;
309
310 return S_OK;
311 }
312
Unadvise(DWORD dwConnection)313 STDMETHODIMP EmbedDocument_Impl::Unadvise( DWORD dwConnection )
314 {
315 AdviseSinkHashMapIterator iAdvise = m_aAdviseHashMap.find( dwConnection );
316 if ( iAdvise != m_aAdviseHashMap.end() )
317 {
318 iAdvise->second->Release();
319 m_aAdviseHashMap.erase( iAdvise );
320 }
321 else
322 return OLE_E_NOCONNECTION;
323
324 return S_OK;
325 }
326
EnumAdvise(IEnumSTATDATA **)327 STDMETHODIMP EmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ )
328 {
329 return E_NOTIMPL;
330 }
331
GetMiscStatus(DWORD,DWORD *)332 STDMETHODIMP EmbedDocument_Impl::GetMiscStatus( DWORD /*dwAspect*/, DWORD * /*pdwStatus*/ )
333 {
334 return OLE_S_USEREG;
335 }
336
SetColorScheme(LOGPALETTE *)337 STDMETHODIMP EmbedDocument_Impl::SetColorScheme( LOGPALETTE * /*pLogpal*/ )
338 {
339 return E_NOTIMPL;
340 }
341
342 //-------------------------------------------------------------------------------
343 // IDispatch
344
GetTypeInfoCount(unsigned int FAR * pctinfo)345 STDMETHODIMP EmbedDocument_Impl::GetTypeInfoCount( unsigned int FAR* pctinfo )
346 {
347 if ( m_pDocHolder->GetIDispatch() )
348 return m_pDocHolder->GetIDispatch()->GetTypeInfoCount( pctinfo );
349
350 return E_NOTIMPL;
351 }
352
GetTypeInfo(unsigned int iTInfo,LCID lcid,ITypeInfo FAR * FAR * ppTInfo)353 STDMETHODIMP EmbedDocument_Impl::GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo )
354 {
355 if ( m_pDocHolder->GetIDispatch() )
356 return m_pDocHolder->GetIDispatch()->GetTypeInfo( iTInfo, lcid, ppTInfo );
357
358 return DISP_E_BADINDEX; // the only error that can be returned
359 }
360
GetIDsOfNames(REFIID riid,OLECHAR FAR * FAR * rgszNames,unsigned int cNames,LCID lcid,DISPID FAR * rgDispId)361 STDMETHODIMP EmbedDocument_Impl::GetIDsOfNames( REFIID riid,
362 OLECHAR FAR* FAR* rgszNames,
363 unsigned int cNames,
364 LCID lcid,
365 DISPID FAR* rgDispId )
366 {
367 if ( m_pDocHolder->GetIDispatch() )
368 return m_pDocHolder->GetIDispatch()->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
369
370 for ( unsigned int ind = 0; ind < cNames; ind++ )
371 rgDispId[ind] = DISPID_UNKNOWN;
372
373 return DISP_E_UNKNOWNNAME;
374 }
375
Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR * pDispParams,VARIANT FAR * pVarResult,EXCEPINFO FAR * pExcepInfo,unsigned int FAR * puArgErr)376 STDMETHODIMP EmbedDocument_Impl::Invoke( DISPID dispIdMember,
377 REFIID riid,
378 LCID lcid,
379 WORD wFlags,
380 DISPPARAMS FAR* pDispParams,
381 VARIANT FAR* pVarResult,
382 EXCEPINFO FAR* pExcepInfo,
383 unsigned int FAR* puArgErr )
384 {
385 if ( m_pDocHolder->GetIDispatch() )
386 return m_pDocHolder->GetIDispatch()->Invoke( dispIdMember,
387 riid,
388 lcid,
389 wFlags,
390 pDispParams,
391 pVarResult,
392 pExcepInfo,
393 puArgErr );
394
395 return DISP_E_MEMBERNOTFOUND;
396 }
397
398 //-------------------------------------------------------------------------------
399 // IExternalConnection
400
AddConnection(DWORD,DWORD)401 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::AddConnection( DWORD , DWORD )
402 {
403 return AddRef();
404 }
405
ReleaseConnection(DWORD,DWORD,BOOL)406 DWORD STDMETHODCALLTYPE EmbedDocument_Impl::ReleaseConnection( DWORD , DWORD , BOOL )
407 {
408 return Release();
409 }
410
411 // C++ - methods
412
SaveObject()413 HRESULT EmbedDocument_Impl::SaveObject()
414 {
415 HRESULT hr = S_OK;
416
417 if(m_pClientSite) {
418 hr = m_pClientSite->SaveObject();
419
420 for ( AdviseSinkHashMapIterator iAdvise =
421 m_aAdviseHashMap.begin();
422 iAdvise != m_aAdviseHashMap.end();
423 iAdvise++ )
424 if ( iAdvise->second )
425 iAdvise->second->OnSave( );
426 }
427 else if ( m_aFileName.getLength() && IsDirty() == S_OK )
428 {
429 ::rtl::OUString aPreservFileName = m_aFileName;
430
431 // in case of links the containers does not provide client site sometimes
432 hr = Save( (LPCOLESTR)NULL, FALSE ); // triggers saving to the link location
433 SaveCompleted( (LPCOLESTR)aPreservFileName.getStr() );
434 }
435
436 notify( false );
437
438 return hr;
439 }
440
441
ShowObject()442 HRESULT EmbedDocument_Impl::ShowObject()
443 {
444 HRESULT hr = S_OK;
445
446 if(m_pClientSite)
447 hr = m_pClientSite->ShowObject();
448
449 return hr;
450 }
451
452
notify(bool bDataChanged)453 void EmbedDocument_Impl::notify( bool bDataChanged )
454 {
455 for ( AdviseSinkHashMapIterator iAdvise =
456 m_aAdviseHashMap.begin();
457 iAdvise != m_aAdviseHashMap.end();
458 iAdvise++ )
459 if ( iAdvise->second )
460 iAdvise->second->OnViewChange( DVASPECT_CONTENT, -1 );
461
462 if ( m_pDAdviseHolder && bDataChanged )
463 m_pDAdviseHolder->SendOnDataChange( (IDataObject*)this, 0, 0 );
464 }
465
Deactivate()466 void EmbedDocument_Impl::Deactivate()
467 {
468 HRESULT hr = S_OK;
469
470 if ( m_pDocHolder->HasFrame() )
471 {
472 hr = SaveObject();
473 m_pDocHolder->CloseFrame();
474 OLENotifyDeactivation();
475 }
476 }
477
OLENotifyDeactivation()478 HRESULT EmbedDocument_Impl::OLENotifyDeactivation()
479 {
480 HRESULT hr = S_OK;
481
482 if ( m_pClientSite )
483 hr = m_pClientSite->OnShowWindow( FALSE );
484
485 return hr;
486
487 }
488
489 // Fix strange warnings about some
490 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
491 // warning C4505: 'xxx' : unreferenced local function has been removed
492 #if defined(_MSC_VER)
493 #pragma warning(disable: 4505)
494 #endif
495
496 /* vim: set noet sw=4 ts=4: */
497