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