build fix
[LibreOffice.git] / embeddedobj / source / msole / olemisc.cxx
blob843e3b3fbb31fc48a59b9ea4bb0d0e20cbab9b8c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <cassert>
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"
36 #if defined(_WIN32)
37 #include <olecomponent.hxx>
38 #endif
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 )
62 , m_bIsLink( false )
63 , m_bHasCachedSize( false )
64 , m_nCachedAspect( 0 )
65 , m_bHasSizeToSet( false )
66 , m_nAspectToSet( 0 )
67 , m_bGotStatus( false )
68 , m_nStatus( 0 )
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 )
94 , m_bIsLink( bLink )
95 , m_bHasCachedSize( false )
96 , m_nCachedAspect( 0 )
97 , m_bHasSizeToSet( false )
98 , m_nAspectToSet( 0 )
99 , m_bGotStatus( false )
100 , m_nStatus( 0 )
101 , m_nStatusAspect( 0 )
102 , m_pOwnView( nullptr )
103 , m_bFromClipboard( false )
104 , m_bTriedConversion( false )
107 #ifdef _WIN32
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 )
125 , m_bIsLink( false )
126 , m_bHasCachedSize( false )
127 , m_nCachedAspect( 0 )
128 , m_bHasSizeToSet( false )
129 , m_nAspectToSet( 0 )
130 , m_bGotStatus( false )
131 , m_nStatus( 0 )
132 , m_nStatusAspect( 0 )
133 , m_pOwnView( nullptr )
134 , m_bFromClipboard( true )
135 , m_bTriedConversion( false )
138 #endif
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
149 try {
150 Dispose();
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& )
186 #ifdef _WIN32
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())
201 if ( bBeforeChange )
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
212 else
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
227 #endif
229 void OleEmbeddedObject::GetRidOfComponent()
231 #ifdef _WIN32
232 if ( m_pOleComponent )
234 if ( m_nObjectState != -1 && m_nObjectState != embed::EmbedStates::LOADED )
235 SaveObject_Impl();
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 );
247 throw;
250 m_pOleComponent->disconnectEmbeddedObject();
251 m_pOleComponent->release();
252 m_pOleComponent = nullptr;
254 #endif
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;
268 if ( m_pOwnView )
270 m_pOwnView->Close();
271 m_pOwnView->release();
272 m_pOwnView = nullptr;
275 if ( m_pOleComponent )
276 try {
277 GetRidOfComponent();
278 } catch( const uno::Exception& )
280 m_bDisposed = true;
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" );
290 if ( xComp.is() )
292 try {
293 xComp->dispose();
294 } catch( const uno::Exception& ) {}
296 m_xObjectStream.clear();
299 m_xParentStorage.clear();
301 m_bDisposed = true;
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 );
318 if ( m_bDisposed )
319 throw lang::DisposedException(); // TODO
321 return m_aClassID;
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 );
338 if ( m_bDisposed )
339 throw lang::DisposedException(); // TODO
341 return m_aClassName;
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 );
356 return;
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 );
378 if ( m_bDisposed )
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) );
388 #if defined(_WIN32)
389 if (m_pOleComponent != nullptr)
391 return uno::Reference< util::XCloseable >( static_cast< ::cppu::OWeakObject* >( m_pOleComponent ), uno::UNO_QUERY );
393 #endif
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 );
411 return;
413 // end wrapping related part ====================
415 ::osl::MutexGuard aGuard( m_aMutex );
416 if ( m_bDisposed )
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(),
423 xListener );
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 );
437 return;
439 // end wrapping related part ====================
441 ::osl::MutexGuard aGuard( m_aMutex );
442 if ( m_pInterfaceContainer )
443 m_pInterfaceContainer->removeInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
444 xListener );
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 );
458 return;
460 // end wrapping related part ====================
462 ::osl::MutexGuard aGuard( m_aMutex );
463 if ( m_bDisposed )
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& )
484 pIterator.remove();
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();
508 Dispose();
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 );
521 return;
523 // end wrapping related part ====================
525 ::osl::MutexGuard aGuard( m_aMutex );
526 if ( m_bDisposed )
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 );
545 return;
547 // end wrapping related part ====================
549 ::osl::MutexGuard aGuard( m_aMutex );
550 if ( m_bDisposed )
551 throw lang::DisposedException(); // TODO
553 if ( m_pInterfaceContainer )
554 m_pInterfaceContainer->removeInterface( cppu::UnoType<util::XCloseListener>::get(),
555 xListener );
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 );
568 return;
570 // end wrapping related part ====================
572 ::osl::MutexGuard aGuard( m_aMutex );
573 if ( m_bDisposed )
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 );
593 return;
595 // end wrapping related part ====================
597 ::osl::MutexGuard aGuard( m_aMutex );
598 if ( m_bDisposed )
599 throw lang::DisposedException(); // TODO
601 if ( m_pInterfaceContainer )
602 m_pInterfaceContainer->removeInterface( cppu::UnoType<document::XEventListener>::get(),
603 xListener );
606 // XInplaceObject ( wrapper related implementation )
608 void SAL_CALL OleEmbeddedObject::setObjectRectangles( const awt::Rectangle& aPosRect,
609 const awt::Rectangle& aClipRect )
610 throw ( embed::WrongStateException,
611 uno::Exception,
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 );
620 return;
622 // end wrapping related part ====================
624 throw embed::WrongStateException();
628 void SAL_CALL OleEmbeddedObject::enableModeless( sal_Bool bEnable )
629 throw ( embed::WrongStateException,
630 uno::Exception,
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 );
639 return;
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 );
658 return;
660 // end wrapping related part ====================
664 // XChild
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 ====================
677 return m_xParent;
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 );
689 return;
691 // end wrapping related part ====================
693 m_xParent = xParent;
696 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */