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