Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <commonembobj.hxx>
21 : #include <com/sun/star/embed/EmbedStates.hpp>
22 : #include <com/sun/star/embed/EmbedVerbs.hpp>
23 : #include <com/sun/star/embed/XStorage.hpp>
24 : #include <com/sun/star/embed/EmbedUpdateModes.hpp>
25 : #include <com/sun/star/embed/XInplaceClient.hpp>
26 : #include <com/sun/star/lang/DisposedException.hpp>
27 : #include <com/sun/star/beans/NamedValue.hpp>
28 :
29 : #include <cppuhelper/typeprovider.hxx>
30 : #include <cppuhelper/queryinterface.hxx>
31 : #include <cppuhelper/interfacecontainer.h>
32 : #include <comphelper/mimeconfighelper.hxx>
33 : #include <comphelper/processfactory.hxx>
34 :
35 : #include "closepreventer.hxx"
36 : #include "intercept.hxx"
37 : #include "persistence.hxx"
38 :
39 : using namespace ::com::sun::star;
40 :
41 :
42 578 : OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< uno::XComponentContext >& rxContext,
43 : const uno::Sequence< beans::NamedValue >& aObjProps )
44 : : m_pDocHolder( NULL )
45 : , m_pInterfaceContainer( NULL )
46 : , m_bReadOnly( false )
47 : , m_bDisposed( false )
48 : , m_bClosed( false )
49 : , m_nObjectState( -1 )
50 : , m_nTargetState( -1 )
51 : , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
52 : , m_xContext( rxContext )
53 : , m_nMiscStatus( 0 )
54 : , m_bEmbeddedScriptSupport( true )
55 : , m_bDocumentRecoverySupport( true )
56 : , m_bWaitSaveCompleted( false )
57 : , m_bIsLink( false )
58 : , m_bLinkHasPassword( false )
59 : , m_bHasClonedSize( false )
60 578 : , m_nClonedMapUnit( 0 )
61 : {
62 578 : CommonInit_Impl( aObjProps );
63 578 : }
64 :
65 :
66 0 : OCommonEmbeddedObject::OCommonEmbeddedObject(
67 : const uno::Reference< uno::XComponentContext >& rxContext,
68 : const uno::Sequence< beans::NamedValue >& aObjProps,
69 : const uno::Sequence< beans::PropertyValue >& aMediaDescr,
70 : const uno::Sequence< beans::PropertyValue >& aObjectDescr )
71 : : m_pDocHolder( NULL )
72 : , m_pInterfaceContainer( NULL )
73 : , m_bReadOnly( false )
74 : , m_bDisposed( false )
75 : , m_bClosed( false )
76 : , m_nObjectState( embed::EmbedStates::LOADED )
77 : , m_nTargetState( -1 )
78 : , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
79 : , m_xContext( rxContext )
80 : , m_nMiscStatus( 0 )
81 : , m_bEmbeddedScriptSupport( true )
82 : , m_bDocumentRecoverySupport( true )
83 : , m_bWaitSaveCompleted( false )
84 : , m_bIsLink( true )
85 : , m_bLinkHasPassword( false )
86 : , m_bHasClonedSize( false )
87 0 : , m_nClonedMapUnit( 0 )
88 : {
89 : // linked object has no own persistence so it is in loaded state starting from creation
90 0 : LinkInit_Impl( aObjProps, aMediaDescr, aObjectDescr );
91 0 : }
92 :
93 :
94 578 : void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedValue >& aObjectProps )
95 : {
96 : OSL_ENSURE( m_xContext.is(), "No ServiceFactory is provided!\n" );
97 578 : if ( !m_xContext.is() )
98 0 : throw uno::RuntimeException();
99 :
100 578 : m_pDocHolder = new DocumentHolder( m_xContext, this );
101 578 : m_pDocHolder->acquire();
102 :
103 : // parse configuration entries
104 : // TODO/LATER: in future UI names can be also provided here
105 4018 : for ( sal_Int32 nInd = 0; nInd < aObjectProps.getLength(); nInd++ )
106 : {
107 3440 : if ( aObjectProps[nInd].Name == "ClassID" )
108 578 : aObjectProps[nInd].Value >>= m_aClassID;
109 2862 : else if ( aObjectProps[nInd].Name == "ObjectDocumentServiceName" )
110 571 : aObjectProps[nInd].Value >>= m_aDocServiceName;
111 2291 : else if ( aObjectProps[nInd].Name == "ObjectDocumentFilterName" )
112 571 : aObjectProps[nInd].Value >>= m_aPresetFilterName;
113 1720 : else if ( aObjectProps[nInd].Name == "ObjectMiscStatus" )
114 571 : aObjectProps[nInd].Value >>= m_nMiscStatus;
115 1149 : else if ( aObjectProps[nInd].Name == "ObjectVerbs" )
116 571 : aObjectProps[nInd].Value >>= m_aObjectVerbs;
117 : }
118 :
119 578 : if ( m_aClassID.getLength() != 16 /*|| !m_aDocServiceName.getLength()*/ )
120 0 : throw uno::RuntimeException(); // something goes really wrong
121 :
122 : // accepted states
123 578 : m_aAcceptedStates.realloc( NUM_SUPPORTED_STATES );
124 :
125 578 : m_aAcceptedStates[0] = embed::EmbedStates::LOADED;
126 578 : m_aAcceptedStates[1] = embed::EmbedStates::RUNNING;
127 578 : m_aAcceptedStates[2] = embed::EmbedStates::INPLACE_ACTIVE;
128 578 : m_aAcceptedStates[3] = embed::EmbedStates::UI_ACTIVE;
129 578 : m_aAcceptedStates[4] = embed::EmbedStates::ACTIVE;
130 :
131 :
132 : // intermediate states
133 : // In the following table the first index points to starting state,
134 : // the second one to the target state, and the sequence referenced by
135 : // first two indexes contains intermediate states, that should be
136 : // passed by object to reach the target state.
137 : // If the sequence is empty that means that indirect switch from start
138 : // state to the target state is forbidden, only if direct switch is possible
139 : // the state can be reached.
140 :
141 578 : m_pIntermediateStatesSeqs[0][2].realloc( 1 );
142 578 : m_pIntermediateStatesSeqs[0][2][0] = embed::EmbedStates::RUNNING;
143 :
144 578 : m_pIntermediateStatesSeqs[0][3].realloc( 2 );
145 578 : m_pIntermediateStatesSeqs[0][3][0] = embed::EmbedStates::RUNNING;
146 578 : m_pIntermediateStatesSeqs[0][3][1] = embed::EmbedStates::INPLACE_ACTIVE;
147 :
148 578 : m_pIntermediateStatesSeqs[0][4].realloc( 1 );
149 578 : m_pIntermediateStatesSeqs[0][4][0] = embed::EmbedStates::RUNNING;
150 :
151 578 : m_pIntermediateStatesSeqs[1][3].realloc( 1 );
152 578 : m_pIntermediateStatesSeqs[1][3][0] = embed::EmbedStates::INPLACE_ACTIVE;
153 :
154 578 : m_pIntermediateStatesSeqs[2][0].realloc( 1 );
155 578 : m_pIntermediateStatesSeqs[2][0][0] = embed::EmbedStates::RUNNING;
156 :
157 578 : m_pIntermediateStatesSeqs[3][0].realloc( 2 );
158 578 : m_pIntermediateStatesSeqs[3][0][0] = embed::EmbedStates::INPLACE_ACTIVE;
159 578 : m_pIntermediateStatesSeqs[3][0][1] = embed::EmbedStates::RUNNING;
160 :
161 578 : m_pIntermediateStatesSeqs[3][1].realloc( 1 );
162 578 : m_pIntermediateStatesSeqs[3][1][0] = embed::EmbedStates::INPLACE_ACTIVE;
163 :
164 578 : m_pIntermediateStatesSeqs[4][0].realloc( 1 );
165 578 : m_pIntermediateStatesSeqs[4][0][0] = embed::EmbedStates::RUNNING;
166 :
167 : // verbs table
168 578 : sal_Int32 nVerbTableSize = 0;
169 4305 : for ( sal_Int32 nVerbInd = 0; nVerbInd < m_aObjectVerbs.getLength(); nVerbInd++ )
170 : {
171 3727 : if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_PRIMARY )
172 : {
173 571 : m_aVerbTable.realloc( ++nVerbTableSize );
174 571 : m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
175 571 : m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
176 571 : m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
177 : }
178 3156 : else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_SHOW )
179 : {
180 571 : m_aVerbTable.realloc( ++nVerbTableSize );
181 571 : m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
182 571 : m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
183 571 : m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
184 : }
185 2585 : else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN )
186 : {
187 570 : m_aVerbTable.realloc( ++nVerbTableSize );
188 570 : m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
189 570 : m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
190 570 : m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::ACTIVE;
191 : }
192 2015 : else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_IPACTIVATE )
193 : {
194 571 : m_aVerbTable.realloc( ++nVerbTableSize );
195 571 : m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
196 571 : m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
197 571 : m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::INPLACE_ACTIVE;
198 : }
199 1444 : else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_UIACTIVATE )
200 : {
201 570 : m_aVerbTable.realloc( ++nVerbTableSize );
202 570 : m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
203 570 : m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
204 570 : m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
205 : }
206 874 : else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_HIDE )
207 : {
208 570 : m_aVerbTable.realloc( ++nVerbTableSize );
209 570 : m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
210 570 : m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
211 570 : m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::RUNNING;
212 : }
213 : }
214 578 : }
215 :
216 :
217 0 : void OCommonEmbeddedObject::LinkInit_Impl(
218 : const uno::Sequence< beans::NamedValue >& aObjectProps,
219 : const uno::Sequence< beans::PropertyValue >& aMediaDescr,
220 : const uno::Sequence< beans::PropertyValue >& aObjectDescr )
221 : {
222 : // setPersistance has no effect on own links, so the complete initialization must be done here
223 :
224 0 : for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ )
225 0 : if ( aMediaDescr[nInd].Name == "URL" )
226 0 : aMediaDescr[nInd].Value >>= m_aLinkURL;
227 0 : else if ( aMediaDescr[nInd].Name == "FilterName" )
228 0 : aMediaDescr[nInd].Value >>= m_aLinkFilterName;
229 :
230 : OSL_ENSURE( m_aLinkURL.getLength() && m_aLinkFilterName.getLength(), "Filter and URL must be provided!\n" );
231 :
232 0 : m_bReadOnly = true;
233 0 : if ( m_aLinkFilterName.getLength() )
234 : {
235 0 : ::comphelper::MimeConfigurationHelper aHelper( m_xContext );
236 0 : OUString aExportFilterName = aHelper.GetExportFilterFromImportFilter( m_aLinkFilterName );
237 0 : m_bReadOnly = !( aExportFilterName.equals( m_aLinkFilterName ) );
238 : }
239 :
240 0 : m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, false );
241 :
242 0 : uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
243 0 : for ( sal_Int32 nObjInd = 0; nObjInd < aObjectDescr.getLength(); nObjInd++ )
244 0 : if ( aObjectDescr[nObjInd].Name == "OutplaceDispatchInterceptor" )
245 : {
246 0 : aObjectDescr[nObjInd].Value >>= xDispatchInterceptor;
247 0 : break;
248 : }
249 0 : else if ( aObjectDescr[nObjInd].Name == "Parent" )
250 : {
251 0 : aObjectDescr[nObjInd].Value >>= m_xParent;
252 : }
253 :
254 0 : CommonInit_Impl( aObjectProps );
255 :
256 0 : if ( xDispatchInterceptor.is() )
257 0 : m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
258 0 : }
259 :
260 :
261 1726 : OCommonEmbeddedObject::~OCommonEmbeddedObject()
262 : {
263 578 : if ( m_pInterfaceContainer || m_pDocHolder )
264 : {
265 578 : m_refCount++;
266 : try {
267 578 : lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
268 :
269 578 : if ( m_pInterfaceContainer )
270 : {
271 574 : m_pInterfaceContainer->disposeAndClear( aSource );
272 :
273 574 : delete m_pInterfaceContainer;
274 574 : m_pInterfaceContainer = NULL;
275 578 : }
276 0 : } catch( const uno::Exception& ) {}
277 :
278 : try {
279 578 : if ( m_pDocHolder )
280 : {
281 4 : m_pDocHolder->CloseFrame();
282 : try {
283 4 : m_pDocHolder->CloseDocument( true, true );
284 0 : } catch ( const uno::Exception& ) {}
285 4 : m_pDocHolder->FreeOffice();
286 :
287 4 : m_pDocHolder->release();
288 4 : m_pDocHolder = NULL;
289 : }
290 0 : } catch( const uno::Exception& ) {}
291 : }
292 1148 : }
293 :
294 :
295 0 : void OCommonEmbeddedObject::requestPositioning( const awt::Rectangle& aRect )
296 : {
297 : // the method is called in case object is inplace active and the object window was resized
298 :
299 : OSL_ENSURE( m_xClientSite.is(), "The client site must be set for inplace active object!\n" );
300 0 : if ( m_xClientSite.is() )
301 : {
302 0 : uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
303 :
304 : OSL_ENSURE( xInplaceClient.is(), "The client site must support XInplaceClient to allow inplace activation!\n" );
305 0 : if ( xInplaceClient.is() )
306 : {
307 : try {
308 0 : xInplaceClient->changedPlacement( aRect );
309 : }
310 0 : catch( const uno::Exception& )
311 : {
312 : OSL_FAIL( "Exception on request to resize!\n" );
313 : }
314 0 : }
315 : }
316 0 : }
317 :
318 :
319 7498 : void OCommonEmbeddedObject::PostEvent_Impl( const OUString& aEventName )
320 : {
321 7498 : if ( m_pInterfaceContainer )
322 : {
323 : ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer(
324 6431 : cppu::UnoType<document::XEventListener>::get());
325 6431 : if( pIC )
326 : {
327 6431 : document::EventObject aEvent;
328 6431 : aEvent.EventName = aEventName;
329 6431 : aEvent.Source = uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) );
330 : // For now all the events are sent as object events
331 : // aEvent.Source = ( xSource.is() ? xSource
332 : // : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) );
333 12862 : ::cppu::OInterfaceIteratorHelper aIt( *pIC );
334 23391 : while( aIt.hasMoreElements() )
335 : {
336 : try
337 : {
338 10529 : static_cast<document::XEventListener *>(aIt.next())->notifyEvent( aEvent );
339 : }
340 0 : catch( const uno::RuntimeException& )
341 : {
342 0 : aIt.remove();
343 : }
344 :
345 : // the listener could dispose the object.
346 10529 : if ( m_bDisposed )
347 7498 : return;
348 6431 : }
349 : }
350 : }
351 : }
352 :
353 :
354 15885 : uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType )
355 : throw( uno::RuntimeException, std::exception )
356 : {
357 15885 : uno::Any aReturn;
358 :
359 15885 : if ( rType == cppu::UnoType<embed::XEmbeddedObject>::get() )
360 : {
361 566 : void * p = static_cast< embed::XEmbeddedObject * >( this );
362 566 : return uno::Any( &p, rType );
363 : }
364 15319 : else if (rType == cppu::UnoType<embed::XEmbedPersist2>::get())
365 : {
366 0 : void* p = static_cast<embed::XEmbedPersist2*>(this);
367 0 : return uno::Any(&p, rType);
368 : }
369 : else
370 30638 : aReturn <<= ::cppu::queryInterface(
371 : rType,
372 : static_cast< embed::XInplaceObject* >( this ),
373 : static_cast< embed::XVisualObject* >( this ),
374 : static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ),
375 : static_cast< embed::XEmbedPersist* >( this ),
376 : static_cast< embed::XLinkageSupport* >( this ),
377 : static_cast< embed::XStateChangeBroadcaster* >( this ),
378 : static_cast< embed::XClassifiedObject* >( this ),
379 : static_cast< embed::XComponentSupplier* >( this ),
380 : static_cast< util::XCloseable* >( this ),
381 : static_cast< container::XChild* >( this ),
382 : static_cast< chart2::XDefaultSizeTransmitter* >( this ),
383 15319 : static_cast< document::XEventBroadcaster* >( this ) );
384 :
385 15319 : if ( aReturn.hasValue() )
386 12438 : return aReturn;
387 : else
388 2881 : return ::cppu::OWeakObject::queryInterface( rType ) ;
389 :
390 : }
391 :
392 :
393 80178 : void SAL_CALL OCommonEmbeddedObject::acquire()
394 : throw()
395 : {
396 80178 : ::cppu::OWeakObject::acquire() ;
397 80178 : }
398 :
399 :
400 80178 : void SAL_CALL OCommonEmbeddedObject::release()
401 : throw()
402 : {
403 80178 : ::cppu::OWeakObject::release() ;
404 80178 : }
405 :
406 :
407 0 : uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes()
408 : throw( uno::RuntimeException )
409 : {
410 : static ::cppu::OTypeCollection* pTypeCollection = NULL;
411 :
412 0 : if ( !pTypeCollection )
413 : {
414 0 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
415 0 : if ( !pTypeCollection )
416 : {
417 0 : if ( m_bIsLink )
418 : {
419 : static ::cppu::OTypeCollection aTypeCollection(
420 0 : cppu::UnoType<lang::XTypeProvider>::get(),
421 0 : cppu::UnoType<embed::XEmbeddedObject>::get(),
422 0 : cppu::UnoType<embed::XInplaceObject>::get(),
423 0 : cppu::UnoType<embed::XCommonEmbedPersist>::get(),
424 0 : cppu::UnoType<container::XChild>::get(),
425 0 : cppu::UnoType<embed::XLinkageSupport>::get());
426 :
427 0 : pTypeCollection = &aTypeCollection ;
428 : }
429 : else
430 : {
431 : static ::cppu::OTypeCollection aTypeCollection(
432 0 : cppu::UnoType<lang::XTypeProvider>::get(),
433 0 : cppu::UnoType<embed::XEmbeddedObject>::get(),
434 0 : cppu::UnoType<embed::XInplaceObject>::get(),
435 0 : cppu::UnoType<embed::XCommonEmbedPersist>::get(),
436 0 : cppu::UnoType<container::XChild>::get(),
437 0 : cppu::UnoType<embed::XEmbedPersist>::get(),
438 0 : cppu::UnoType<embed::XEmbedPersist2>::get());
439 :
440 0 : pTypeCollection = &aTypeCollection ;
441 : }
442 0 : }
443 : }
444 :
445 0 : return pTypeCollection->getTypes() ;
446 :
447 : }
448 :
449 8347 : uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID()
450 : throw ( uno::RuntimeException, std::exception )
451 : {
452 8347 : if ( m_bDisposed )
453 0 : throw lang::DisposedException();
454 :
455 8347 : return m_aClassID;
456 : }
457 :
458 0 : OUString SAL_CALL OCommonEmbeddedObject::getClassName()
459 : throw ( uno::RuntimeException, std::exception )
460 : {
461 0 : if ( m_bDisposed )
462 0 : throw lang::DisposedException();
463 :
464 0 : return m_aClassName;
465 : }
466 :
467 0 : void SAL_CALL OCommonEmbeddedObject::setClassInfo(
468 : const uno::Sequence< sal_Int8 >& /*aClassID*/, const OUString& /*aClassName*/ )
469 : throw ( lang::NoSupportException,
470 : uno::RuntimeException, std::exception )
471 : {
472 : // the object class info can not be changed explicitly
473 0 : throw lang::NoSupportException(); //TODO:
474 : }
475 :
476 :
477 8420 : uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent()
478 : throw ( uno::RuntimeException, std::exception )
479 : {
480 8420 : ::osl::MutexGuard aGuard( m_aMutex );
481 8420 : if ( m_bDisposed )
482 0 : throw lang::DisposedException(); // TODO
483 :
484 : // add an exception
485 8420 : if ( m_nObjectState == -1 )
486 : {
487 : // the object is still not loaded
488 : throw uno::RuntimeException( "Can't store object without persistence!",
489 0 : static_cast< ::cppu::OWeakObject* >(this) );
490 : }
491 :
492 8420 : return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
493 : }
494 :
495 :
496 1815 : void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener )
497 : throw ( uno::RuntimeException, std::exception )
498 : {
499 1815 : ::osl::MutexGuard aGuard( m_aMutex );
500 1815 : if ( m_bDisposed )
501 0 : throw lang::DisposedException(); // TODO
502 :
503 1815 : if ( !m_pInterfaceContainer )
504 574 : m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
505 :
506 1815 : m_pInterfaceContainer->addInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
507 3630 : xListener );
508 1815 : }
509 :
510 :
511 1815 : void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener(
512 : const uno::Reference< embed::XStateChangeListener >& xListener )
513 : throw (uno::RuntimeException, std::exception)
514 : {
515 1815 : ::osl::MutexGuard aGuard( m_aMutex );
516 1815 : if ( m_pInterfaceContainer )
517 1815 : m_pInterfaceContainer->removeInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
518 3630 : xListener );
519 1815 : }
520 :
521 :
522 1547 : void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
523 : throw ( util::CloseVetoException,
524 : uno::RuntimeException, std::exception )
525 : {
526 1547 : ::osl::MutexGuard aGuard( m_aMutex );
527 1547 : if ( m_bClosed )
528 710 : throw lang::DisposedException(); // TODO
529 :
530 1674 : uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
531 1674 : lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
532 :
533 837 : if ( m_pInterfaceContainer )
534 : {
535 : ::cppu::OInterfaceContainerHelper* pContainer =
536 837 : m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
537 837 : if ( pContainer != NULL )
538 : {
539 836 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
540 1672 : while (pIterator.hasMoreElements())
541 : {
542 : try
543 : {
544 263 : static_cast<util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership );
545 : }
546 0 : catch( const uno::RuntimeException& )
547 : {
548 0 : pIterator.remove();
549 : }
550 836 : }
551 : }
552 :
553 : pContainer = m_pInterfaceContainer->getContainer(
554 574 : cppu::UnoType<util::XCloseListener>::get());
555 574 : if ( pContainer != NULL )
556 : {
557 573 : ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
558 1146 : while (pCloseIterator.hasMoreElements())
559 : {
560 : try
561 : {
562 0 : static_cast<util::XCloseListener*>(pCloseIterator.next())->notifyClosing( aSource );
563 : }
564 0 : catch( const uno::RuntimeException& )
565 : {
566 0 : pCloseIterator.remove();
567 : }
568 573 : }
569 : }
570 :
571 574 : m_pInterfaceContainer->disposeAndClear( aSource );
572 : }
573 :
574 574 : m_bDisposed = true; // the object is disposed now for outside
575 :
576 : // it is possible that the document can not be closed, in this case if the argument is false
577 : // the exception will be thrown otherwise in addition to exception the object must register itself
578 : // as termination listener and listen for document events
579 :
580 574 : if ( m_pDocHolder )
581 : {
582 574 : m_pDocHolder->CloseFrame();
583 :
584 : try {
585 574 : m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership );
586 : }
587 0 : catch( const uno::Exception& )
588 : {
589 0 : if ( bDeliverOwnership )
590 : {
591 0 : m_pDocHolder->release();
592 0 : m_pDocHolder = NULL;
593 0 : m_bClosed = true;
594 : }
595 :
596 0 : throw;
597 : }
598 :
599 574 : m_pDocHolder->FreeOffice();
600 :
601 574 : m_pDocHolder->release();
602 574 : m_pDocHolder = NULL;
603 : }
604 :
605 : // TODO: for now the storage will be disposed by the object, but after the document
606 : // will use the storage, the storage will be disposed by the document and recreated by the object
607 574 : if ( m_xObjectStorage.is() )
608 : {
609 566 : uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY );
610 : OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" );
611 :
612 566 : if ( xComp.is() )
613 : {
614 : try {
615 566 : xComp->dispose();
616 0 : } catch ( const uno::Exception& ) {}
617 : }
618 :
619 566 : m_xObjectStorage.clear();
620 566 : m_xRecoveryStorage.clear();
621 : }
622 :
623 2121 : m_bClosed = true; // the closing succeeded
624 574 : }
625 :
626 :
627 1146 : void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
628 : throw ( uno::RuntimeException, std::exception )
629 : {
630 1146 : ::osl::MutexGuard aGuard( m_aMutex );
631 1146 : if ( m_bDisposed )
632 0 : throw lang::DisposedException(); // TODO
633 :
634 1146 : if ( !m_pInterfaceContainer )
635 0 : m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
636 :
637 1146 : m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
638 1146 : }
639 :
640 :
641 1147 : void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
642 : throw (uno::RuntimeException, std::exception)
643 : {
644 1147 : ::osl::MutexGuard aGuard( m_aMutex );
645 1147 : if ( m_pInterfaceContainer )
646 1147 : m_pInterfaceContainer->removeInterface( cppu::UnoType<util::XCloseListener>::get(),
647 2294 : xListener );
648 1147 : }
649 :
650 :
651 1420 : void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener )
652 : throw ( uno::RuntimeException, std::exception )
653 : {
654 1420 : ::osl::MutexGuard aGuard( m_aMutex );
655 1420 : if ( m_bDisposed )
656 0 : throw lang::DisposedException(); // TODO
657 :
658 1420 : if ( !m_pInterfaceContainer )
659 0 : m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
660 :
661 1420 : m_pInterfaceContainer->addInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
662 1420 : }
663 :
664 :
665 1420 : void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
666 : throw ( uno::RuntimeException, std::exception )
667 : {
668 1420 : ::osl::MutexGuard aGuard( m_aMutex );
669 1420 : if ( m_pInterfaceContainer )
670 1420 : m_pInterfaceContainer->removeInterface( cppu::UnoType<document::XEventListener>::get(),
671 2840 : xListener );
672 1420 : }
673 :
674 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|