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