Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / embeddedobj / source / msole / olemisc.cxx
blob6d371d428fd647f6d50e8e12efe4e9f15a8af5a2
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 <comphelper/multicontainer2.hxx>
32 #include <comphelper/sequenceashashmap.hxx>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <osl/diagnose.h>
36 #include <oleembobj.hxx>
37 #include <utility>
38 #include "olepersist.hxx"
40 #include "ownview.hxx"
42 #include "olecomponent.hxx"
44 using namespace ::com::sun::star;
47 OleEmbeddedObject::OleEmbeddedObject( uno::Reference< uno::XComponentContext > xContext,
48 const uno::Sequence< sal_Int8 >& aClassID,
49 OUString aClassName )
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(std::move( xContext ))
56 , m_aClassID( aClassID )
57 , m_aClassName(std::move( 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( uno::Reference< uno::XComponentContext > xContext, bool bLink )
81 : m_bReadOnly( false )
82 , m_bDisposed( false )
83 , m_nObjectState( -1 )
84 , m_nTargetState( -1 )
85 , m_nUpdateMode( embed::EmbedUpdateModes::ALWAYS_UPDATE )
86 , m_xContext(std::move( xContext ))
87 , m_bWaitSaveCompleted( false )
88 , m_bNewVisReplInStream( true )
89 , m_bStoreLoaded( false )
90 , m_bVisReplInitialized( false )
91 , m_bVisReplInStream( false )
92 , m_bStoreVisRepl( false )
93 , m_bIsLink( bLink )
94 , m_bHasCachedSize( false )
95 , m_nCachedAspect( 0 )
96 , m_bHasSizeToSet( false )
97 , m_nAspectToSet( 0 )
98 , m_bGotStatus( false )
99 , m_nStatus( 0 )
100 , m_nStatusAspect( 0 )
101 , m_bFromClipboard( false )
102 , m_bTriedConversion( false )
105 #ifdef _WIN32
107 // this constructor let object be initialized from clipboard
108 OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentContext >& xContext )
109 : m_bReadOnly( false )
110 , m_bDisposed( false )
111 , m_nObjectState( -1 )
112 , m_nTargetState( -1 )
113 , m_nUpdateMode( embed::EmbedUpdateModes::ALWAYS_UPDATE )
114 , m_xContext( xContext )
115 , m_bWaitSaveCompleted( false )
116 , m_bNewVisReplInStream( true )
117 , m_bStoreLoaded( false )
118 , m_bVisReplInitialized( false )
119 , m_bVisReplInStream( false )
120 , m_bStoreVisRepl( false )
121 , m_bIsLink( false )
122 , m_bHasCachedSize( false )
123 , m_nCachedAspect( 0 )
124 , m_bHasSizeToSet( false )
125 , m_nAspectToSet( 0 )
126 , m_bGotStatus( false )
127 , m_nStatus( 0 )
128 , m_nStatusAspect( 0 )
129 , m_bFromClipboard( true )
130 , m_bTriedConversion( false )
133 #endif
135 OleEmbeddedObject::~OleEmbeddedObject()
137 OSL_ENSURE( !m_pInterfaceContainer && !m_pOleComponent && !m_xObjectStream.is(),
138 "The object is not closed! DISASTER is possible!" );
140 if ( m_pOleComponent || m_pInterfaceContainer || m_xObjectStream.is() )
142 // the component must be cleaned during closing
143 osl_atomic_increment(&m_refCount); // to avoid crash
144 try {
145 Dispose();
146 } catch( const uno::Exception& ) {}
149 if ( !m_aTempURL.isEmpty() )
150 KillFile_Impl( m_aTempURL, m_xContext );
152 if ( !m_aTempDumpURL.isEmpty() )
153 KillFile_Impl( m_aTempDumpURL, m_xContext );
157 void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString& aEventName )
159 if ( !m_pInterfaceContainer )
160 return;
162 comphelper::OInterfaceContainerHelper2* pContainer =
163 m_pInterfaceContainer->getContainer(
164 cppu::UnoType<document::XEventListener>::get());
165 if ( pContainer == nullptr )
166 return;
168 document::EventObject aEvent( static_cast< ::cppu::OWeakObject* >( this ), aEventName );
169 comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
170 while (pIterator.hasMoreElements())
174 static_cast<document::XEventListener*>(pIterator.next())->notifyEvent( aEvent );
176 catch( const uno::RuntimeException& )
181 #ifdef _WIN32
183 void OleEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState )
185 if ( m_pInterfaceContainer )
187 comphelper::OInterfaceContainerHelper2* pContainer = m_pInterfaceContainer->getContainer(
188 cppu::UnoType<embed::XStateChangeListener>::get());
189 if ( pContainer != nullptr )
191 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
192 comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
194 while (pIterator.hasMoreElements())
196 if ( bBeforeChange )
200 static_cast<embed::XStateChangeListener*>(pIterator.next())->changingState( aSource, nOldState, nNewState );
202 catch( const uno::Exception& )
204 // even if the listener complains ignore it for now
207 else
211 static_cast<embed::XStateChangeListener*>(pIterator.next())->stateChanged( aSource, nOldState, nNewState );
213 catch( const uno::Exception& )
215 // if anything happened it is problem of listener, ignore it
222 #endif
224 void OleEmbeddedObject::GetRidOfComponent()
226 #ifdef _WIN32
227 if ( m_pOleComponent )
229 if ( m_nObjectState != -1 && m_nObjectState != embed::EmbedStates::LOADED )
230 SaveObject_Impl();
232 m_pOleComponent->removeCloseListener( m_xClosePreventer );
235 m_pOleComponent->close( false );
237 catch( const uno::Exception& )
239 // TODO: there should be a special listener to wait for component closing
240 // and to notify object, may be object itself can be such a listener
241 m_pOleComponent->addCloseListener( m_xClosePreventer );
242 throw;
245 m_pOleComponent->disconnectEmbeddedObject();
246 m_pOleComponent.clear();
248 #endif
252 void OleEmbeddedObject::Dispose()
254 if ( m_pInterfaceContainer )
256 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
257 m_pInterfaceContainer->disposeAndClear( aSource );
258 m_pInterfaceContainer.reset();
261 if ( m_xOwnView.is() )
263 m_xOwnView->Close();
264 m_xOwnView.clear();
267 if ( m_pOleComponent )
268 try {
269 GetRidOfComponent();
270 } catch( const uno::Exception& )
272 m_bDisposed = true;
273 throw; // TODO: there should be a special listener that will close object when
274 // component is finally closed
277 if ( m_xObjectStream.is() )
279 uno::Reference< lang::XComponent > xComp( m_xObjectStream, uno::UNO_QUERY );
280 OSL_ENSURE( xComp.is(), "Storage stream doesn't support XComponent!" );
282 if ( xComp.is() )
284 try {
285 xComp->dispose();
286 } catch( const uno::Exception& ) {}
288 m_xObjectStream.clear();
291 m_xParentStorage.clear();
293 m_bDisposed = true;
297 uno::Sequence< sal_Int8 > SAL_CALL OleEmbeddedObject::getClassID()
299 // begin wrapping related part ====================
300 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
301 if ( xWrappedObject.is() )
303 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
304 return xWrappedObject->getClassID();
306 // end wrapping related part ====================
308 ::osl::MutexGuard aGuard( m_aMutex );
309 if ( m_bDisposed )
310 throw lang::DisposedException(); // TODO
312 return m_aClassID;
316 OUString SAL_CALL OleEmbeddedObject::getClassName()
318 // begin wrapping related part ====================
319 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
320 if ( xWrappedObject.is() )
322 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
323 return xWrappedObject->getClassName();
325 // end wrapping related part ====================
327 ::osl::MutexGuard aGuard( m_aMutex );
328 if ( m_bDisposed )
329 throw lang::DisposedException(); // TODO
331 return m_aClassName;
335 void SAL_CALL OleEmbeddedObject::setClassInfo(
336 const uno::Sequence< sal_Int8 >& aClassID, const OUString& aClassName )
338 // begin wrapping related part ====================
339 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
340 if ( xWrappedObject.is() )
342 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
343 xWrappedObject->setClassInfo( aClassID, aClassName );
344 return;
346 // end wrapping related part ====================
348 // the object class info can not be changed explicitly
349 throw lang::NoSupportException(); //TODO:
353 uno::Reference< util::XCloseable > SAL_CALL OleEmbeddedObject::getComponent()
355 // begin wrapping related part ====================
356 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
357 if ( xWrappedObject.is() )
359 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
360 return xWrappedObject->getComponent();
362 // end wrapping related part ====================
364 ::osl::MutexGuard aGuard( m_aMutex );
365 if ( m_bDisposed )
366 throw lang::DisposedException(); // TODO
368 if ( m_nObjectState == -1 ) // || m_nObjectState == embed::EmbedStates::LOADED )
370 // the object is still not running
371 throw uno::RuntimeException( "The object is not loaded!",
372 static_cast< ::cppu::OWeakObject* >(this) );
375 #if defined(_WIN32)
376 if (m_pOleComponent.is())
378 return uno::Reference< util::XCloseable >( m_pOleComponent );
380 #endif
382 assert(!m_pOleComponent.is());
383 // TODO/LATER: Is it correct???
384 return uno::Reference< util::XCloseable >();
385 // throw uno::RuntimeException(); // TODO
389 void SAL_CALL OleEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener )
391 // begin wrapping related part ====================
392 if ( m_xWrappedObject.is() )
394 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
395 m_xWrappedObject->addStateChangeListener( xListener );
396 return;
398 // end wrapping related part ====================
400 ::osl::MutexGuard aGuard( m_aMutex );
401 if ( m_bDisposed )
402 throw lang::DisposedException(); // TODO
404 if ( !m_pInterfaceContainer )
405 m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
407 m_pInterfaceContainer->addInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
408 xListener );
412 void SAL_CALL OleEmbeddedObject::removeStateChangeListener(
413 const uno::Reference< embed::XStateChangeListener >& xListener )
415 // begin wrapping related part ====================
416 if ( m_xWrappedObject.is() )
418 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
419 m_xWrappedObject->removeStateChangeListener( xListener );
420 return;
422 // end wrapping related part ====================
424 ::osl::MutexGuard aGuard( m_aMutex );
425 if ( m_pInterfaceContainer )
426 m_pInterfaceContainer->removeInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
427 xListener );
431 void SAL_CALL OleEmbeddedObject::close( sal_Bool bDeliverOwnership )
433 // begin wrapping related part ====================
434 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
435 if ( xWrappedObject.is() )
437 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
438 xWrappedObject->close( bDeliverOwnership );
439 return;
441 // end wrapping related part ====================
443 ::osl::MutexGuard aGuard( m_aMutex );
444 if ( m_bDisposed )
445 throw lang::DisposedException(); // TODO
447 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
448 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
450 if ( m_pInterfaceContainer )
452 comphelper::OInterfaceContainerHelper2* pContainer =
453 m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
454 if ( pContainer != nullptr )
456 comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
457 while (pIterator.hasMoreElements())
461 static_cast<util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership );
463 catch( const uno::RuntimeException& )
465 pIterator.remove();
470 pContainer = m_pInterfaceContainer->getContainer(
471 cppu::UnoType<util::XCloseListener>::get());
472 if ( pContainer != nullptr )
474 comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer);
475 while (pCloseIterator.hasMoreElements())
479 static_cast<util::XCloseListener*>(pCloseIterator.next())->notifyClosing( aSource );
481 catch( const uno::RuntimeException& )
483 pCloseIterator.remove();
489 Dispose();
493 void SAL_CALL OleEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
495 // begin wrapping related part ====================
496 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
497 if ( xWrappedObject.is() )
499 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
500 xWrappedObject->addCloseListener( xListener );
501 return;
503 // end wrapping related part ====================
505 ::osl::MutexGuard aGuard( m_aMutex );
506 if ( m_bDisposed )
507 throw lang::DisposedException(); // TODO
509 if ( !m_pInterfaceContainer )
510 m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
512 m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
516 void SAL_CALL OleEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
518 // begin wrapping related part ====================
519 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
520 if ( xWrappedObject.is() )
522 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
523 xWrappedObject->removeCloseListener( xListener );
524 return;
526 // end wrapping related part ====================
528 ::osl::MutexGuard aGuard( m_aMutex );
529 if ( m_bDisposed )
530 throw lang::DisposedException(); // TODO
532 if ( m_pInterfaceContainer )
533 m_pInterfaceContainer->removeInterface( cppu::UnoType<util::XCloseListener>::get(),
534 xListener );
538 void SAL_CALL OleEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener )
540 // begin wrapping related part ====================
541 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
542 if ( xWrappedObject.is() )
544 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
545 xWrappedObject->addEventListener( xListener );
546 return;
548 // end wrapping related part ====================
550 ::osl::MutexGuard aGuard( m_aMutex );
551 if ( m_bDisposed )
552 throw lang::DisposedException(); // TODO
554 if ( !m_pInterfaceContainer )
555 m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
557 m_pInterfaceContainer->addInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
561 void SAL_CALL OleEmbeddedObject::removeEventListener(
562 const uno::Reference< document::XEventListener >& xListener )
564 // begin wrapping related part ====================
565 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
566 if ( xWrappedObject.is() )
568 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
569 xWrappedObject->removeEventListener( xListener );
570 return;
572 // end wrapping related part ====================
574 ::osl::MutexGuard aGuard( m_aMutex );
575 if ( m_bDisposed )
576 throw lang::DisposedException(); // TODO
578 if ( m_pInterfaceContainer )
579 m_pInterfaceContainer->removeInterface( cppu::UnoType<document::XEventListener>::get(),
580 xListener );
583 // XInplaceObject ( wrapper related implementation )
585 void SAL_CALL OleEmbeddedObject::setObjectRectangles( const awt::Rectangle& aPosRect,
586 const awt::Rectangle& aClipRect )
588 // begin wrapping related part ====================
589 uno::Reference< embed::XInplaceObject > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
590 if ( xWrappedObject.is() )
592 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
593 xWrappedObject->setObjectRectangles( aPosRect, aClipRect );
594 return;
596 // end wrapping related part ====================
598 throw embed::WrongStateException();
602 void SAL_CALL OleEmbeddedObject::enableModeless( sal_Bool bEnable )
604 // begin wrapping related part ====================
605 uno::Reference< embed::XInplaceObject > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
606 if ( xWrappedObject.is() )
608 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
609 xWrappedObject->enableModeless( bEnable );
610 return;
612 // end wrapping related part ====================
614 throw embed::WrongStateException();
618 void SAL_CALL OleEmbeddedObject::translateAccelerators(
619 const uno::Sequence< awt::KeyEvent >& aKeys )
621 // begin wrapping related part ====================
622 uno::Reference< embed::XInplaceObject > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
623 if ( xWrappedObject.is() )
625 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
626 xWrappedObject->translateAccelerators( aKeys );
627 return;
629 // end wrapping related part ====================
633 // XChild
635 css::uno::Reference< css::uno::XInterface > SAL_CALL OleEmbeddedObject::getParent()
637 // begin wrapping related part ====================
638 uno::Reference< container::XChild > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
639 if ( xWrappedObject.is() )
641 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
642 return xWrappedObject->getParent();
644 // end wrapping related part ====================
646 return m_xParent;
650 void SAL_CALL OleEmbeddedObject::setParent( const css::uno::Reference< css::uno::XInterface >& xParent )
652 // begin wrapping related part ====================
653 uno::Reference< container::XChild > 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->setParent( xParent );
658 return;
660 // end wrapping related part ====================
662 m_xParent = xParent;
665 void OleEmbeddedObject::setStream(const css::uno::Reference<css::io::XStream>& xStream)
667 m_xObjectStream = xStream;
670 css::uno::Reference<css::io::XStream> OleEmbeddedObject::getStream()
672 return m_xObjectStream;
675 void OleEmbeddedObject::initialize(const uno::Sequence<uno::Any>& rArguments)
677 if (!rArguments.hasElements())
678 return;
680 comphelper::SequenceAsHashMap aValues(rArguments[0]);
681 auto it = aValues.find("StreamReadOnly");
682 if (it != aValues.end())
683 it->second >>= m_bStreamReadOnly;
686 OUString SAL_CALL OleEmbeddedObject::getImplementationName()
688 return "com.sun.star.comp.embed.OleEmbeddedObject";
691 sal_Bool SAL_CALL OleEmbeddedObject::supportsService(const OUString& ServiceName)
693 return cppu::supportsService(this, ServiceName);
696 uno::Sequence<OUString> SAL_CALL OleEmbeddedObject::getSupportedServiceNames()
698 return { "com.sun.star.comp.embed.OleEmbeddedObject" };
701 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */