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