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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_embeddedobj.hxx"
26
27 #include <commonembobj.hxx>
28 #include <com/sun/star/embed/EmbedStates.hpp>
29 #include <com/sun/star/embed/EmbedVerbs.hpp>
30 #include <com/sun/star/embed/XStorage.hpp>
31 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
32 #include <com/sun/star/embed/XInplaceClient.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/beans/NamedValue.hpp>
35
36 #include <cppuhelper/typeprovider.hxx>
37 #include <cppuhelper/interfacecontainer.h>
38 #include <comphelper/mimeconfighelper.hxx>
39
40 #include "closepreventer.hxx"
41 #include "intercept.hxx"
42
43 using namespace ::com::sun::star;
44
45
46 uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
47 sal_Bool bCanUseDocumentBaseURL );
48
49 //------------------------------------------------------
OCommonEmbeddedObject(const uno::Reference<lang::XMultiServiceFactory> & xFactory,const uno::Sequence<beans::NamedValue> & aObjProps)50 OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
51 const uno::Sequence< beans::NamedValue >& aObjProps )
52 : m_pDocHolder( NULL )
53 , m_pInterfaceContainer( NULL )
54 , m_bReadOnly( sal_False )
55 , m_bDisposed( sal_False )
56 , m_bClosed( sal_False )
57 , m_nObjectState( -1 )
58 , m_nTargetState( -1 )
59 , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
60 , m_xFactory( xFactory )
61 , m_nMiscStatus( 0 )
62 , m_bEmbeddedScriptSupport( sal_True )
63 , m_bDocumentRecoverySupport( sal_True )
64 , m_bWaitSaveCompleted( sal_False )
65 , m_bIsLink( sal_False )
66 , m_bLinkHasPassword( sal_False )
67 , m_bHasClonedSize( sal_False )
68 , m_nClonedMapUnit( 0 )
69 {
70 CommonInit_Impl( aObjProps );
71 }
72
73 //------------------------------------------------------
OCommonEmbeddedObject(const uno::Reference<lang::XMultiServiceFactory> & xFactory,const uno::Sequence<beans::NamedValue> & aObjProps,const uno::Sequence<beans::PropertyValue> & aMediaDescr,const uno::Sequence<beans::PropertyValue> & aObjectDescr)74 OCommonEmbeddedObject::OCommonEmbeddedObject(
75 const uno::Reference< lang::XMultiServiceFactory >& xFactory,
76 const uno::Sequence< beans::NamedValue >& aObjProps,
77 const uno::Sequence< beans::PropertyValue >& aMediaDescr,
78 const uno::Sequence< beans::PropertyValue >& aObjectDescr )
79 : m_pDocHolder( NULL )
80 , m_pInterfaceContainer( NULL )
81 , m_bReadOnly( sal_False )
82 , m_bDisposed( sal_False )
83 , m_bClosed( sal_False )
84 , m_nObjectState( embed::EmbedStates::LOADED )
85 , m_nTargetState( -1 )
86 , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
87 , m_xFactory( xFactory )
88 , m_nMiscStatus( 0 )
89 , m_bEmbeddedScriptSupport( sal_True )
90 , m_bDocumentRecoverySupport( sal_True )
91 , m_bWaitSaveCompleted( sal_False )
92 , m_bIsLink( sal_True )
93 , m_bLinkHasPassword( sal_False )
94 , m_bHasClonedSize( sal_False )
95 , m_nClonedMapUnit( 0 )
96 {
97 // linked object has no own persistence so it is in loaded state starting from creation
98 LinkInit_Impl( aObjProps, aMediaDescr, aObjectDescr );
99 }
100
101 //------------------------------------------------------
CommonInit_Impl(const uno::Sequence<beans::NamedValue> & aObjectProps)102 void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedValue >& aObjectProps )
103 {
104 OSL_ENSURE( m_xFactory.is(), "No ServiceFactory is provided!\n" );
105 if ( !m_xFactory.is() )
106 throw uno::RuntimeException();
107
108 m_pDocHolder = new DocumentHolder( m_xFactory, this );
109 m_pDocHolder->acquire();
110
111 // parse configuration entries
112 // TODO/LATER: in future UI names can be also provided here
113 for ( sal_Int32 nInd = 0; nInd < aObjectProps.getLength(); nInd++ )
114 {
115 if ( aObjectProps[nInd].Name.equalsAscii( "ClassID" ) )
116 aObjectProps[nInd].Value >>= m_aClassID;
117 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentServiceName" ) )
118 aObjectProps[nInd].Value >>= m_aDocServiceName;
119 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentFilterName" ) )
120 aObjectProps[nInd].Value >>= m_aPresetFilterName;
121 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectMiscStatus" ) )
122 aObjectProps[nInd].Value >>= m_nMiscStatus;
123 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectVerbs" ) )
124 aObjectProps[nInd].Value >>= m_aObjectVerbs;
125 }
126
127 if ( m_aClassID.getLength() != 16 /*|| !m_aDocServiceName.getLength()*/ )
128 throw uno::RuntimeException(); // something goes really wrong
129
130 // accepted states
131 m_aAcceptedStates.realloc( NUM_SUPPORTED_STATES );
132
133 m_aAcceptedStates[0] = embed::EmbedStates::LOADED;
134 m_aAcceptedStates[1] = embed::EmbedStates::RUNNING;
135 m_aAcceptedStates[2] = embed::EmbedStates::INPLACE_ACTIVE;
136 m_aAcceptedStates[3] = embed::EmbedStates::UI_ACTIVE;
137 m_aAcceptedStates[4] = embed::EmbedStates::ACTIVE;
138
139
140 // intermediate states
141 // In the following table the first index points to starting state,
142 // the second one to the target state, and the sequence referenced by
143 // first two indexes contains intermediate states, that should be
144 // passed by object to reach the target state.
145 // If the sequence is empty that means that indirect switch from start
146 // state to the target state is forbidden, only if direct switch is possible
147 // the state can be reached.
148
149 m_pIntermediateStatesSeqs[0][2].realloc( 1 );
150 m_pIntermediateStatesSeqs[0][2][0] = embed::EmbedStates::RUNNING;
151
152 m_pIntermediateStatesSeqs[0][3].realloc( 2 );
153 m_pIntermediateStatesSeqs[0][3][0] = embed::EmbedStates::RUNNING;
154 m_pIntermediateStatesSeqs[0][3][1] = embed::EmbedStates::INPLACE_ACTIVE;
155
156 m_pIntermediateStatesSeqs[0][4].realloc( 1 );
157 m_pIntermediateStatesSeqs[0][4][0] = embed::EmbedStates::RUNNING;
158
159 m_pIntermediateStatesSeqs[1][3].realloc( 1 );
160 m_pIntermediateStatesSeqs[1][3][0] = embed::EmbedStates::INPLACE_ACTIVE;
161
162 m_pIntermediateStatesSeqs[2][0].realloc( 1 );
163 m_pIntermediateStatesSeqs[2][0][0] = embed::EmbedStates::RUNNING;
164
165 m_pIntermediateStatesSeqs[3][0].realloc( 2 );
166 m_pIntermediateStatesSeqs[3][0][0] = embed::EmbedStates::INPLACE_ACTIVE;
167 m_pIntermediateStatesSeqs[3][0][1] = embed::EmbedStates::RUNNING;
168
169 m_pIntermediateStatesSeqs[3][1].realloc( 1 );
170 m_pIntermediateStatesSeqs[3][1][0] = embed::EmbedStates::INPLACE_ACTIVE;
171
172 m_pIntermediateStatesSeqs[4][0].realloc( 1 );
173 m_pIntermediateStatesSeqs[4][0][0] = embed::EmbedStates::RUNNING;
174
175 // verbs table
176 sal_Int32 nVerbTableSize = 0;
177 for ( sal_Int32 nVerbInd = 0; nVerbInd < m_aObjectVerbs.getLength(); nVerbInd++ )
178 {
179 if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_PRIMARY )
180 {
181 m_aVerbTable.realloc( ++nVerbTableSize );
182 m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
183 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
184 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
185 }
186 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_SHOW )
187 {
188 m_aVerbTable.realloc( ++nVerbTableSize );
189 m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
190 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
191 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
192 }
193 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN )
194 {
195 m_aVerbTable.realloc( ++nVerbTableSize );
196 m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
197 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
198 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::ACTIVE;
199 }
200 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_IPACTIVATE )
201 {
202 m_aVerbTable.realloc( ++nVerbTableSize );
203 m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
204 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
205 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::INPLACE_ACTIVE;
206 }
207 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_UIACTIVATE )
208 {
209 m_aVerbTable.realloc( ++nVerbTableSize );
210 m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
211 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
212 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
213 }
214 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_HIDE )
215 {
216 m_aVerbTable.realloc( ++nVerbTableSize );
217 m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
218 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
219 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::RUNNING;
220 }
221 }
222 }
223
224 //------------------------------------------------------
LinkInit_Impl(const uno::Sequence<beans::NamedValue> & aObjectProps,const uno::Sequence<beans::PropertyValue> & aMediaDescr,const uno::Sequence<beans::PropertyValue> & aObjectDescr)225 void OCommonEmbeddedObject::LinkInit_Impl(
226 const uno::Sequence< beans::NamedValue >& aObjectProps,
227 const uno::Sequence< beans::PropertyValue >& aMediaDescr,
228 const uno::Sequence< beans::PropertyValue >& aObjectDescr )
229 {
230 // setPersistance has no effect on own links, so the complete initialization must be done here
231
232 for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ )
233 if ( aMediaDescr[nInd].Name.equalsAscii( "URL" ) )
234 aMediaDescr[nInd].Value >>= m_aLinkURL;
235 else if ( aMediaDescr[nInd].Name.equalsAscii( "FilterName" ) )
236 aMediaDescr[nInd].Value >>= m_aLinkFilterName;
237
238 OSL_ENSURE( m_aLinkURL.getLength() && m_aLinkFilterName.getLength(), "Filter and URL must be provided!\n" );
239
240 m_bReadOnly = sal_True;
241 if ( m_aLinkFilterName.getLength() )
242 {
243 ::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
244 ::rtl::OUString aExportFilterName = aHelper.GetExportFilterFromImportFilter( m_aLinkFilterName );
245 m_bReadOnly = !( aExportFilterName.equals( m_aLinkFilterName ) );
246 }
247
248 m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, sal_False );
249
250 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
251 for ( sal_Int32 nObjInd = 0; nObjInd < aObjectDescr.getLength(); nObjInd++ )
252 if ( aObjectDescr[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
253 {
254 aObjectDescr[nObjInd].Value >>= xDispatchInterceptor;
255 break;
256 }
257 else if ( aObjectDescr[nObjInd].Name.equalsAscii( "Parent" ) )
258 {
259 aObjectDescr[nObjInd].Value >>= m_xParent;
260 }
261
262 CommonInit_Impl( aObjectProps );
263
264 if ( xDispatchInterceptor.is() )
265 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
266 }
267
268 //------------------------------------------------------
~OCommonEmbeddedObject()269 OCommonEmbeddedObject::~OCommonEmbeddedObject()
270 {
271 if ( m_pInterfaceContainer || m_pDocHolder )
272 {
273 m_refCount++;
274 try {
275 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
276
277 if ( m_pInterfaceContainer )
278 {
279 m_pInterfaceContainer->disposeAndClear( aSource );
280
281 delete m_pInterfaceContainer;
282 m_pInterfaceContainer = NULL;
283 }
284 } catch( uno::Exception& ) {}
285
286 try {
287 if ( m_pDocHolder )
288 {
289 m_pDocHolder->CloseFrame();
290 try {
291 m_pDocHolder->CloseDocument( sal_True, sal_True );
292 } catch ( uno::Exception& ) {}
293 m_pDocHolder->FreeOffice();
294
295 m_pDocHolder->release();
296 m_pDocHolder = NULL;
297 }
298 } catch( uno::Exception& ) {}
299 }
300 }
301
302 //------------------------------------------------------
requestPositioning(const awt::Rectangle & aRect)303 void OCommonEmbeddedObject::requestPositioning( const awt::Rectangle& aRect )
304 {
305 // the method is called in case object is inplace active and the object window was resized
306
307 OSL_ENSURE( m_xClientSite.is(), "The client site must be set for inplace active object!\n" );
308 if ( m_xClientSite.is() )
309 {
310 uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
311
312 OSL_ENSURE( xInplaceClient.is(), "The client site must support XInplaceClient to allow inplace activation!\n" );
313 if ( xInplaceClient.is() )
314 {
315 try {
316 xInplaceClient->changedPlacement( aRect );
317 }
318 catch( uno::Exception& )
319 {
320 OSL_ENSURE( sal_False, "Exception on request to resize!\n" );
321 }
322 }
323 }
324 }
325
326 //------------------------------------------------------
PostEvent_Impl(const::rtl::OUString & aEventName,const uno::Reference<uno::XInterface> &)327 void OCommonEmbeddedObject::PostEvent_Impl( const ::rtl::OUString& aEventName,
328 const uno::Reference< uno::XInterface >& /*xSource*/ )
329 {
330 if ( m_pInterfaceContainer )
331 {
332 ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer(
333 ::getCppuType((const uno::Reference< document::XEventListener >*)0) );
334 if( pIC )
335 {
336 document::EventObject aEvent;
337 aEvent.EventName = aEventName;
338 aEvent.Source = uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) );
339 // For now all the events are sent as object events
340 // aEvent.Source = ( xSource.is() ? xSource
341 // : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) );
342 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
343 while( aIt.hasMoreElements() )
344 {
345 try
346 {
347 ((document::XEventListener *)aIt.next())->notifyEvent( aEvent );
348 }
349 catch( uno::RuntimeException& )
350 {
351 aIt.remove();
352 }
353
354 // the listener could dispose the object.
355 if ( m_bDisposed )
356 return;
357 }
358 }
359 }
360 }
361
362 //------------------------------------------------------
queryInterface(const uno::Type & rType)363 uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType )
364 {
365 uno::Any aReturn;
366
367 if ( rType == ::getCppuType( (uno::Reference< embed::XEmbeddedObject > const *)0 ))
368 {
369 void * p = static_cast< embed::XEmbeddedObject * >( this );
370 return uno::Any( &p, rType );
371 }
372 else
373 aReturn <<= ::cppu::queryInterface(
374 rType,
375 static_cast< embed::XInplaceObject* >( this ),
376 static_cast< embed::XVisualObject* >( this ),
377 static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ),
378 static_cast< embed::XEmbedPersist* >( this ),
379 static_cast< embed::XLinkageSupport* >( this ),
380 static_cast< embed::XStateChangeBroadcaster* >( this ),
381 static_cast< embed::XClassifiedObject* >( this ),
382 static_cast< embed::XComponentSupplier* >( this ),
383 static_cast< util::XCloseable* >( this ),
384 static_cast< container::XChild* >( this ),
385 static_cast< chart2::XDefaultSizeTransmitter* >( this ),
386 static_cast< document::XEventBroadcaster* >( this ) );
387
388 if ( aReturn.hasValue() )
389 return aReturn;
390 else
391 return ::cppu::OWeakObject::queryInterface( rType ) ;
392
393 }
394
395 //------------------------------------------------------
acquire()396 void SAL_CALL OCommonEmbeddedObject::acquire()
397 throw()
398 {
399 ::cppu::OWeakObject::acquire() ;
400 }
401
402 //------------------------------------------------------
release()403 void SAL_CALL OCommonEmbeddedObject::release()
404 throw()
405 {
406 ::cppu::OWeakObject::release() ;
407 }
408
409 //------------------------------------------------------
getTypes()410 uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes()
411 {
412 static ::cppu::OTypeCollection* pTypeCollection = NULL;
413
414 if ( !pTypeCollection )
415 {
416 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
417 if ( !pTypeCollection )
418 {
419 if ( m_bIsLink )
420 {
421 static ::cppu::OTypeCollection aTypeCollection(
422 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ),
423 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ),
424 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ),
425 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ),
426 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ),
427 ::getCppuType( (const uno::Reference< embed::XLinkageSupport >*)NULL ) );
428
429 pTypeCollection = &aTypeCollection ;
430 }
431 else
432 {
433 static ::cppu::OTypeCollection aTypeCollection(
434 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ),
435 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ),
436 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ),
437 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ),
438 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ),
439 ::getCppuType( (const uno::Reference< embed::XEmbedPersist >*)NULL ) );
440
441 pTypeCollection = &aTypeCollection ;
442 }
443 }
444 }
445
446 return pTypeCollection->getTypes() ;
447
448 }
449
450 //------------------------------------------------------
getImplementationId()451 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getImplementationId()
452 {
453 static ::cppu::OImplementationId* pID = NULL ;
454
455 if ( !pID )
456 {
457 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
458 if ( !pID )
459 {
460 static ::cppu::OImplementationId aID( sal_False ) ;
461 pID = &aID ;
462 }
463 }
464
465 return pID->getImplementationId() ;
466 }
467
468 //------------------------------------------------------
getClassID()469 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID()
470 {
471 if ( m_bDisposed )
472 throw lang::DisposedException();
473
474 return m_aClassID;
475 }
476
477 //------------------------------------------------------
getClassName()478 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getClassName()
479 {
480 if ( m_bDisposed )
481 throw lang::DisposedException();
482
483 return m_aClassName;
484 }
485
486 //------------------------------------------------------
setClassInfo(const uno::Sequence<sal_Int8> &,const::rtl::OUString &)487 void SAL_CALL OCommonEmbeddedObject::setClassInfo(
488 const uno::Sequence< sal_Int8 >& /*aClassID*/, const ::rtl::OUString& /*aClassName*/ )
489 {
490 // the object class info can not be changed explicitly
491 throw lang::NoSupportException(); //TODO:
492 }
493
494 //------------------------------------------------------
getComponent()495 uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent()
496 {
497 ::osl::MutexGuard aGuard( m_aMutex );
498 if ( m_bDisposed )
499 throw lang::DisposedException(); // TODO
500
501 // add an exception
502 if ( m_nObjectState == -1 )
503 {
504 // the object is still not loaded
505 throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
506 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
507 }
508
509 // if ( m_bWaitSaveCompleted )
510 // throw embed::WrongStateException(
511 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
512 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );
513
514 return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
515 }
516
517 //----------------------------------------------
addStateChangeListener(const uno::Reference<embed::XStateChangeListener> & xListener)518 void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener )
519 {
520 ::osl::MutexGuard aGuard( m_aMutex );
521 if ( m_bDisposed )
522 throw lang::DisposedException(); // TODO
523
524 if ( !m_pInterfaceContainer )
525 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
526
527 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ),
528 xListener );
529 }
530
531 //----------------------------------------------
removeStateChangeListener(const uno::Reference<embed::XStateChangeListener> & xListener)532 void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener(
533 const uno::Reference< embed::XStateChangeListener >& xListener )
534 {
535 ::osl::MutexGuard aGuard( m_aMutex );
536 if ( m_pInterfaceContainer )
537 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ),
538 xListener );
539 }
540
541 //----------------------------------------------
close(sal_Bool bDeliverOwnership)542 void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
543 {
544 ::osl::MutexGuard aGuard( m_aMutex );
545 if ( m_bClosed )
546 throw lang::DisposedException(); // TODO
547
548 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
549 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
550
551 if ( m_pInterfaceContainer )
552 {
553 ::cppu::OInterfaceContainerHelper* pContainer =
554 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
555 if ( pContainer != NULL )
556 {
557 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
558 while (pIterator.hasMoreElements())
559 {
560 try
561 {
562 ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership );
563 }
564 catch( uno::RuntimeException& )
565 {
566 pIterator.remove();
567 }
568 }
569 }
570
571 pContainer = m_pInterfaceContainer->getContainer(
572 ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
573 if ( pContainer != NULL )
574 {
575 ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
576 while (pCloseIterator.hasMoreElements())
577 {
578 try
579 {
580 ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource );
581 }
582 catch( uno::RuntimeException& )
583 {
584 pCloseIterator.remove();
585 }
586 }
587 }
588
589 m_pInterfaceContainer->disposeAndClear( aSource );
590 }
591
592 m_bDisposed = sal_True; // the object is disposed now for outside
593
594 // it is possible that the document can not be closed, in this case if the argument is false
595 // the exception will be thrown otherwise in addition to exception the object must register itself
596 // as termination listener and listen for document events
597
598 if ( m_pDocHolder )
599 {
600 m_pDocHolder->CloseFrame();
601
602 try {
603 m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership );
604 }
605 catch( uno::Exception& )
606 {
607 if ( bDeliverOwnership )
608 {
609 m_pDocHolder->release();
610 m_pDocHolder = NULL;
611 m_bClosed = sal_True;
612 }
613
614 throw;
615 }
616
617 m_pDocHolder->FreeOffice();
618
619 m_pDocHolder->release();
620 m_pDocHolder = NULL;
621 }
622
623 // TODO: for now the storage will be disposed by the object, but after the document
624 // will use the storage, the storage will be disposed by the document and recreated by the object
625 if ( m_xObjectStorage.is() )
626 {
627 uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY );
628 OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" );
629
630 if ( xComp.is() )
631 {
632 try {
633 xComp->dispose();
634 } catch ( uno::Exception& ) {}
635 }
636
637 m_xObjectStorage.clear();
638 m_xRecoveryStorage.clear();
639 }
640
641 m_bClosed = sal_True; // the closing succeeded
642 }
643
644 //----------------------------------------------
addCloseListener(const uno::Reference<util::XCloseListener> & xListener)645 void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
646 {
647 ::osl::MutexGuard aGuard( m_aMutex );
648 if ( m_bDisposed )
649 throw lang::DisposedException(); // TODO
650
651 if ( !m_pInterfaceContainer )
652 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
653
654 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), xListener );
655 }
656
657 //----------------------------------------------
removeCloseListener(const uno::Reference<util::XCloseListener> & xListener)658 void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
659 {
660 ::osl::MutexGuard aGuard( m_aMutex );
661 if ( m_pInterfaceContainer )
662 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ),
663 xListener );
664 }
665
666 //------------------------------------------------------
addEventListener(const uno::Reference<document::XEventListener> & xListener)667 void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener )
668 {
669 ::osl::MutexGuard aGuard( m_aMutex );
670 if ( m_bDisposed )
671 throw lang::DisposedException(); // TODO
672
673 if ( !m_pInterfaceContainer )
674 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
675
676 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), xListener );
677 }
678
679 //------------------------------------------------------
removeEventListener(const uno::Reference<document::XEventListener> & xListener)680 void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
681 {
682 ::osl::MutexGuard aGuard( m_aMutex );
683 if ( m_pInterfaceContainer )
684 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ),
685 xListener );
686 }
687