nss: upgrade to release 3.73
[LibreOffice.git] / embeddedobj / source / msole / olemisc.cxx
blob90041729d03d7c1f9780fcde7ddd62d650952949
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/embed/WrongStateException.hpp>
27 #include <com/sun/star/lang/NoSupportException.hpp>
28 #include <com/sun/star/lang/XComponent.hpp>
29 #include <com/sun/star/lang/DisposedException.hpp>
31 #include <cppuhelper/interfacecontainer.h>
32 #include <comphelper/sequenceashashmap.hxx>
34 #include <oleembobj.hxx>
35 #include "olepersist.hxx"
37 #include "ownview.hxx"
39 #if defined(_WIN32)
40 #include "olecomponent.hxx"
41 #endif
43 using namespace ::com::sun::star;
46 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentContext >& xContext,
47 const uno::Sequence< sal_Int8 >& aClassID,
48 const OUString& aClassName )
49 : m_pOleComponent( nullptr )
50 , m_bReadOnly( false )
51 , m_bDisposed( false )
52 , m_nObjectState( -1 )
53 , m_nTargetState( -1 )
54 , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
55 , m_xContext( xContext )
56 , m_aClassID( aClassID )
57 , m_aClassName( aClassName )
58 , m_bWaitSaveCompleted( false )
59 , m_bNewVisReplInStream( true )
60 , m_bStoreLoaded( false )
61 , m_bVisReplInitialized( false )
62 , m_bVisReplInStream( false )
63 , m_bStoreVisRepl( false )
64 , m_bIsLink( false )
65 , m_bHasCachedSize( false )
66 , m_nCachedAspect( 0 )
67 , m_bHasSizeToSet( false )
68 , m_nAspectToSet( 0 )
69 , m_bGotStatus( false )
70 , m_nStatus( 0 )
71 , m_nStatusAspect( 0 )
72 , m_bFromClipboard( false )
73 , m_bTriedConversion( false )
78 // In case of loading from persistent entry the classID of the object
79 // will be retrieved from the entry, during construction it is unknown
80 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentContext >& xContext, bool bLink )
81 : m_pOleComponent( 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_xContext( xContext )
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_bFromClipboard( false )
103 , m_bTriedConversion( false )
106 #ifdef _WIN32
108 // this constructor let object be initialized from clipboard
109 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentContext >& xContext )
110 : m_pOleComponent( nullptr )
111 , m_bReadOnly( false )
112 , m_bDisposed( false )
113 , m_nObjectState( -1 )
114 , m_nTargetState( -1 )
115 , m_nUpdateMode( embed::EmbedUpdateModes::ALWAYS_UPDATE )
116 , m_xContext( xContext )
117 , m_bWaitSaveCompleted( false )
118 , m_bNewVisReplInStream( true )
119 , m_bStoreLoaded( false )
120 , m_bVisReplInitialized( false )
121 , m_bVisReplInStream( false )
122 , m_bStoreVisRepl( false )
123 , m_bIsLink( false )
124 , m_bHasCachedSize( false )
125 , m_nCachedAspect( 0 )
126 , m_bHasSizeToSet( false )
127 , m_nAspectToSet( 0 )
128 , m_bGotStatus( false )
129 , m_nStatus( 0 )
130 , m_nStatusAspect( 0 )
131 , m_bFromClipboard( true )
132 , m_bTriedConversion( false )
135 #endif
137 OleEmbeddedObject::~OleEmbeddedObject()
139 OSL_ENSURE( !m_pInterfaceContainer && !m_pOleComponent && !m_xObjectStream.is(),
140 "The object is not closed! DISASTER is possible!" );
142 if ( m_pOleComponent || m_pInterfaceContainer || m_xObjectStream.is() )
144 // the component must be cleaned during closing
145 osl_atomic_increment(&m_refCount); // to avoid crash
146 try {
147 Dispose();
148 } catch( const uno::Exception& ) {}
151 if ( !m_aTempURL.isEmpty() )
152 KillFile_Impl( m_aTempURL, m_xContext );
154 if ( !m_aTempDumpURL.isEmpty() )
155 KillFile_Impl( m_aTempDumpURL, m_xContext );
159 void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString& aEventName )
161 if ( !m_pInterfaceContainer )
162 return;
164 ::cppu::OInterfaceContainerHelper* pContainer =
165 m_pInterfaceContainer->getContainer(
166 cppu::UnoType<document::XEventListener>::get());
167 if ( pContainer == nullptr )
168 return;
170 document::EventObject aEvent( static_cast< ::cppu::OWeakObject* >( this ), aEventName );
171 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
172 while (pIterator.hasMoreElements())
176 static_cast<document::XEventListener*>(pIterator.next())->notifyEvent( aEvent );
178 catch( const uno::RuntimeException& )
183 #ifdef _WIN32
185 void OleEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState )
187 if ( m_pInterfaceContainer )
189 ::cppu::OInterfaceContainerHelper* pContainer = m_pInterfaceContainer->getContainer(
190 cppu::UnoType<embed::XStateChangeListener>::get());
191 if ( pContainer != nullptr )
193 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
194 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
196 while (pIterator.hasMoreElements())
198 if ( bBeforeChange )
202 static_cast<embed::XStateChangeListener*>(pIterator.next())->changingState( aSource, nOldState, nNewState );
204 catch( const uno::Exception& )
206 // even if the listener complains ignore it for now
209 else
213 static_cast<embed::XStateChangeListener*>(pIterator.next())->stateChanged( aSource, nOldState, nNewState );
215 catch( const uno::Exception& )
217 // if anything happened it is problem of listener, ignore it
224 #endif
226 void OleEmbeddedObject::GetRidOfComponent()
228 #ifdef _WIN32
229 if ( m_pOleComponent )
231 if ( m_nObjectState != -1 && m_nObjectState != embed::EmbedStates::LOADED )
232 SaveObject_Impl();
234 m_pOleComponent->removeCloseListener( m_xClosePreventer );
237 m_pOleComponent->close( false );
239 catch( const uno::Exception& )
241 // TODO: there should be a special listener to wait for component closing
242 // and to notify object, may be object itself can be such a listener
243 m_pOleComponent->addCloseListener( m_xClosePreventer );
244 throw;
247 m_pOleComponent->disconnectEmbeddedObject();
248 m_pOleComponent->release();
249 m_pOleComponent = nullptr;
251 #endif
255 void OleEmbeddedObject::Dispose()
257 if ( m_pInterfaceContainer )
259 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
260 m_pInterfaceContainer->disposeAndClear( aSource );
261 m_pInterfaceContainer.reset();
264 if ( m_xOwnView.is() )
266 m_xOwnView->Close();
267 m_xOwnView.clear();
270 if ( m_pOleComponent )
271 try {
272 GetRidOfComponent();
273 } catch( const uno::Exception& )
275 m_bDisposed = true;
276 throw; // TODO: there should be a special listener that will close object when
277 // component is finally closed
280 if ( m_xObjectStream.is() )
282 uno::Reference< lang::XComponent > xComp( m_xObjectStream, uno::UNO_QUERY );
283 OSL_ENSURE( xComp.is(), "Storage stream doesn't support XComponent!" );
285 if ( xComp.is() )
287 try {
288 xComp->dispose();
289 } catch( const uno::Exception& ) {}
291 m_xObjectStream.clear();
294 m_xParentStorage.clear();
296 m_bDisposed = true;
300 uno::Sequence< sal_Int8 > SAL_CALL OleEmbeddedObject::getClassID()
302 // begin wrapping related part ====================
303 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
304 if ( xWrappedObject.is() )
306 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
307 return xWrappedObject->getClassID();
309 // end wrapping related part ====================
311 ::osl::MutexGuard aGuard( m_aMutex );
312 if ( m_bDisposed )
313 throw lang::DisposedException(); // TODO
315 return m_aClassID;
319 OUString SAL_CALL OleEmbeddedObject::getClassName()
321 // begin wrapping related part ====================
322 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
323 if ( xWrappedObject.is() )
325 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
326 return xWrappedObject->getClassName();
328 // end wrapping related part ====================
330 ::osl::MutexGuard aGuard( m_aMutex );
331 if ( m_bDisposed )
332 throw lang::DisposedException(); // TODO
334 return m_aClassName;
338 void SAL_CALL OleEmbeddedObject::setClassInfo(
339 const uno::Sequence< sal_Int8 >& aClassID, const OUString& aClassName )
341 // begin wrapping related part ====================
342 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
343 if ( xWrappedObject.is() )
345 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
346 xWrappedObject->setClassInfo( aClassID, aClassName );
347 return;
349 // end wrapping related part ====================
351 // the object class info can not be changed explicitly
352 throw lang::NoSupportException(); //TODO:
356 uno::Reference< util::XCloseable > SAL_CALL OleEmbeddedObject::getComponent()
358 // begin wrapping related part ====================
359 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
360 if ( xWrappedObject.is() )
362 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
363 return xWrappedObject->getComponent();
365 // end wrapping related part ====================
367 ::osl::MutexGuard aGuard( m_aMutex );
368 if ( m_bDisposed )
369 throw lang::DisposedException(); // TODO
371 if ( m_nObjectState == -1 ) // || m_nObjectState == embed::EmbedStates::LOADED )
373 // the object is still not running
374 throw uno::RuntimeException( "The object is not loaded!",
375 static_cast< ::cppu::OWeakObject* >(this) );
378 #if defined(_WIN32)
379 if (m_pOleComponent != nullptr)
381 return uno::Reference< util::XCloseable >( static_cast< ::cppu::OWeakObject* >( m_pOleComponent ), uno::UNO_QUERY );
383 #endif
385 assert(m_pOleComponent == nullptr);
386 // TODO/LATER: Is it correct???
387 return uno::Reference< util::XCloseable >();
388 // throw uno::RuntimeException(); // TODO
392 void SAL_CALL OleEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener )
394 // begin wrapping related part ====================
395 if ( m_xWrappedObject.is() )
397 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
398 m_xWrappedObject->addStateChangeListener( xListener );
399 return;
401 // end wrapping related part ====================
403 ::osl::MutexGuard aGuard( m_aMutex );
404 if ( m_bDisposed )
405 throw lang::DisposedException(); // TODO
407 if ( !m_pInterfaceContainer )
408 m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
410 m_pInterfaceContainer->addInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
411 xListener );
415 void SAL_CALL OleEmbeddedObject::removeStateChangeListener(
416 const uno::Reference< embed::XStateChangeListener >& xListener )
418 // begin wrapping related part ====================
419 if ( m_xWrappedObject.is() )
421 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
422 m_xWrappedObject->removeStateChangeListener( xListener );
423 return;
425 // end wrapping related part ====================
427 ::osl::MutexGuard aGuard( m_aMutex );
428 if ( m_pInterfaceContainer )
429 m_pInterfaceContainer->removeInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
430 xListener );
434 void SAL_CALL OleEmbeddedObject::close( sal_Bool bDeliverOwnership )
436 // begin wrapping related part ====================
437 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
438 if ( xWrappedObject.is() )
440 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
441 xWrappedObject->close( bDeliverOwnership );
442 return;
444 // end wrapping related part ====================
446 ::osl::MutexGuard aGuard( m_aMutex );
447 if ( m_bDisposed )
448 throw lang::DisposedException(); // TODO
450 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
451 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
453 if ( m_pInterfaceContainer )
455 ::cppu::OInterfaceContainerHelper* pContainer =
456 m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
457 if ( pContainer != nullptr )
459 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
460 while (pIterator.hasMoreElements())
464 static_cast<util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership );
466 catch( const uno::RuntimeException& )
468 pIterator.remove();
473 pContainer = m_pInterfaceContainer->getContainer(
474 cppu::UnoType<util::XCloseListener>::get());
475 if ( pContainer != nullptr )
477 ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
478 while (pCloseIterator.hasMoreElements())
482 static_cast<util::XCloseListener*>(pCloseIterator.next())->notifyClosing( aSource );
484 catch( const uno::RuntimeException& )
486 pCloseIterator.remove();
492 Dispose();
496 void SAL_CALL OleEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
498 // begin wrapping related part ====================
499 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
500 if ( xWrappedObject.is() )
502 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
503 xWrappedObject->addCloseListener( xListener );
504 return;
506 // end wrapping related part ====================
508 ::osl::MutexGuard aGuard( m_aMutex );
509 if ( m_bDisposed )
510 throw lang::DisposedException(); // TODO
512 if ( !m_pInterfaceContainer )
513 m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
515 m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
519 void SAL_CALL OleEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
521 // begin wrapping related part ====================
522 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
523 if ( xWrappedObject.is() )
525 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
526 xWrappedObject->removeCloseListener( xListener );
527 return;
529 // end wrapping related part ====================
531 ::osl::MutexGuard aGuard( m_aMutex );
532 if ( m_bDisposed )
533 throw lang::DisposedException(); // TODO
535 if ( m_pInterfaceContainer )
536 m_pInterfaceContainer->removeInterface( cppu::UnoType<util::XCloseListener>::get(),
537 xListener );
541 void SAL_CALL OleEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener )
543 // begin wrapping related part ====================
544 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
545 if ( xWrappedObject.is() )
547 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
548 xWrappedObject->addEventListener( xListener );
549 return;
551 // end wrapping related part ====================
553 ::osl::MutexGuard aGuard( m_aMutex );
554 if ( m_bDisposed )
555 throw lang::DisposedException(); // TODO
557 if ( !m_pInterfaceContainer )
558 m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
560 m_pInterfaceContainer->addInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
564 void SAL_CALL OleEmbeddedObject::removeEventListener(
565 const uno::Reference< document::XEventListener >& xListener )
567 // begin wrapping related part ====================
568 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
569 if ( xWrappedObject.is() )
571 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
572 xWrappedObject->removeEventListener( xListener );
573 return;
575 // end wrapping related part ====================
577 ::osl::MutexGuard aGuard( m_aMutex );
578 if ( m_bDisposed )
579 throw lang::DisposedException(); // TODO
581 if ( m_pInterfaceContainer )
582 m_pInterfaceContainer->removeInterface( cppu::UnoType<document::XEventListener>::get(),
583 xListener );
586 // XInplaceObject ( wrapper related implementation )
588 void SAL_CALL OleEmbeddedObject::setObjectRectangles( const awt::Rectangle& aPosRect,
589 const awt::Rectangle& aClipRect )
591 // begin wrapping related part ====================
592 uno::Reference< embed::XInplaceObject > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
593 if ( xWrappedObject.is() )
595 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
596 xWrappedObject->setObjectRectangles( aPosRect, aClipRect );
597 return;
599 // end wrapping related part ====================
601 throw embed::WrongStateException();
605 void SAL_CALL OleEmbeddedObject::enableModeless( sal_Bool bEnable )
607 // begin wrapping related part ====================
608 uno::Reference< embed::XInplaceObject > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
609 if ( xWrappedObject.is() )
611 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
612 xWrappedObject->enableModeless( bEnable );
613 return;
615 // end wrapping related part ====================
617 throw embed::WrongStateException();
621 void SAL_CALL OleEmbeddedObject::translateAccelerators(
622 const uno::Sequence< awt::KeyEvent >& aKeys )
624 // begin wrapping related part ====================
625 uno::Reference< embed::XInplaceObject > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
626 if ( xWrappedObject.is() )
628 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
629 xWrappedObject->translateAccelerators( aKeys );
630 return;
632 // end wrapping related part ====================
636 // XChild
638 css::uno::Reference< css::uno::XInterface > SAL_CALL OleEmbeddedObject::getParent()
640 // begin wrapping related part ====================
641 uno::Reference< container::XChild > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
642 if ( xWrappedObject.is() )
644 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
645 return xWrappedObject->getParent();
647 // end wrapping related part ====================
649 return m_xParent;
653 void SAL_CALL OleEmbeddedObject::setParent( const css::uno::Reference< css::uno::XInterface >& xParent )
655 // begin wrapping related part ====================
656 uno::Reference< container::XChild > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
657 if ( xWrappedObject.is() )
659 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
660 xWrappedObject->setParent( xParent );
661 return;
663 // end wrapping related part ====================
665 m_xParent = xParent;
668 void OleEmbeddedObject::setStream(const css::uno::Reference<css::io::XStream>& xStream)
670 m_xObjectStream = xStream;
673 css::uno::Reference<css::io::XStream> OleEmbeddedObject::getStream()
675 return m_xObjectStream;
678 void OleEmbeddedObject::initialize(const uno::Sequence<uno::Any>& rArguments)
680 if (!rArguments.hasElements())
681 return;
683 comphelper::SequenceAsHashMap aValues(rArguments[0]);
684 for (const auto& rValue : aValues)
686 if (rValue.first == "StreamReadOnly")
687 rValue.second >>= m_bStreamReadOnly;
691 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */