1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
25 #include <com/sun/star/embed/EmbedStates.hpp>
26 #include <com/sun/star/lang/XComponent.hpp>
27 #include <com/sun/star/lang/DisposedException.hpp>
29 #include <cppuhelper/interfacecontainer.h>
31 #include <oleembobj.hxx>
32 #include <olepersist.hxx>
34 #include "ownview.hxx"
37 #include <olecomponent.hxx>
40 using namespace ::com::sun::star
;
43 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
,
44 const uno::Sequence
< sal_Int8
>& aClassID
,
45 const OUString
& aClassName
)
46 : m_pOleComponent( nullptr )
47 , m_pInterfaceContainer( nullptr )
48 , m_bReadOnly( false )
49 , m_bDisposed( false )
50 , m_nObjectState( -1 )
51 , m_nTargetState( -1 )
52 , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE
)
53 , m_xFactory( xFactory
)
54 , m_aClassID( aClassID
)
55 , m_aClassName( aClassName
)
56 , m_bWaitSaveCompleted( false )
57 , m_bNewVisReplInStream( true )
58 , m_bStoreLoaded( false )
59 , m_bVisReplInitialized( false )
60 , m_bVisReplInStream( false )
61 , m_bStoreVisRepl( false )
63 , m_bHasCachedSize( false )
64 , m_nCachedAspect( 0 )
65 , m_bHasSizeToSet( false )
67 , m_bGotStatus( false )
69 , m_nStatusAspect( 0 )
70 , m_pOwnView( nullptr )
71 , m_bFromClipboard( false )
72 , m_bTriedConversion( false )
77 // In case of loading from persistent entry the classID of the object
78 // will be retrieved from the entry, during construction it is unknown
79 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
, bool bLink
)
80 : m_pOleComponent( nullptr )
81 , m_pInterfaceContainer( nullptr )
82 , m_bReadOnly( false )
83 , m_bDisposed( false )
84 , m_nObjectState( -1 )
85 , m_nTargetState( -1 )
86 , m_nUpdateMode( embed::EmbedUpdateModes::ALWAYS_UPDATE
)
87 , m_xFactory( xFactory
)
88 , m_bWaitSaveCompleted( false )
89 , m_bNewVisReplInStream( true )
90 , m_bStoreLoaded( false )
91 , m_bVisReplInitialized( false )
92 , m_bVisReplInStream( false )
93 , m_bStoreVisRepl( false )
95 , m_bHasCachedSize( false )
96 , m_nCachedAspect( 0 )
97 , m_bHasSizeToSet( false )
99 , m_bGotStatus( false )
101 , m_nStatusAspect( 0 )
102 , m_pOwnView( nullptr )
103 , m_bFromClipboard( false )
104 , m_bTriedConversion( false )
109 // this constructor let object be initialized from clipboard
110 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
111 : m_pOleComponent( nullptr )
112 , m_pInterfaceContainer( nullptr )
113 , m_bReadOnly( false )
114 , m_bDisposed( false )
115 , m_nObjectState( -1 )
116 , m_nTargetState( -1 )
117 , m_nUpdateMode( embed::EmbedUpdateModes::ALWAYS_UPDATE
)
118 , m_xFactory( xFactory
)
119 , m_bWaitSaveCompleted( false )
120 , m_bNewVisReplInStream( true )
121 , m_bStoreLoaded( false )
122 , m_bVisReplInitialized( false )
123 , m_bVisReplInStream( false )
124 , m_bStoreVisRepl( false )
126 , m_bHasCachedSize( false )
127 , m_nCachedAspect( 0 )
128 , m_bHasSizeToSet( false )
129 , m_nAspectToSet( 0 )
130 , m_bGotStatus( false )
132 , m_nStatusAspect( 0 )
133 , m_pOwnView( nullptr )
134 , m_bFromClipboard( true )
135 , m_bTriedConversion( false )
140 OleEmbeddedObject::~OleEmbeddedObject()
142 OSL_ENSURE( !m_pInterfaceContainer
&& !m_pOleComponent
&& !m_xObjectStream
.is(),
143 "The object is not closed! DISASTER is possible!" );
145 if ( m_pOleComponent
|| m_pInterfaceContainer
|| m_xObjectStream
.is() )
147 // the component must be cleaned during closing
148 m_refCount
++; // to avoid crash
151 } catch( const uno::Exception
& ) {}
154 if ( !m_aTempURL
.isEmpty() )
155 KillFile_Impl( m_aTempURL
, m_xFactory
);
157 if ( !m_aTempDumpURL
.isEmpty() )
158 KillFile_Impl( m_aTempDumpURL
, m_xFactory
);
162 void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString
& aEventName
)
164 if ( m_pInterfaceContainer
)
166 ::cppu::OInterfaceContainerHelper
* pContainer
=
167 m_pInterfaceContainer
->getContainer(
168 cppu::UnoType
<document::XEventListener
>::get());
169 if ( pContainer
!= nullptr )
171 document::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >( this ), aEventName
);
172 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
173 while (pIterator
.hasMoreElements())
177 static_cast<document::XEventListener
*>(pIterator
.next())->notifyEvent( aEvent
);
179 catch( const uno::RuntimeException
& )
188 void OleEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange
, sal_Int32 nOldState
, sal_Int32 nNewState
)
190 if ( m_pInterfaceContainer
)
192 ::cppu::OInterfaceContainerHelper
* pContainer
= m_pInterfaceContainer
->getContainer(
193 cppu::UnoType
<embed::XStateChangeListener
>::get());
194 if ( pContainer
!= nullptr )
196 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >( this ) );
197 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
199 while (pIterator
.hasMoreElements())
205 static_cast<embed::XStateChangeListener
*>(pIterator
.next())->changingState( aSource
, nOldState
, nNewState
);
207 catch( const uno::Exception
& )
209 // even if the listener complains ignore it for now
216 static_cast<embed::XStateChangeListener
*>(pIterator
.next())->stateChanged( aSource
, nOldState
, nNewState
);
218 catch( const uno::Exception
& )
220 // if anything happened it is problem of listener, ignore it
229 void OleEmbeddedObject::GetRidOfComponent()
232 if ( m_pOleComponent
)
234 if ( m_nObjectState
!= -1 && m_nObjectState
!= embed::EmbedStates::LOADED
)
237 m_pOleComponent
->removeCloseListener( m_xClosePreventer
);
240 m_pOleComponent
->close( false );
242 catch( const uno::Exception
& )
244 // TODO: there should be a special listener to wait for component closing
245 // and to notify object, may be object itself can be such a listener
246 m_pOleComponent
->addCloseListener( m_xClosePreventer
);
250 m_pOleComponent
->disconnectEmbeddedObject();
251 m_pOleComponent
->release();
252 m_pOleComponent
= nullptr;
258 void OleEmbeddedObject::Dispose()
260 if ( m_pInterfaceContainer
)
262 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >( this ) );
263 m_pInterfaceContainer
->disposeAndClear( aSource
);
264 delete m_pInterfaceContainer
;
265 m_pInterfaceContainer
= nullptr;
271 m_pOwnView
->release();
272 m_pOwnView
= nullptr;
275 if ( m_pOleComponent
)
278 } catch( const uno::Exception
& )
281 throw; // TODO: there should be a special listener that will close object when
282 // component is finally closed
285 if ( m_xObjectStream
.is() )
287 uno::Reference
< lang::XComponent
> xComp( m_xObjectStream
, uno::UNO_QUERY
);
288 OSL_ENSURE( xComp
.is(), "Storage stream doesn't support XComponent!\n" );
294 } catch( const uno::Exception
& ) {}
296 m_xObjectStream
.clear();
299 m_xParentStorage
.clear();
305 uno::Sequence
< sal_Int8
> SAL_CALL
OleEmbeddedObject::getClassID()
306 throw ( uno::RuntimeException
, std::exception
)
308 // begin wrapping related part ====================
309 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
310 if ( xWrappedObject
.is() )
312 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
313 return xWrappedObject
->getClassID();
315 // end wrapping related part ====================
317 ::osl::MutexGuard
aGuard( m_aMutex
);
319 throw lang::DisposedException(); // TODO
325 OUString SAL_CALL
OleEmbeddedObject::getClassName()
326 throw ( uno::RuntimeException
, std::exception
)
328 // begin wrapping related part ====================
329 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
330 if ( xWrappedObject
.is() )
332 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
333 return xWrappedObject
->getClassName();
335 // end wrapping related part ====================
337 ::osl::MutexGuard
aGuard( m_aMutex
);
339 throw lang::DisposedException(); // TODO
345 void SAL_CALL
OleEmbeddedObject::setClassInfo(
346 const uno::Sequence
< sal_Int8
>& aClassID
, const OUString
& aClassName
)
347 throw ( lang::NoSupportException
,
348 uno::RuntimeException
, std::exception
)
350 // begin wrapping related part ====================
351 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
352 if ( xWrappedObject
.is() )
354 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
355 xWrappedObject
->setClassInfo( aClassID
, aClassName
);
358 // end wrapping related part ====================
360 // the object class info can not be changed explicitly
361 throw lang::NoSupportException(); //TODO:
365 uno::Reference
< util::XCloseable
> SAL_CALL
OleEmbeddedObject::getComponent()
366 throw ( uno::RuntimeException
, std::exception
)
368 // begin wrapping related part ====================
369 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
370 if ( xWrappedObject
.is() )
372 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
373 return xWrappedObject
->getComponent();
375 // end wrapping related part ====================
377 ::osl::MutexGuard
aGuard( m_aMutex
);
379 throw lang::DisposedException(); // TODO
381 if ( m_nObjectState
== -1 ) // || m_nObjectState == embed::EmbedStates::LOADED )
383 // the object is still not running
384 throw uno::RuntimeException( "The object is not loaded!",
385 static_cast< ::cppu::OWeakObject
* >(this) );
389 if (m_pOleComponent
!= nullptr)
391 return uno::Reference
< util::XCloseable
>( static_cast< ::cppu::OWeakObject
* >( m_pOleComponent
), uno::UNO_QUERY
);
395 assert(m_pOleComponent
== nullptr);
396 // TODO/LATER: Is it correct???
397 return uno::Reference
< util::XCloseable
>();
398 // throw uno::RuntimeException(); // TODO
402 void SAL_CALL
OleEmbeddedObject::addStateChangeListener( const uno::Reference
< embed::XStateChangeListener
>& xListener
)
403 throw ( uno::RuntimeException
, std::exception
)
405 // begin wrapping related part ====================
406 uno::Reference
< embed::XStateChangeBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
407 if ( xWrappedObject
.is() )
409 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
410 xWrappedObject
->addStateChangeListener( xListener
);
413 // end wrapping related part ====================
415 ::osl::MutexGuard
aGuard( m_aMutex
);
417 throw lang::DisposedException(); // TODO
419 if ( !m_pInterfaceContainer
)
420 m_pInterfaceContainer
= new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex
);
422 m_pInterfaceContainer
->addInterface( cppu::UnoType
<embed::XStateChangeListener
>::get(),
427 void SAL_CALL
OleEmbeddedObject::removeStateChangeListener(
428 const uno::Reference
< embed::XStateChangeListener
>& xListener
)
429 throw (uno::RuntimeException
, std::exception
)
431 // begin wrapping related part ====================
432 uno::Reference
< embed::XStateChangeBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
433 if ( xWrappedObject
.is() )
435 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
436 xWrappedObject
->removeStateChangeListener( xListener
);
439 // end wrapping related part ====================
441 ::osl::MutexGuard
aGuard( m_aMutex
);
442 if ( m_pInterfaceContainer
)
443 m_pInterfaceContainer
->removeInterface( cppu::UnoType
<embed::XStateChangeListener
>::get(),
448 void SAL_CALL
OleEmbeddedObject::close( sal_Bool bDeliverOwnership
)
449 throw ( util::CloseVetoException
,
450 uno::RuntimeException
, std::exception
)
452 // begin wrapping related part ====================
453 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
454 if ( xWrappedObject
.is() )
456 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
457 xWrappedObject
->close( bDeliverOwnership
);
460 // end wrapping related part ====================
462 ::osl::MutexGuard
aGuard( m_aMutex
);
464 throw lang::DisposedException(); // TODO
466 uno::Reference
< uno::XInterface
> xSelfHold( static_cast< ::cppu::OWeakObject
* >( this ) );
467 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >( this ) );
469 if ( m_pInterfaceContainer
)
471 ::cppu::OInterfaceContainerHelper
* pContainer
=
472 m_pInterfaceContainer
->getContainer( cppu::UnoType
<util::XCloseListener
>::get());
473 if ( pContainer
!= nullptr )
475 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
476 while (pIterator
.hasMoreElements())
480 static_cast<util::XCloseListener
*>(pIterator
.next())->queryClosing( aSource
, bDeliverOwnership
);
482 catch( const uno::RuntimeException
& )
489 pContainer
= m_pInterfaceContainer
->getContainer(
490 cppu::UnoType
<util::XCloseListener
>::get());
491 if ( pContainer
!= nullptr )
493 ::cppu::OInterfaceIteratorHelper
pCloseIterator(*pContainer
);
494 while (pCloseIterator
.hasMoreElements())
498 static_cast<util::XCloseListener
*>(pCloseIterator
.next())->notifyClosing( aSource
);
500 catch( const uno::RuntimeException
& )
502 pCloseIterator
.remove();
512 void SAL_CALL
OleEmbeddedObject::addCloseListener( const uno::Reference
< util::XCloseListener
>& xListener
)
513 throw ( uno::RuntimeException
, std::exception
)
515 // begin wrapping related part ====================
516 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
517 if ( xWrappedObject
.is() )
519 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
520 xWrappedObject
->addCloseListener( xListener
);
523 // end wrapping related part ====================
525 ::osl::MutexGuard
aGuard( m_aMutex
);
527 throw lang::DisposedException(); // TODO
529 if ( !m_pInterfaceContainer
)
530 m_pInterfaceContainer
= new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex
);
532 m_pInterfaceContainer
->addInterface( cppu::UnoType
<util::XCloseListener
>::get(), xListener
);
536 void SAL_CALL
OleEmbeddedObject::removeCloseListener( const uno::Reference
< util::XCloseListener
>& xListener
)
537 throw (uno::RuntimeException
, std::exception
)
539 // begin wrapping related part ====================
540 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
541 if ( xWrappedObject
.is() )
543 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
544 xWrappedObject
->removeCloseListener( xListener
);
547 // end wrapping related part ====================
549 ::osl::MutexGuard
aGuard( m_aMutex
);
551 throw lang::DisposedException(); // TODO
553 if ( m_pInterfaceContainer
)
554 m_pInterfaceContainer
->removeInterface( cppu::UnoType
<util::XCloseListener
>::get(),
559 void SAL_CALL
OleEmbeddedObject::addEventListener( const uno::Reference
< document::XEventListener
>& xListener
)
560 throw ( uno::RuntimeException
, std::exception
)
562 // begin wrapping related part ====================
563 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
564 if ( xWrappedObject
.is() )
566 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
567 xWrappedObject
->addEventListener( xListener
);
570 // end wrapping related part ====================
572 ::osl::MutexGuard
aGuard( m_aMutex
);
574 throw lang::DisposedException(); // TODO
576 if ( !m_pInterfaceContainer
)
577 m_pInterfaceContainer
= new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex
);
579 m_pInterfaceContainer
->addInterface( cppu::UnoType
<document::XEventListener
>::get(), xListener
);
583 void SAL_CALL
OleEmbeddedObject::removeEventListener(
584 const uno::Reference
< document::XEventListener
>& xListener
)
585 throw ( uno::RuntimeException
, std::exception
)
587 // begin wrapping related part ====================
588 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
589 if ( xWrappedObject
.is() )
591 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
592 xWrappedObject
->removeEventListener( xListener
);
595 // end wrapping related part ====================
597 ::osl::MutexGuard
aGuard( m_aMutex
);
599 throw lang::DisposedException(); // TODO
601 if ( m_pInterfaceContainer
)
602 m_pInterfaceContainer
->removeInterface( cppu::UnoType
<document::XEventListener
>::get(),
606 // XInplaceObject ( wrapper related implementation )
608 void SAL_CALL
OleEmbeddedObject::setObjectRectangles( const awt::Rectangle
& aPosRect
,
609 const awt::Rectangle
& aClipRect
)
610 throw ( embed::WrongStateException
,
612 uno::RuntimeException
, std::exception
)
614 // begin wrapping related part ====================
615 uno::Reference
< embed::XInplaceObject
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
616 if ( xWrappedObject
.is() )
618 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
619 xWrappedObject
->setObjectRectangles( aPosRect
, aClipRect
);
622 // end wrapping related part ====================
624 throw embed::WrongStateException();
628 void SAL_CALL
OleEmbeddedObject::enableModeless( sal_Bool bEnable
)
629 throw ( embed::WrongStateException
,
631 uno::RuntimeException
, std::exception
)
633 // begin wrapping related part ====================
634 uno::Reference
< embed::XInplaceObject
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
635 if ( xWrappedObject
.is() )
637 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
638 xWrappedObject
->enableModeless( bEnable
);
641 // end wrapping related part ====================
643 throw embed::WrongStateException();
647 void SAL_CALL
OleEmbeddedObject::translateAccelerators(
648 const uno::Sequence
< awt::KeyEvent
>& aKeys
)
649 throw ( embed::WrongStateException
,
650 uno::RuntimeException
, std::exception
)
652 // begin wrapping related part ====================
653 uno::Reference
< embed::XInplaceObject
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
654 if ( xWrappedObject
.is() )
656 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
657 xWrappedObject
->translateAccelerators( aKeys
);
660 // end wrapping related part ====================
666 css::uno::Reference
< css::uno::XInterface
> SAL_CALL
OleEmbeddedObject::getParent() throw (css::uno::RuntimeException
, std::exception
)
668 // begin wrapping related part ====================
669 uno::Reference
< container::XChild
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
670 if ( xWrappedObject
.is() )
672 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
673 return xWrappedObject
->getParent();
675 // end wrapping related part ====================
681 void SAL_CALL
OleEmbeddedObject::setParent( const css::uno::Reference
< css::uno::XInterface
>& xParent
) throw (css::lang::NoSupportException
, css::uno::RuntimeException
, std::exception
)
683 // begin wrapping related part ====================
684 uno::Reference
< container::XChild
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
685 if ( xWrappedObject
.is() )
687 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
688 xWrappedObject
->setParent( xParent
);
691 // end wrapping related part ====================
696 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */