1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_embeddedobj.hxx"
30 #include <com/sun/star/embed/EmbedStates.hpp>
31 #include <com/sun/star/embed/EmbedVerbs.hpp>
32 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
33 #include <com/sun/star/embed/XEmbeddedClient.hpp>
34 #include <com/sun/star/embed/XInplaceClient.hpp>
35 #include <com/sun/star/embed/XWindowSupplier.hpp>
36 #include <com/sun/star/embed/StateChangeInProgressException.hpp>
37 #include <com/sun/star/embed/Aspects.hpp>
38 
39 #include <com/sun/star/awt/XWindowPeer.hpp>
40 #include <com/sun/star/util/XCloseBroadcaster.hpp>
41 #include <com/sun/star/util/XCloseable.hpp>
42 #include <com/sun/star/util/XModifiable.hpp>
43 #include <com/sun/star/frame/XFrame.hpp>
44 #include <com/sun/star/frame/XComponentLoader.hpp>
45 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
46 #include <com/sun/star/frame/XModuleManager.hpp>
47 #include <com/sun/star/lang/DisposedException.hpp>
48 
49 #include <com/sun/star/embed/EmbedMisc.hpp>
50 
51 #include <rtl/logfile.hxx>
52 
53 #include <targetstatecontrol.hxx>
54 
55 #include "commonembobj.hxx"
56 #include "intercept.hxx"
57 
58 
59 using namespace ::com::sun::star;
60 
61 awt::Rectangle GetRectangleInterception( const awt::Rectangle& aRect1, const awt::Rectangle& aRect2 )
62 {
63     awt::Rectangle aResult;
64 
65     OSL_ENSURE( aRect1.Width >= 0 && aRect2.Width >= 0 && aRect1.Height >= 0 && aRect2.Height >= 0,
66                 "Offset must not be less then zero!" );
67 
68     aResult.X = aRect1.X > aRect2.X ? aRect1.X : aRect2.X;
69     aResult.Y = aRect1.Y > aRect2.Y ? aRect1.Y : aRect2.Y;
70 
71     sal_Int32 nRight1 = aRect1.X + aRect1.Width;
72     sal_Int32 nBottom1 = aRect1.Y + aRect1.Height;
73     sal_Int32 nRight2 = aRect2.X + aRect2.Width;
74     sal_Int32 nBottom2 = aRect2.Y + aRect2.Height;
75     aResult.Width = ( nRight1 < nRight2 ? nRight1 : nRight2 ) - aResult.X;
76     aResult.Height = ( nBottom1 < nBottom2 ? nBottom1 : nBottom2 ) - aResult.Y;
77 
78     return aResult;
79 }
80 
81 //----------------------------------------------
82 sal_Int32 OCommonEmbeddedObject::ConvertVerbToState_Impl( sal_Int32 nVerb )
83 {
84     for ( sal_Int32 nInd = 0; nInd < m_aVerbTable.getLength(); nInd++ )
85         if ( m_aVerbTable[nInd][0] == nVerb )
86             return m_aVerbTable[nInd][1];
87 
88     throw lang::IllegalArgumentException(); // TODO: unexpected verb provided
89 }
90 
91 //----------------------------------------------
92 void OCommonEmbeddedObject::Deactivate()
93 {
94     uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
95     //MBA if ( !xModif.is() )
96     //MBA    throw uno::RuntimeException();
97 
98     // no need to lock for the initialization
99     uno::Reference< embed::XEmbeddedClient > xClientSite = m_xClientSite;
100     if ( !xClientSite.is() )
101         throw embed::WrongStateException(); //TODO: client site is not set!
102 
103     // store document if it is modified
104     if ( xModif.is() && xModif->isModified() )
105     {
106         try {
107             xClientSite->saveObject();
108         }
109         catch( embed::ObjectSaveVetoException& )
110         {
111         }
112         catch( uno::Exception& e )
113         {
114             throw embed::StorageWrappedTargetException(
115                 ::rtl::OUString::createFromAscii( "The client could not store the object!" ),
116                 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
117                 uno::makeAny( e ) );
118         }
119     }
120 
121     m_pDocHolder->CloseFrame();
122 
123     xClientSite->visibilityChanged( sal_False );
124 }
125 
126 //----------------------------------------------
127 void OCommonEmbeddedObject::StateChangeNotification_Impl( sal_Bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState ,::osl::ResettableMutexGuard& rGuard )
128 {
129     if ( m_pInterfaceContainer )
130     {
131         ::cppu::OInterfaceContainerHelper* pContainer = m_pInterfaceContainer->getContainer(
132                             ::getCppuType( ( const uno::Reference< embed::XStateChangeListener >*) NULL ) );
133         if ( pContainer != NULL )
134         {
135             lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
136             ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
137 
138             // should be locked after the method is finished successfully
139             rGuard.clear();
140 
141             while (pIterator.hasMoreElements())
142             {
143                 try
144                 {
145                     if ( bBeforeChange )
146                         ((embed::XStateChangeListener*)pIterator.next())->changingState( aSource, nOldState, nNewState );
147                     else
148                         ((embed::XStateChangeListener*)pIterator.next())->stateChanged( aSource, nOldState, nNewState );
149                 }
150                 catch( uno::Exception& )
151                 {
152                     // even if the listener complains ignore it for now
153                    }
154 
155                 if ( m_bDisposed )
156                     return;
157             }
158 
159             rGuard.reset();
160         }
161     }
162 }
163 
164 //----------------------------------------------
165 void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
166 {
167     // TODO: may be needs interaction handler to detect wherether the object state
168     //         can be changed even after errors
169 
170     if ( m_nObjectState == embed::EmbedStates::LOADED )
171     {
172         if ( nNextState == embed::EmbedStates::RUNNING )
173         {
174             // after the object reaches the running state the cloned size is not necessary any more
175             m_bHasClonedSize = sal_False;
176 
177             if ( m_bIsLink )
178             {
179                 m_pDocHolder->SetComponent( LoadLink_Impl(), m_bReadOnly );
180             }
181             else
182             {
183                 uno::Reference < embed::XEmbedPersist > xPersist( static_cast < embed::XClassifiedObject* > (this), uno::UNO_QUERY );
184                 if ( xPersist.is() )
185                 {
186                     // in case embedded object is in loaded state the contents must
187                     // be stored in the related storage and the storage
188                     // must be created already
189                     if ( !m_xObjectStorage.is() )
190                         throw io::IOException(); //TODO: access denied
191 
192                     m_pDocHolder->SetComponent( LoadDocumentFromStorage_Impl(), m_bReadOnly );
193                 }
194                 else
195                 {
196                     // objects without persistence will be initialized internally
197                     uno::Sequence < uno::Any > aArgs(1);
198                     aArgs[0] <<= uno::Reference < embed::XEmbeddedObject >( this );
199                     uno::Reference< util::XCloseable > xDocument(
200                             m_xFactory->createInstanceWithArguments( GetDocumentServiceName(), aArgs ), uno::UNO_QUERY );
201 
202                     uno::Reference < container::XChild > xChild( xDocument, uno::UNO_QUERY );
203                     if ( xChild.is() )
204                         xChild->setParent( m_xParent );
205 
206                     m_pDocHolder->SetComponent( xDocument, m_bReadOnly );
207                 }
208             }
209 
210             if ( !m_pDocHolder->GetComponent().is() )
211                 throw embed::UnreachableStateException(); //TODO: can't open document
212 
213             m_nObjectState = nNextState;
214         }
215         else
216         {
217             OSL_ENSURE( sal_False, "Unacceptable state switch!\n" );
218             throw uno::RuntimeException(); // TODO
219         }
220     }
221     else if ( m_nObjectState == embed::EmbedStates::RUNNING )
222     {
223         if ( nNextState == embed::EmbedStates::LOADED )
224         {
225             m_nClonedMapUnit = m_pDocHolder->GetMapUnit( embed::Aspects::MSOLE_CONTENT );
226             m_bHasClonedSize = m_pDocHolder->GetExtent( embed::Aspects::MSOLE_CONTENT, &m_aClonedSize );
227 
228             // actually frame should not exist at this point
229             m_pDocHolder->CloseDocument( sal_False, sal_False );
230 
231             m_nObjectState = nNextState;
232         }
233         else
234         {
235             if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
236             {
237                 if ( !m_xClientSite.is() )
238                     throw embed::WrongStateException(
239                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "client site not set, yet" ) ),
240                         *this
241                 );
242 
243                 uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
244                 if ( xInplaceClient.is() && xInplaceClient->canInplaceActivate() )
245                 {
246                     xInplaceClient->activatingInplace();
247 
248                     uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY );
249                     if ( !xClientWindowSupplier.is() )
250                         throw uno::RuntimeException(); // TODO: the inplace client implementation must support XWinSupp
251 
252                     m_xClientWindow = xClientWindowSupplier->getWindow();
253                     m_aOwnRectangle = xInplaceClient->getPlacement();
254                     m_aClipRectangle = xInplaceClient->getClipRectangle();
255                     awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
256 
257                     // create own window based on the client window
258                     // place and resize the window according to the rectangles
259                     uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY );
260                     if ( !xClientWindowPeer.is() )
261                         throw uno::RuntimeException(); // TODO: the container window must support the interface
262 
263                     // dispatch provider may not be provided
264                     uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
265                     sal_Bool bOk = m_pDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
266                     m_nObjectState = nNextState;
267                     if ( !bOk )
268                     {
269                         SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
270                         throw embed::WrongStateException(); //TODO: can't activate inplace
271                     }
272                 }
273                 else
274                     throw embed::WrongStateException(); //TODO: can't activate inplace
275             }
276             else if ( nNextState == embed::EmbedStates::ACTIVE )
277             {
278                 if ( !m_xClientSite.is() )
279                     throw embed::WrongStateException(); //TODO: client site is not set!
280 
281                 // create frame and load document in the frame
282                 m_pDocHolder->Show();
283 
284                 m_xClientSite->visibilityChanged( sal_True );
285                 m_nObjectState = nNextState;
286             }
287             else
288             {
289                 OSL_ENSURE( sal_False, "Unacceptable state switch!\n" );
290                 throw uno::RuntimeException(); // TODO
291             }
292         }
293     }
294     else if ( m_nObjectState == embed::EmbedStates::INPLACE_ACTIVE )
295     {
296         if ( nNextState == embed::EmbedStates::RUNNING )
297         {
298             uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
299             if ( !xInplaceClient.is() )
300                 throw uno::RuntimeException();
301 
302             m_xClientSite->visibilityChanged( sal_True );
303 
304             xInplaceClient->deactivatedInplace();
305             Deactivate();
306             m_nObjectState = nNextState;
307         }
308         else if ( nNextState == embed::EmbedStates::UI_ACTIVE )
309         {
310             if ( !(m_nMiscStatus & embed::EmbedMisc::MS_EMBED_NOUIACTIVATE) )
311             {
312                 uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY_THROW );
313                 // TODO:
314                 uno::Reference< ::com::sun::star::frame::XLayoutManager > xContainerLM =
315                             xInplaceClient->getLayoutManager();
316                 if ( xContainerLM.is() )
317                 {
318                     // dispatch provider may not be provided
319                     uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
320 
321                     // get the container module name
322                     ::rtl::OUString aModuleName;
323                     try
324                     {
325                         uno::Reference< embed::XComponentSupplier > xCompSupl( m_xClientSite, uno::UNO_QUERY_THROW );
326                         uno::Reference< uno::XInterface > xContDoc( xCompSupl->getComponent(), uno::UNO_QUERY_THROW );
327 
328                         uno::Reference< frame::XModuleManager > xManager(
329                             m_xFactory->createInstance(
330                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ),
331                             uno::UNO_QUERY_THROW );
332 
333                         aModuleName = xManager->identify( xContDoc );
334                     }
335                     catch( uno::Exception& )
336                     {}
337 
338                     // if currently another object is UIactive it will be deactivated; usually this will activate the LM of
339                     // the container. Locking the LM will prevent flicker.
340                     xContainerLM->lock();
341                     xInplaceClient->activatingUI();
342                     sal_Bool bOk = m_pDocHolder->ShowUI( xContainerLM, xContainerDP, aModuleName );
343                     xContainerLM->unlock();
344 
345                     if ( bOk )
346                     {
347                         m_nObjectState = nNextState;
348                         m_pDocHolder->ResizeHatchWindow();
349                     }
350                     else
351                     {
352                         xInplaceClient->deactivatedUI();
353                         throw embed::WrongStateException(); //TODO: can't activate UI
354                     }
355                 }
356                 else
357                     throw embed::WrongStateException(); //TODO: can't activate UI
358             }
359         }
360         else
361         {
362             OSL_ENSURE( sal_False, "Unacceptable state switch!\n" );
363             throw uno::RuntimeException(); // TODO
364         }
365     }
366     else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
367     {
368         if ( nNextState == embed::EmbedStates::RUNNING )
369         {
370             Deactivate();
371             m_nObjectState = nNextState;
372         }
373         else
374         {
375             OSL_ENSURE( sal_False, "Unacceptable state switch!\n" );
376             throw uno::RuntimeException(); // TODO
377         }
378     }
379     else if ( m_nObjectState == embed::EmbedStates::UI_ACTIVE )
380     {
381         if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
382         {
383             uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY_THROW );
384             uno::Reference< ::com::sun::star::frame::XLayoutManager > xContainerLM =
385                         xInplaceClient->getLayoutManager();
386 
387             sal_Bool bOk = sal_False;
388             if ( xContainerLM.is() )
389                    bOk = m_pDocHolder->HideUI( xContainerLM );
390 
391             if ( bOk )
392             {
393                 m_nObjectState = nNextState;
394                 m_pDocHolder->ResizeHatchWindow();
395                    xInplaceClient->deactivatedUI();
396             }
397             else
398                 throw embed::WrongStateException(); //TODO: can't activate UI
399         }
400     }
401     else
402         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object is in unacceptable state!\n" ),
403                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
404 }
405 
406 //----------------------------------------------
407 uno::Sequence< sal_Int32 > OCommonEmbeddedObject::GetIntermediateStatesSequence_Impl( sal_Int32 nNewState )
408 {
409     sal_Int32 nCurInd = 0;
410     for ( nCurInd = 0; nCurInd < m_aAcceptedStates.getLength(); nCurInd++ )
411         if ( m_aAcceptedStates[nCurInd] == m_nObjectState )
412             break;
413 
414     if ( nCurInd == m_aAcceptedStates.getLength() )
415         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object is in unacceptable state!\n" ),
416                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
417 
418     sal_Int32 nDestInd = 0;
419     for ( nDestInd = 0; nDestInd < m_aAcceptedStates.getLength(); nDestInd++ )
420         if ( m_aAcceptedStates[nDestInd] == nNewState )
421             break;
422 
423     if ( nDestInd == m_aAcceptedStates.getLength() )
424         throw embed::UnreachableStateException(
425             ::rtl::OUString::createFromAscii( "The state either not reachable, or the object allows the state only as an intermediate one!\n" ),
426             uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
427             m_nObjectState,
428             nNewState );
429 
430     return m_pIntermediateStatesSeqs[nCurInd][nDestInd];
431 }
432 
433 //----------------------------------------------
434 void SAL_CALL OCommonEmbeddedObject::changeState( sal_Int32 nNewState )
435         throw ( embed::UnreachableStateException,
436                 embed::WrongStateException,
437                 uno::Exception,
438                 uno::RuntimeException )
439 {
440     RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::changeState" );
441 
442     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ), uno::UNO_QUERY);
443     {
444         ::osl::ResettableMutexGuard aGuard( m_aMutex );
445         if ( m_bDisposed )
446             throw lang::DisposedException(); // TODO
447 
448         if ( m_nObjectState == -1 )
449             throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
450                                             uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
451 
452         sal_Int32 nOldState = m_nObjectState;
453 
454         if ( m_nTargetState != -1 )
455         {
456             // means that the object is currently trying to reach the target state
457             throw embed::StateChangeInProgressException( ::rtl::OUString(),
458                                                         uno::Reference< uno::XInterface >(),
459                                                         m_nTargetState );
460         }
461         else
462         {
463             TargetStateControl_Impl aControl( m_nTargetState, nNewState );
464 
465             // in case the object is already in requested state
466             if ( m_nObjectState == nNewState )
467             {
468                 // if active object is activated again, bring it's window to top
469                 if ( m_nObjectState == embed::EmbedStates::ACTIVE )
470                     m_pDocHolder->Show();
471 
472                 return;
473             }
474 
475             // retrieve sequence of states that should be passed to reach desired state
476             uno::Sequence< sal_Int32 > aIntermediateStates = GetIntermediateStatesSequence_Impl( nNewState );
477 
478             // notify listeners that the object is going to change the state
479             StateChangeNotification_Impl( sal_True, nOldState, nNewState,aGuard );
480 
481             try {
482                 for ( sal_Int32 nInd = 0; nInd < aIntermediateStates.getLength(); nInd++ )
483                     SwitchStateTo_Impl( aIntermediateStates[nInd] );
484 
485                 SwitchStateTo_Impl( nNewState );
486             }
487             catch( uno::Exception& )
488             {
489                 if ( nOldState != m_nObjectState )
490                     // notify listeners that the object has changed the state
491                     StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState, aGuard );
492 
493                 throw;
494             }
495         }
496 
497         // notify listeners that the object has changed the state
498         StateChangeNotification_Impl( sal_False, nOldState, nNewState, aGuard );
499 
500         // let the object window be shown
501         if ( nNewState == embed::EmbedStates::UI_ACTIVE || nNewState == embed::EmbedStates::INPLACE_ACTIVE )
502             PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ),
503                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
504     }
505 }
506 
507 //----------------------------------------------
508 uno::Sequence< sal_Int32 > SAL_CALL OCommonEmbeddedObject::getReachableStates()
509         throw ( embed::WrongStateException,
510                 uno::RuntimeException )
511 {
512     if ( m_bDisposed )
513         throw lang::DisposedException(); // TODO
514 
515     if ( m_nObjectState == -1 )
516         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
517                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
518 
519     return m_aAcceptedStates;
520 }
521 
522 //----------------------------------------------
523 sal_Int32 SAL_CALL OCommonEmbeddedObject::getCurrentState()
524         throw ( embed::WrongStateException,
525                 uno::RuntimeException )
526 {
527     if ( m_bDisposed )
528         throw lang::DisposedException(); // TODO
529 
530     if ( m_nObjectState == -1 )
531         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
532                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
533 
534     return m_nObjectState;
535 }
536 
537 //----------------------------------------------
538 void SAL_CALL OCommonEmbeddedObject::doVerb( sal_Int32 nVerbID )
539         throw ( lang::IllegalArgumentException,
540                 embed::WrongStateException,
541                 embed::UnreachableStateException,
542                 uno::Exception,
543                 uno::RuntimeException )
544 {
545     RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::doVerb" );
546 
547     ::osl::ResettableMutexGuard aGuard( m_aMutex );
548     if ( m_bDisposed )
549         throw lang::DisposedException(); // TODO
550 
551     if ( m_nObjectState == -1 )
552         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
553                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
554 
555     // for internal documents this call is just a duplicate of changeState
556     sal_Int32 nNewState = -1;
557     try
558     {
559         nNewState = ConvertVerbToState_Impl( nVerbID );
560     }
561     catch( uno::Exception& )
562     {}
563 
564     if ( nNewState == -1 )
565     {
566         // TODO/LATER: Save Copy as... verb ( -8 ) is implemented by container
567         // TODO/LATER: check if the verb is a supported one and if it is produce related operation
568     }
569     else
570     {
571         aGuard.clear();
572         changeState( nNewState );
573     }
574 }
575 
576 //----------------------------------------------
577 uno::Sequence< embed::VerbDescriptor > SAL_CALL OCommonEmbeddedObject::getSupportedVerbs()
578         throw ( embed::WrongStateException,
579                 uno::RuntimeException )
580 {
581     if ( m_bDisposed )
582         throw lang::DisposedException(); // TODO
583 
584     if ( m_nObjectState == -1 )
585         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
586                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
587 
588     return m_aObjectVerbs;
589 }
590 
591 //----------------------------------------------
592 void SAL_CALL OCommonEmbeddedObject::setClientSite(
593                 const uno::Reference< embed::XEmbeddedClient >& xClient )
594         throw ( embed::WrongStateException,
595                 uno::RuntimeException )
596 {
597     ::osl::MutexGuard aGuard( m_aMutex );
598     if ( m_bDisposed )
599         throw lang::DisposedException(); // TODO
600 
601     if ( m_xClientSite != xClient)
602     {
603         if ( m_nObjectState != embed::EmbedStates::LOADED && m_nObjectState != embed::EmbedStates::RUNNING )
604             throw embed::WrongStateException(
605                                     ::rtl::OUString::createFromAscii( "The client site can not be set currently!\n" ),
606                                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
607 
608         m_xClientSite = xClient;
609     }
610 }
611 
612 //----------------------------------------------
613 uno::Reference< embed::XEmbeddedClient > SAL_CALL OCommonEmbeddedObject::getClientSite()
614         throw ( embed::WrongStateException,
615                 uno::RuntimeException )
616 {
617     if ( m_bDisposed )
618         throw lang::DisposedException(); // TODO
619 
620     if ( m_nObjectState == -1 )
621         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
622                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
623 
624     return m_xClientSite;
625 }
626 
627 //----------------------------------------------
628 void SAL_CALL OCommonEmbeddedObject::update()
629         throw ( embed::WrongStateException,
630                 uno::Exception,
631                 uno::RuntimeException )
632 {
633     ::osl::MutexGuard aGuard( m_aMutex );
634     if ( m_bDisposed )
635         throw lang::DisposedException(); // TODO
636 
637     if ( m_nObjectState == -1 )
638         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
639                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
640 
641     PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ),
642                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
643 }
644 
645 //----------------------------------------------
646 void SAL_CALL OCommonEmbeddedObject::setUpdateMode( sal_Int32 nMode )
647         throw ( embed::WrongStateException,
648                 uno::RuntimeException )
649 {
650     ::osl::MutexGuard aGuard( m_aMutex );
651     if ( m_bDisposed )
652         throw lang::DisposedException(); // TODO
653 
654     if ( m_nObjectState == -1 )
655         throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
656                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
657 
658     OSL_ENSURE( nMode == embed::EmbedUpdateModes::ALWAYS_UPDATE
659                     || nMode == embed::EmbedUpdateModes::EXPLICIT_UPDATE,
660                 "Unknown update mode!\n" );
661     m_nUpdateMode = nMode;
662 }
663 
664 //----------------------------------------------
665 sal_Int64 SAL_CALL OCommonEmbeddedObject::getStatus( sal_Int64 )
666         throw ( embed::WrongStateException,
667                 uno::RuntimeException )
668 {
669     if ( m_bDisposed )
670         throw lang::DisposedException(); // TODO
671 
672     return m_nMiscStatus;
673 }
674 
675 //----------------------------------------------
676 void SAL_CALL OCommonEmbeddedObject::setContainerName( const ::rtl::OUString& sName )
677         throw ( uno::RuntimeException )
678 {
679     ::osl::MutexGuard aGuard( m_aMutex );
680     if ( m_bDisposed )
681         throw lang::DisposedException(); // TODO
682 
683     m_aContainerName = sName;
684 }
685 
686 com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL OCommonEmbeddedObject::getParent() throw (::com::sun::star::uno::RuntimeException)
687 {
688     return m_xParent;
689 }
690 
691 void SAL_CALL OCommonEmbeddedObject::setParent( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& xParent ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException)
692 {
693     m_xParent = xParent;
694     if ( m_nObjectState != -1 && m_nObjectState != embed::EmbedStates::LOADED )
695     {
696         uno::Reference < container::XChild > xChild( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
697         if ( xChild.is() )
698             xChild->setParent( xParent );
699     }
700 }
701 
702 // XDefaultSizeTransmitter
703 void SAL_CALL OCommonEmbeddedObject::setDefaultSize( const ::com::sun::star::awt::Size& rSize_100TH_MM ) throw (::com::sun::star::uno::RuntimeException)
704 {
705     //#i103460# charts do not necessaryly have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this method
706     m_aDefaultSizeForChart_In_100TH_MM = rSize_100TH_MM;
707 }
708