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 throw( uno::RuntimeException )
365 {
366 uno::Any aReturn;
367
368 if ( rType == ::getCppuType( (uno::Reference< embed::XEmbeddedObject > const *)0 ))
369 {
370 void * p = static_cast< embed::XEmbeddedObject * >( this );
371 return uno::Any( &p, rType );
372 }
373 else
374 aReturn <<= ::cppu::queryInterface(
375 rType,
376 static_cast< embed::XInplaceObject* >( this ),
377 static_cast< embed::XVisualObject* >( this ),
378 static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ),
379 static_cast< embed::XEmbedPersist* >( this ),
380 static_cast< embed::XLinkageSupport* >( this ),
381 static_cast< embed::XStateChangeBroadcaster* >( this ),
382 static_cast< embed::XClassifiedObject* >( this ),
383 static_cast< embed::XComponentSupplier* >( this ),
384 static_cast< util::XCloseable* >( this ),
385 static_cast< container::XChild* >( this ),
386 static_cast< chart2::XDefaultSizeTransmitter* >( this ),
387 static_cast< document::XEventBroadcaster* >( this ) );
388
389 if ( aReturn.hasValue() )
390 return aReturn;
391 else
392 return ::cppu::OWeakObject::queryInterface( rType ) ;
393
394 }
395
396 //------------------------------------------------------
acquire()397 void SAL_CALL OCommonEmbeddedObject::acquire()
398 throw()
399 {
400 ::cppu::OWeakObject::acquire() ;
401 }
402
403 //------------------------------------------------------
release()404 void SAL_CALL OCommonEmbeddedObject::release()
405 throw()
406 {
407 ::cppu::OWeakObject::release() ;
408 }
409
410 //------------------------------------------------------
getTypes()411 uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes()
412 throw( uno::RuntimeException )
413 {
414 static ::cppu::OTypeCollection* pTypeCollection = NULL;
415
416 if ( !pTypeCollection )
417 {
418 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
419 if ( !pTypeCollection )
420 {
421 if ( m_bIsLink )
422 {
423 static ::cppu::OTypeCollection aTypeCollection(
424 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ),
425 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ),
426 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ),
427 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ),
428 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ),
429 ::getCppuType( (const uno::Reference< embed::XLinkageSupport >*)NULL ) );
430
431 pTypeCollection = &aTypeCollection ;
432 }
433 else
434 {
435 static ::cppu::OTypeCollection aTypeCollection(
436 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ),
437 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ),
438 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ),
439 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ),
440 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ),
441 ::getCppuType( (const uno::Reference< embed::XEmbedPersist >*)NULL ) );
442
443 pTypeCollection = &aTypeCollection ;
444 }
445 }
446 }
447
448 return pTypeCollection->getTypes() ;
449
450 }
451
452 //------------------------------------------------------
getImplementationId()453 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getImplementationId()
454 throw( uno::RuntimeException )
455 {
456 static ::cppu::OImplementationId* pID = NULL ;
457
458 if ( !pID )
459 {
460 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
461 if ( !pID )
462 {
463 static ::cppu::OImplementationId aID( sal_False ) ;
464 pID = &aID ;
465 }
466 }
467
468 return pID->getImplementationId() ;
469 }
470
471 //------------------------------------------------------
getClassID()472 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID()
473 throw ( uno::RuntimeException )
474 {
475 if ( m_bDisposed )
476 throw lang::DisposedException();
477
478 return m_aClassID;
479 }
480
481 //------------------------------------------------------
getClassName()482 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getClassName()
483 throw ( uno::RuntimeException )
484 {
485 if ( m_bDisposed )
486 throw lang::DisposedException();
487
488 return m_aClassName;
489 }
490
491 //------------------------------------------------------
setClassInfo(const uno::Sequence<sal_Int8> &,const::rtl::OUString &)492 void SAL_CALL OCommonEmbeddedObject::setClassInfo(
493 const uno::Sequence< sal_Int8 >& /*aClassID*/, const ::rtl::OUString& /*aClassName*/ )
494 throw ( lang::NoSupportException,
495 uno::RuntimeException )
496 {
497 // the object class info can not be changed explicitly
498 throw lang::NoSupportException(); //TODO:
499 }
500
501 //------------------------------------------------------
getComponent()502 uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent()
503 throw ( uno::RuntimeException )
504 {
505 ::osl::MutexGuard aGuard( m_aMutex );
506 if ( m_bDisposed )
507 throw lang::DisposedException(); // TODO
508
509 // add an exception
510 if ( m_nObjectState == -1 )
511 {
512 // the object is still not loaded
513 throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
514 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
515 }
516
517 // if ( m_bWaitSaveCompleted )
518 // throw embed::WrongStateException(
519 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
520 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );
521
522 return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
523 }
524
525 //----------------------------------------------
addStateChangeListener(const uno::Reference<embed::XStateChangeListener> & xListener)526 void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener )
527 throw ( uno::RuntimeException )
528 {
529 ::osl::MutexGuard aGuard( m_aMutex );
530 if ( m_bDisposed )
531 throw lang::DisposedException(); // TODO
532
533 if ( !m_pInterfaceContainer )
534 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
535
536 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ),
537 xListener );
538 }
539
540 //----------------------------------------------
removeStateChangeListener(const uno::Reference<embed::XStateChangeListener> & xListener)541 void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener(
542 const uno::Reference< embed::XStateChangeListener >& xListener )
543 throw (uno::RuntimeException)
544 {
545 ::osl::MutexGuard aGuard( m_aMutex );
546 if ( m_pInterfaceContainer )
547 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ),
548 xListener );
549 }
550
551 //----------------------------------------------
close(sal_Bool bDeliverOwnership)552 void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
553 throw ( util::CloseVetoException,
554 uno::RuntimeException )
555 {
556 ::osl::MutexGuard aGuard( m_aMutex );
557 if ( m_bClosed )
558 throw lang::DisposedException(); // TODO
559
560 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
561 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
562
563 if ( m_pInterfaceContainer )
564 {
565 ::cppu::OInterfaceContainerHelper* pContainer =
566 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
567 if ( pContainer != NULL )
568 {
569 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
570 while (pIterator.hasMoreElements())
571 {
572 try
573 {
574 ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership );
575 }
576 catch( uno::RuntimeException& )
577 {
578 pIterator.remove();
579 }
580 }
581 }
582
583 pContainer = m_pInterfaceContainer->getContainer(
584 ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
585 if ( pContainer != NULL )
586 {
587 ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
588 while (pCloseIterator.hasMoreElements())
589 {
590 try
591 {
592 ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource );
593 }
594 catch( uno::RuntimeException& )
595 {
596 pCloseIterator.remove();
597 }
598 }
599 }
600
601 m_pInterfaceContainer->disposeAndClear( aSource );
602 }
603
604 m_bDisposed = sal_True; // the object is disposed now for outside
605
606 // it is possible that the document can not be closed, in this case if the argument is false
607 // the exception will be thrown otherwise in addition to exception the object must register itself
608 // as termination listener and listen for document events
609
610 if ( m_pDocHolder )
611 {
612 m_pDocHolder->CloseFrame();
613
614 try {
615 m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership );
616 }
617 catch( uno::Exception& )
618 {
619 if ( bDeliverOwnership )
620 {
621 m_pDocHolder->release();
622 m_pDocHolder = NULL;
623 m_bClosed = sal_True;
624 }
625
626 throw;
627 }
628
629 m_pDocHolder->FreeOffice();
630
631 m_pDocHolder->release();
632 m_pDocHolder = NULL;
633 }
634
635 // TODO: for now the storage will be disposed by the object, but after the document
636 // will use the storage, the storage will be disposed by the document and recreated by the object
637 if ( m_xObjectStorage.is() )
638 {
639 uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY );
640 OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" );
641
642 if ( xComp.is() )
643 {
644 try {
645 xComp->dispose();
646 } catch ( uno::Exception& ) {}
647 }
648
649 m_xObjectStorage.clear();
650 m_xRecoveryStorage.clear();
651 }
652
653 m_bClosed = sal_True; // the closing succeeded
654 }
655
656 //----------------------------------------------
addCloseListener(const uno::Reference<util::XCloseListener> & xListener)657 void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
658 throw ( uno::RuntimeException )
659 {
660 ::osl::MutexGuard aGuard( m_aMutex );
661 if ( m_bDisposed )
662 throw lang::DisposedException(); // TODO
663
664 if ( !m_pInterfaceContainer )
665 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
666
667 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), xListener );
668 }
669
670 //----------------------------------------------
removeCloseListener(const uno::Reference<util::XCloseListener> & xListener)671 void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
672 throw (uno::RuntimeException)
673 {
674 ::osl::MutexGuard aGuard( m_aMutex );
675 if ( m_pInterfaceContainer )
676 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ),
677 xListener );
678 }
679
680 //------------------------------------------------------
addEventListener(const uno::Reference<document::XEventListener> & xListener)681 void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener )
682 throw ( uno::RuntimeException )
683 {
684 ::osl::MutexGuard aGuard( m_aMutex );
685 if ( m_bDisposed )
686 throw lang::DisposedException(); // TODO
687
688 if ( !m_pInterfaceContainer )
689 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
690
691 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), xListener );
692 }
693
694 //------------------------------------------------------
removeEventListener(const uno::Reference<document::XEventListener> & xListener)695 void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
696 throw ( uno::RuntimeException )
697 {
698 ::osl::MutexGuard aGuard( m_aMutex );
699 if ( m_pInterfaceContainer )
700 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ),
701 xListener );
702 }
703
704