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