update dev300-m58
[ooovba.git] / embeddedobj / source / commonembedding / persistence.cxx
blob8310ebc3a10054a76360264d9939bc4bc2e39b51
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: persistence.cxx,v $
10 * $Revision: 1.36 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_embeddedobj.hxx"
34 #include <commonembobj.hxx>
35 #include <com/sun/star/embed/Aspects.hpp>
36 #include <com/sun/star/document/XStorageBasedDocument.hpp>
37 #include <com/sun/star/embed/EmbedStates.hpp>
38 #include <com/sun/star/embed/EmbedVerbs.hpp>
39 #include <com/sun/star/embed/EntryInitModes.hpp>
40 #include <com/sun/star/embed/XStorage.hpp>
41 #include <com/sun/star/embed/XOptimizedStorage.hpp>
42 #include <com/sun/star/embed/ElementModes.hpp>
43 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
46 #include <com/sun/star/frame/XLoadable.hpp>
47 #include <com/sun/star/frame/XComponentLoader.hpp>
48 #include <com/sun/star/frame/XModule.hpp>
49 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
51 #include <com/sun/star/lang/DisposedException.hpp>
52 #include <com/sun/star/util/XModifiable.hpp>
54 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCEESS_HPP_
55 #include <com/sun/star/container/XNameAccess.hpp>
56 #endif
57 #include <com/sun/star/container/XChild.hpp>
58 #include <com/sun/star/util/XCloseable.hpp>
59 #include <com/sun/star/beans/XPropertySet.hpp>
60 #include <com/sun/star/beans/IllegalTypeException.hpp>
62 #include <comphelper/fileformat.h>
63 #include <comphelper/storagehelper.hxx>
64 #include <comphelper/mimeconfighelper.hxx>
66 #include <rtl/logfile.hxx>
68 #define USE_STORAGEBASED_DOCUMENT
70 using namespace ::com::sun::star;
73 //------------------------------------------------------
74 uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
75 sal_Bool bCanUseDocumentBaseURL )
77 uno::Sequence< beans::PropertyValue > aResult;
78 sal_Int32 nResLen = 0;
80 for ( sal_Int32 nInd = 0; nInd < aMedDescr.getLength(); nInd++ )
82 if ( aMedDescr[nInd].Name.equalsAscii( "ComponentData" )
83 || aMedDescr[nInd].Name.equalsAscii( "DocumentTitle" )
84 || aMedDescr[nInd].Name.equalsAscii( "InteractionHandler" )
85 || aMedDescr[nInd].Name.equalsAscii( "JumpMark" )
86 // || aMedDescr[nInd].Name.equalsAscii( "Password" ) makes no sence for embedded objects
87 || aMedDescr[nInd].Name.equalsAscii( "Preview" )
88 || aMedDescr[nInd].Name.equalsAscii( "ReadOnly" )
89 || aMedDescr[nInd].Name.equalsAscii( "StartPresentation" )
90 || aMedDescr[nInd].Name.equalsAscii( "RepairPackage" )
91 || aMedDescr[nInd].Name.equalsAscii( "StatusIndicator" )
92 || aMedDescr[nInd].Name.equalsAscii( "ViewData" )
93 || aMedDescr[nInd].Name.equalsAscii( "ViewId" )
94 || aMedDescr[nInd].Name.equalsAscii( "MacroExecutionMode" )
95 || aMedDescr[nInd].Name.equalsAscii( "UpdateDocMode" )
96 || (aMedDescr[nInd].Name.equalsAscii( "DocumentBaseURL" ) && bCanUseDocumentBaseURL) )
98 aResult.realloc( ++nResLen );
99 aResult[nResLen-1] = aMedDescr[nInd];
103 return aResult;
106 //------------------------------------------------------
107 uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence< beans::PropertyValue >& aOrig )
109 sal_Bool bAsTemplateSet = sal_False;
110 sal_Int32 nLength = aOrig.getLength();
111 uno::Sequence< beans::PropertyValue > aResult( nLength );
113 for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ )
115 aResult[nInd].Name = aOrig[nInd].Name;
116 if ( aResult[nInd].Name.equalsAscii( "AsTemplate" ) )
118 aResult[nInd].Value <<= sal_True;
119 bAsTemplateSet = sal_True;
121 else
122 aResult[nInd].Value = aOrig[nInd].Value;
125 if ( !bAsTemplateSet )
127 aResult.realloc( nLength + 1 );
128 aResult[nLength].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
129 aResult[nLength].Value <<= sal_True;
132 return aResult;
135 //------------------------------------------------------
136 uno::Reference< io::XInputStream > createTempInpStreamFromStor(
137 const uno::Reference< embed::XStorage >& xStorage,
138 const uno::Reference< lang::XMultiServiceFactory >& xFactory )
140 OSL_ENSURE( xStorage.is(), "The storage can not be empty!" );
142 uno::Reference< io::XInputStream > xResult;
144 const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
145 uno::Reference < io::XStream > xTempStream = uno::Reference < io::XStream > (
146 xFactory->createInstance ( aServiceName ),
147 uno::UNO_QUERY );
148 if ( xTempStream.is() )
150 uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
151 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
152 uno::UNO_QUERY );
154 uno::Sequence< uno::Any > aArgs( 2 );
155 aArgs[0] <<= xTempStream;
156 aArgs[1] <<= embed::ElementModes::READWRITE;
157 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
158 uno::UNO_QUERY );
159 if ( !xTempStorage.is() )
160 throw uno::RuntimeException(); // TODO:
164 xStorage->copyToStorage( xTempStorage );
165 } catch( uno::Exception& e )
167 throw embed::StorageWrappedTargetException(
168 ::rtl::OUString::createFromAscii( "Can't copy storage!" ),
169 uno::Reference< uno::XInterface >(),
170 uno::makeAny( e ) );
173 try {
174 uno::Reference< lang::XComponent > xComponent( xTempStorage, uno::UNO_QUERY );
175 OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
176 if ( xComponent.is() )
177 xComponent->dispose();
179 catch ( uno::Exception& )
183 try {
184 uno::Reference< io::XOutputStream > xTempOut = xTempStream->getOutputStream();
185 if ( xTempOut.is() )
186 xTempOut->closeOutput();
188 catch ( uno::Exception& )
192 xResult = xTempStream->getInputStream();
195 return xResult;
199 //------------------------------------------------------
200 static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< lang::XMultiServiceFactory >& _rxFactory,
201 const ::rtl::OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport )
203 uno::Sequence< uno::Any > aArguments(2);
204 aArguments[0] <<= beans::NamedValue(
205 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbeddedObject" ) ),
206 uno::makeAny( (sal_Bool)sal_True )
208 aArguments[1] <<= beans::NamedValue(
209 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbeddedScriptSupport" ) ),
210 uno::makeAny( (sal_Bool)_bEmbeddedScriptSupport )
213 uno::Reference< uno::XInterface > xDocument;
216 xDocument = _rxFactory->createInstanceWithArguments( _rDocumentServiceName, aArguments );
218 catch( const uno::Exception& )
220 // some of our embedded object implementations (in particular chart) do neither support
221 // the EmbeddedObject, nor the EmbeddedScriptSupport argument. Also, they do not support
222 // XInitialization, which means the default factory from cppuhelper will throw an
223 // IllegalArgumentException when we try to create the instance with arguments.
224 // Okay, so we fall back to creating the instance without any arguments.
225 xDocument = _rxFactory->createInstance( _rDocumentServiceName );
228 return uno::Reference< util::XCloseable >( xDocument, uno::UNO_QUERY );
231 //------------------------------------------------------
232 static void SetDocToEmbedded( const uno::Reference< frame::XModel > xDocument, const ::rtl::OUString& aModuleName )
234 if ( xDocument.is() )
236 uno::Sequence< beans::PropertyValue > aSeq( 1 );
237 aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" );
238 aSeq[0].Value <<= sal_True;
239 xDocument->attachResource( ::rtl::OUString(), aSeq );
241 if ( aModuleName.getLength() )
245 uno::Reference< frame::XModule > xModule( xDocument, uno::UNO_QUERY_THROW );
246 xModule->setIdentifier( aModuleName );
248 catch( uno::Exception& )
254 //------------------------------------------------------
255 void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
256 const uno::Reference< embed::XStorage >& xNewObjectStorage,
257 const ::rtl::OUString& aNewName )
259 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
261 OSL_ENSURE( xNewObjectStorage == m_xObjectStorage, "The storage must be the same!\n" );
262 return;
265 uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
266 OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
268 m_xObjectStorage = xNewObjectStorage;
269 m_xParentStorage = xNewParentStorage;
270 m_aEntryName = aNewName;
272 #ifdef USE_STORAGEBASED_DOCUMENT
273 // the linked document should not be switched
274 if ( !m_bIsLink )
276 uno::Reference< document::XStorageBasedDocument > xDoc( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
277 if ( xDoc.is() )
278 xDoc->switchToStorage( m_xObjectStorage );
280 #endif
282 try {
283 if ( xComponent.is() )
284 xComponent->dispose();
286 catch ( uno::Exception& )
291 //------------------------------------------------------
292 void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
293 const ::rtl::OUString& aNewName )
295 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
296 return;
298 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
300 uno::Reference< embed::XStorage > xNewOwnStorage = xNewParentStorage->openStorageElement( aNewName, nStorageMode );
301 OSL_ENSURE( xNewOwnStorage.is(), "The method can not return empty reference!" );
303 SwitchOwnPersistence( xNewParentStorage, xNewOwnStorage, aNewName );
306 //------------------------------------------------------
307 uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
309 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
310 m_bEmbeddedScriptSupport ) );
312 uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY );
313 uno::Reference< frame::XLoadable > xLoadable( xModel, uno::UNO_QUERY );
314 if ( !xLoadable.is() )
315 throw uno::RuntimeException();
319 // set the document mode to embedded as the first action on document!!!
320 SetDocToEmbedded( xModel, m_aModuleName );
324 uno::Reference < container::XChild > xChild( xDocument, uno::UNO_QUERY );
325 if ( xChild.is() )
326 xChild->setParent( m_xParent );
328 catch( const lang::NoSupportException & )
330 OSL_ENSURE( false, "Cannot set parent at document" );
333 // init document as a new
334 xLoadable->initNew();
335 xModel->attachResource( xModel->getURL(),m_aDocMediaDescriptor);
337 catch( uno::Exception& )
339 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
340 if ( xCloseable.is() )
344 xCloseable->close( sal_True );
346 catch( uno::Exception& )
351 throw; // TODO
354 return xDocument;
357 //------------------------------------------------------
358 uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
360 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
361 m_bEmbeddedScriptSupport ) );
363 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
364 if ( !xLoadable.is() )
365 throw uno::RuntimeException();
367 sal_Int32 nLen = 2;
368 uno::Sequence< beans::PropertyValue > aArgs( nLen );
369 aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
370 aArgs[0].Value <<= m_aLinkURL;
371 aArgs[1].Name = ::rtl::OUString::createFromAscii( "FilterName" );
372 aArgs[1].Value <<= m_aLinkFilterName;
373 if ( m_bLinkHasPassword )
375 aArgs.realloc( ++nLen );
376 aArgs[nLen-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) );
377 aArgs[nLen-1].Value <<= m_aLinkPassword;
380 aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
381 for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
383 aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
384 aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
389 // the document is not really an embedded one, it is a link
390 SetDocToEmbedded( uno::Reference < frame::XModel >( xDocument, uno::UNO_QUERY ), m_aModuleName );
394 uno::Reference < container::XChild > xChild( xDocument, uno::UNO_QUERY );
395 if ( xChild.is() )
396 xChild->setParent( m_xParent );
398 catch( const lang::NoSupportException & )
400 OSL_ENSURE( false, "Cannot set parent at document" );
403 // load the document
404 xLoadable->load( aArgs );
406 if ( !m_bLinkHasPassword )
408 // check if there is a password to cache
409 uno::Reference< frame::XModel > xModel( xLoadable, uno::UNO_QUERY_THROW );
410 uno::Sequence< beans::PropertyValue > aProps = xModel->getArgs();
411 for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
412 if ( aProps[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) )
413 && ( aProps[nInd].Value >>= m_aLinkPassword ) )
415 m_bLinkHasPassword = sal_True;
416 break;
420 catch( uno::Exception& )
422 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
423 if ( xCloseable.is() )
427 xCloseable->close( sal_True );
429 catch( uno::Exception& )
434 throw; // TODO
437 return xDocument;
441 //------------------------------------------------------
442 ::rtl::OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion )
444 ::rtl::OUString aFilterName = GetPresetFilterName();
445 if ( !aFilterName.getLength() )
447 try {
448 ::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
449 aFilterName = aHelper.GetDefaultFilterFromServiceName( GetDocumentServiceName(), nVersion );
450 } catch( uno::Exception& )
454 return aFilterName;
457 //------------------------------------------------------
458 uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorage_Impl(
459 const uno::Reference< embed::XStorage >& xStorage )
461 OSL_ENSURE( xStorage.is(), "The storage can not be empty!" );
463 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
464 m_bEmbeddedScriptSupport ) );
466 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
467 uno::Reference< document::XStorageBasedDocument > xDoc
468 #ifdef USE_STORAGEBASED_DOCUMENT
469 ( xDocument, uno::UNO_QUERY )
470 #endif
472 if ( !xDoc.is() && !xLoadable.is() ) ///BUG: This should be || instead of && ?
473 throw uno::RuntimeException();
475 ::rtl::OUString aFilterName = GetFilterName( ::comphelper::OStorageHelper::GetXStorageFormat( xStorage ) );
477 OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
478 if ( !aFilterName.getLength() )
479 throw io::IOException();
481 sal_Int32 nLen = xDoc.is() ? 4 : 6;
482 uno::Sequence< beans::PropertyValue > aArgs( nLen );
484 aArgs[0].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
485 aArgs[0].Value <<= GetBaseURL_Impl();
486 aArgs[1].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
487 aArgs[1].Value <<= m_aEntryName;
488 aArgs[2].Name = ::rtl::OUString::createFromAscii( "ReadOnly" );
489 aArgs[2].Value <<= m_bReadOnly;
490 aArgs[3].Name = ::rtl::OUString::createFromAscii( "FilterName" );
491 aArgs[3].Value <<= aFilterName;
493 uno::Reference< io::XInputStream > xTempInpStream;
494 if ( !xDoc.is() )
496 xTempInpStream = createTempInpStreamFromStor( xStorage, m_xFactory );
497 if ( !xTempInpStream.is() )
498 throw uno::RuntimeException();
500 ::rtl::OUString aTempFileURL;
503 // no need to let the file stay after the stream is removed since the embedded document
504 // can not be stored directly
505 uno::Reference< beans::XPropertySet > xTempStreamProps( xTempInpStream, uno::UNO_QUERY_THROW );
506 xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL;
508 catch( uno::Exception& )
512 OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" );
514 aArgs[4].Name = ::rtl::OUString::createFromAscii( "URL" );
515 aArgs[4].Value <<= aTempFileURL; // ::rtl::OUString::createFromAscii( "private:stream" );
516 aArgs[5].Name = ::rtl::OUString::createFromAscii( "InputStream" );
517 aArgs[5].Value <<= xTempInpStream;
520 // aArgs[4].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
521 // aArgs[4].Value <<= sal_True;
523 aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
524 for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
526 aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
527 aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
532 // set the document mode to embedded as the first step!!!
533 SetDocToEmbedded( uno::Reference < frame::XModel >( xDocument, uno::UNO_QUERY ), m_aModuleName );
537 uno::Reference < container::XChild > xChild( xDocument, uno::UNO_QUERY );
538 if ( xChild.is() )
539 xChild->setParent( m_xParent );
541 catch( const lang::NoSupportException & )
543 OSL_ENSURE( false, "Cannot set parent at document" );
546 if ( xDoc.is() )
547 xDoc->loadFromStorage( xStorage, aArgs );
548 else
549 xLoadable->load( aArgs );
551 catch( uno::Exception& )
553 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
554 if ( xCloseable.is() )
558 xCloseable->close( sal_True );
560 catch( uno::Exception& )
565 throw; // TODO
568 return xDocument;
571 //------------------------------------------------------
572 uno::Reference< io::XInputStream > OCommonEmbeddedObject::StoreDocumentToTempStream_Impl(
573 sal_Int32 nStorageFormat,
574 const ::rtl::OUString& aBaseURL,
575 const ::rtl::OUString& aHierarchName )
577 uno::Reference < io::XOutputStream > xTempOut(
578 m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
579 uno::UNO_QUERY );
580 uno::Reference< io::XInputStream > aResult( xTempOut, uno::UNO_QUERY );
582 if ( !xTempOut.is() || !aResult.is() )
583 throw uno::RuntimeException(); // TODO:
585 uno::Reference< frame::XStorable > xStorable;
587 osl::MutexGuard aGuard( m_aMutex );
588 if ( m_pDocHolder )
589 xStorable = uno::Reference< frame::XStorable > ( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
592 if( !xStorable.is() )
593 throw uno::RuntimeException(); // TODO:
595 ::rtl::OUString aFilterName = GetFilterName( nStorageFormat );
597 OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
598 if ( !aFilterName.getLength() )
599 throw io::IOException(); // TODO:
601 uno::Sequence< beans::PropertyValue > aArgs( 4 );
602 aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
603 aArgs[0].Value <<= aFilterName;
604 aArgs[1].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
605 aArgs[1].Value <<= xTempOut;
606 aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
607 aArgs[2].Value <<= aBaseURL;
608 aArgs[3].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
609 aArgs[3].Value <<= aHierarchName;
611 xStorable->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aArgs );
614 xTempOut->closeOutput();
616 catch( uno::Exception& )
618 OSL_ENSURE( sal_False, "Looks like stream was closed already" );
621 return aResult;
624 //------------------------------------------------------
625 void OCommonEmbeddedObject::SaveObject_Impl()
627 if ( m_xClientSite.is() )
631 // check whether the component is modified,
632 // if not there is no need for storing
633 uno::Reference< util::XModifiable > xModifiable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
634 if ( xModifiable.is() && !xModifiable->isModified() )
635 return;
637 catch( uno::Exception& )
640 try {
641 m_xClientSite->saveObject();
643 catch( uno::Exception& )
645 OSL_ENSURE( sal_False, "The object was not stored!\n" );
650 //------------------------------------------------------
651 ::rtl::OUString OCommonEmbeddedObject::GetBaseURL_Impl()
653 ::rtl::OUString aBaseURL;
654 sal_Int32 nInd = 0;
656 if ( m_xClientSite.is() )
660 uno::Reference< frame::XModel > xParentModel( m_xClientSite->getComponent(), uno::UNO_QUERY_THROW );
661 uno::Sequence< beans::PropertyValue > aModelProps = xParentModel->getArgs();
662 for ( nInd = 0; nInd < aModelProps.getLength(); nInd++ )
663 if ( aModelProps[nInd].Name.equals(
664 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
666 aModelProps[nInd].Value >>= aBaseURL;
667 break;
672 catch( uno::Exception& )
676 if ( !aBaseURL.getLength() )
678 for ( nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
679 if ( m_aDocMediaDescriptor[nInd].Name.equals(
680 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
682 m_aDocMediaDescriptor[nInd].Value >>= aBaseURL;
683 break;
687 if ( !aBaseURL.getLength() )
688 aBaseURL = m_aDefaultParentBaseURL;
690 return aBaseURL;
693 //------------------------------------------------------
694 ::rtl::OUString OCommonEmbeddedObject::GetBaseURLFrom_Impl(
695 const uno::Sequence< beans::PropertyValue >& lArguments,
696 const uno::Sequence< beans::PropertyValue >& lObjArgs )
698 ::rtl::OUString aBaseURL;
699 sal_Int32 nInd = 0;
701 for ( nInd = 0; nInd < lArguments.getLength(); nInd++ )
702 if ( lArguments[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
704 lArguments[nInd].Value >>= aBaseURL;
705 break;
708 if ( !aBaseURL.getLength() )
710 for ( nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
711 if ( lObjArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultParentBaseURL" ) ) ) )
713 lObjArgs[nInd].Value >>= aBaseURL;
714 break;
718 return aBaseURL;
722 //------------------------------------------------------
723 void OCommonEmbeddedObject::StoreDocToStorage_Impl( const uno::Reference< embed::XStorage >& xStorage,
724 sal_Int32 nStorageFormat,
725 const ::rtl::OUString& aBaseURL,
726 const ::rtl::OUString& aHierarchName,
727 sal_Bool bAttachToTheStorage )
729 OSL_ENSURE( xStorage.is(), "No storage is provided for storing!" );
731 if ( !xStorage.is() )
732 throw uno::RuntimeException(); // TODO:
734 #ifdef USE_STORAGEBASED_DOCUMENT
735 uno::Reference< document::XStorageBasedDocument > xDoc;
737 osl::MutexGuard aGuard( m_aMutex );
738 if ( m_pDocHolder )
739 xDoc = uno::Reference< document::XStorageBasedDocument >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
742 if ( xDoc.is() )
744 ::rtl::OUString aFilterName = GetFilterName( nStorageFormat );
746 OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
747 if ( !aFilterName.getLength() )
748 throw io::IOException(); // TODO:
750 uno::Sequence< beans::PropertyValue > aArgs( 3 );
751 aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
752 aArgs[0].Value <<= aFilterName;
753 aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
754 aArgs[2].Value <<= aBaseURL;
755 aArgs[1].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
756 aArgs[1].Value <<= aHierarchName;
758 xDoc->storeToStorage( xStorage, aArgs );
759 if ( bAttachToTheStorage )
761 xDoc->switchToStorage( xStorage );
762 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
763 if ( xModif.is() )
764 xModif->setModified( sal_False );
767 else
768 #endif
770 // store document to temporary stream based on temporary file
771 uno::Reference < io::XInputStream > xTempIn = StoreDocumentToTempStream_Impl( nStorageFormat, aBaseURL, aHierarchName );
773 OSL_ENSURE( xTempIn.is(), "The stream reference can not be empty!\n" );
775 // open storage based on document temporary file for reading
776 uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
777 m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
778 uno::UNO_QUERY );
780 uno::Sequence< uno::Any > aArgs(1);
781 aArgs[0] <<= xTempIn;
782 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
783 uno::UNO_QUERY );
784 if ( !xTempStorage.is() )
785 throw uno::RuntimeException(); // TODO:
787 // object storage must be commited automatically
788 xTempStorage->copyToStorage( xStorage );
792 //------------------------------------------------------
793 uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateDocFromMediaDescr_Impl(
794 const uno::Sequence< beans::PropertyValue >& aMedDescr )
796 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
797 m_bEmbeddedScriptSupport ) );
799 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
800 if ( !xLoadable.is() )
801 throw uno::RuntimeException();
805 // set the document mode to embedded as the first action on the document!!!
806 SetDocToEmbedded( uno::Reference < frame::XModel >( xDocument, uno::UNO_QUERY ), m_aModuleName );
810 uno::Reference < container::XChild > xChild( xDocument, uno::UNO_QUERY );
811 if ( xChild.is() )
812 xChild->setParent( m_xParent );
814 catch( const lang::NoSupportException & )
816 OSL_ENSURE( false, "Cannot set parent at document" );
819 xLoadable->load( addAsTemplate( aMedDescr ) );
821 catch( uno::Exception& )
823 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
824 if ( xCloseable.is() )
828 xCloseable->close( sal_True );
830 catch( uno::Exception& )
835 throw; // TODO
838 return xDocument;
841 //------------------------------------------------------
842 uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_Impl()
844 uno::Reference< util::XCloseable > xResult;
846 OSL_ENSURE( m_bIsLink, "The object is not a linked one!\n" );
848 uno::Sequence< beans::PropertyValue > aTempMediaDescr;
850 sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
851 try {
852 nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
854 catch ( beans::IllegalTypeException& )
856 // the container just has an unknown type, use current file format
858 catch ( uno::Exception& )
860 OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" );
863 if ( m_pDocHolder->GetComponent().is() )
865 aTempMediaDescr.realloc( 4 );
867 // TODO/LATER: may be private:stream should be used as target URL
868 ::rtl::OUString aTempFileURL;
869 uno::Reference< io::XInputStream > xTempStream = StoreDocumentToTempStream_Impl( SOFFICE_FILEFORMAT_CURRENT,
870 ::rtl::OUString(),
871 ::rtl::OUString() );
874 // no need to let the file stay after the stream is removed since the embedded document
875 // can not be stored directly
876 uno::Reference< beans::XPropertySet > xTempStreamProps( xTempStream, uno::UNO_QUERY_THROW );
877 xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL;
879 catch( uno::Exception& )
883 OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" );
885 aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
886 aTempMediaDescr[0].Value <<= aTempFileURL;
887 aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "InputStream" );
888 aTempMediaDescr[1].Value <<= xTempStream;
889 aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "FilterName" );
890 aTempMediaDescr[2].Value <<= GetFilterName( nStorageFormat );
891 aTempMediaDescr[3].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
892 aTempMediaDescr[3].Value <<= sal_True;
894 else
896 aTempMediaDescr.realloc( 2 );
897 aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
898 aTempMediaDescr[0].Value <<= m_aLinkURL;
899 aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "FilterName" );
900 aTempMediaDescr[1].Value <<= m_aLinkFilterName;
901 // aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
902 // aTempMediaDescr[2].Value <<= sal_True;
905 xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr );
907 return xResult;
910 //------------------------------------------------------
911 void SAL_CALL OCommonEmbeddedObject::setPersistentEntry(
912 const uno::Reference< embed::XStorage >& xStorage,
913 const ::rtl::OUString& sEntName,
914 sal_Int32 nEntryConnectionMode,
915 const uno::Sequence< beans::PropertyValue >& lArguments,
916 const uno::Sequence< beans::PropertyValue >& lObjArgs )
917 throw ( lang::IllegalArgumentException,
918 embed::WrongStateException,
919 io::IOException,
920 uno::Exception,
921 uno::RuntimeException )
923 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::setPersistentEntry" );
925 // the type of the object must be already set
926 // a kind of typedetection should be done in the factory
928 ::osl::MutexGuard aGuard( m_aMutex );
929 if ( m_bDisposed )
930 throw lang::DisposedException(); // TODO
932 if ( !xStorage.is() )
933 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
934 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
935 1 );
937 if ( !sEntName.getLength() )
938 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
939 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
940 2 );
942 // May be LOADED should be forbidden here ???
943 if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
944 && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
946 // if the object is not loaded
947 // it can not get persistant representation without initialization
949 // if the object is loaded
950 // it can switch persistant representation only without initialization
952 throw embed::WrongStateException(
953 ::rtl::OUString::createFromAscii( "Can't change persistant representation of activated object!\n" ),
954 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
957 if ( m_bWaitSaveCompleted )
959 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
960 saveCompleted( ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) ) );
961 else
962 throw embed::WrongStateException(
963 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
964 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
967 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
968 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
969 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
970 if ( m_bIsLink )
972 m_aEntryName = sEntName;
973 return;
976 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
977 if ( !xNameAccess.is() )
978 throw uno::RuntimeException(); //TODO
980 // detect entry existence
981 sal_Bool bElExists = xNameAccess->hasByName( sEntName );
983 m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments,
984 nEntryConnectionMode != embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT );
986 m_bReadOnly = sal_False;
987 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
988 if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
989 lArguments[nInd].Value >>= m_bReadOnly;
991 // TODO: use lObjArgs for StoreVisualReplacement
992 for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
993 if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
995 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
996 if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
997 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
999 else if ( lObjArgs[nObjInd].Name.equalsAscii( "DefaultParentBaseURL" ) )
1001 lObjArgs[nObjInd].Value >>= m_aDefaultParentBaseURL;
1003 else if ( lObjArgs[nObjInd].Name.equalsAscii( "Parent" ) )
1005 lObjArgs[nObjInd].Value >>= m_xParent;
1007 else if ( lObjArgs[nObjInd].Name.equalsAscii( "IndividualMiscStatus" ) )
1009 sal_Int64 nMiscStatus=0;
1010 lObjArgs[nObjInd].Value >>= nMiscStatus;
1011 m_nMiscStatus |= nMiscStatus;
1013 else if ( lObjArgs[nObjInd].Name.equalsAscii( "CloneFrom" ) )
1015 uno::Reference < embed::XEmbeddedObject > xObj;
1016 lObjArgs[nObjInd].Value >>= xObj;
1017 if ( xObj.is() )
1019 m_bHasClonedSize = sal_True;
1020 m_aClonedSize = xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1021 m_nClonedMapUnit = xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT );
1024 else if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceFrameProperties" ) )
1026 uno::Sequence< uno::Any > aOutFrameProps;
1027 uno::Sequence< beans::NamedValue > aOutFramePropsTyped;
1028 if ( lObjArgs[nObjInd].Value >>= aOutFrameProps )
1030 m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
1032 else if ( lObjArgs[nObjInd].Value >>= aOutFramePropsTyped )
1034 aOutFrameProps.realloc( aOutFramePropsTyped.getLength() );
1035 uno::Any* pProp = aOutFrameProps.getArray();
1036 for ( const beans::NamedValue* pTypedProp = aOutFramePropsTyped.getConstArray();
1037 pTypedProp != aOutFramePropsTyped.getConstArray() + aOutFramePropsTyped.getLength();
1038 ++pTypedProp, ++pProp
1041 *pProp <<= *pTypedProp;
1043 m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
1045 else
1046 OSL_ENSURE( false, "OCommonEmbeddedObject::setPersistentEntry: illegal type for argument 'OutplaceFrameProperties'!" );
1048 else if ( lObjArgs[nObjInd].Name.equalsAscii( "ModuleName" ) )
1050 lObjArgs[nObjInd].Value >>= m_aModuleName;
1052 else if ( lObjArgs[nObjInd].Name.equalsAscii( "EmbeddedScriptSupport" ) )
1054 OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bEmbeddedScriptSupport );
1058 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1060 SwitchOwnPersistence( xStorage, sEntName );
1062 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
1064 if ( bElExists )
1066 // the initialization from existing storage allows to leave object in loaded state
1067 m_nObjectState = embed::EmbedStates::LOADED;
1069 else
1071 m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
1072 if ( !m_pDocHolder->GetComponent().is() )
1073 throw io::IOException(); // TODO: can not create document
1075 m_nObjectState = embed::EmbedStates::RUNNING;
1078 else
1080 if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
1081 throw io::IOException();
1083 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1085 // the document just already changed its storage to store to
1086 // the links to OOo documents for now ignore this call
1087 // TODO: OOo links will have persistence so it will be switched here
1089 else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
1091 // TODO:
1092 m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
1094 if ( !m_pDocHolder->GetComponent().is() )
1095 throw io::IOException(); // TODO: can not create document
1097 m_nObjectState = embed::EmbedStates::RUNNING;
1099 else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
1101 m_pDocHolder->SetComponent( CreateDocFromMediaDescr_Impl( lArguments ), m_bReadOnly );
1102 m_nObjectState = embed::EmbedStates::RUNNING;
1104 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1106 //TODO:
1108 else
1109 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong connection mode is provided!\n" ),
1110 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1111 3 );
1115 //------------------------------------------------------
1116 void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
1117 const ::rtl::OUString& sEntName,
1118 const uno::Sequence< beans::PropertyValue >& lArguments,
1119 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1120 throw ( lang::IllegalArgumentException,
1121 embed::WrongStateException,
1122 io::IOException,
1123 uno::Exception,
1124 uno::RuntimeException )
1126 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeToEntry" );
1128 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1129 if ( m_bDisposed )
1130 throw lang::DisposedException(); // TODO
1132 if ( m_nObjectState == -1 )
1134 // the object is still not loaded
1135 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1136 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1139 if ( m_bWaitSaveCompleted )
1140 throw embed::WrongStateException(
1141 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1142 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1144 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
1145 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1146 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1147 if ( m_bIsLink )
1148 return;
1150 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
1152 sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1153 sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1154 try {
1155 nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
1157 catch ( beans::IllegalTypeException& )
1159 // the container just has an unknown type, use current file format
1161 catch ( uno::Exception& )
1163 OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" );
1168 nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
1170 catch ( beans::IllegalTypeException& )
1172 // the container just has an unknown type, use current file format
1174 catch ( uno::Exception& )
1176 OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" );
1179 sal_Bool bTryOptimization = sal_False;
1180 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1182 // StoreVisualReplacement and VisualReplacement args have no sence here
1183 if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
1184 lObjArgs[nInd].Value >>= bTryOptimization;
1187 sal_Bool bSwitchBackToLoaded = sal_False;
1189 // Storing to different format can be done only in running state.
1190 if ( m_nObjectState == embed::EmbedStates::LOADED )
1192 // TODO/LATER: copying is not legal for documents with relative links.
1193 if ( nTargetStorageFormat == nOriginalStorageFormat )
1195 sal_Bool bOptimizationWorks = sal_False;
1196 if ( bTryOptimization )
1200 // try to use optimized copying
1201 uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
1202 uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
1203 xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
1204 bOptimizationWorks = sal_True;
1206 catch( uno::Exception& )
1211 if ( !bOptimizationWorks )
1212 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1214 else
1216 changeState( embed::EmbedStates::RUNNING );
1217 bSwitchBackToLoaded = sal_True;
1221 if ( m_nObjectState != embed::EmbedStates::LOADED )
1223 uno::Reference< embed::XStorage > xSubStorage =
1224 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
1226 if ( !xSubStorage.is() )
1227 throw uno::RuntimeException(); //TODO
1229 aGuard.clear();
1230 // TODO/LATER: support hierarchical name for embedded objects in embedded objects
1231 StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
1232 aGuard.reset();
1234 if ( bSwitchBackToLoaded )
1235 changeState( embed::EmbedStates::LOADED );
1238 // TODO: should the listener notification be done?
1241 //------------------------------------------------------
1242 void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
1243 const ::rtl::OUString& sEntName,
1244 const uno::Sequence< beans::PropertyValue >& lArguments,
1245 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1246 throw ( lang::IllegalArgumentException,
1247 embed::WrongStateException,
1248 io::IOException,
1249 uno::Exception,
1250 uno::RuntimeException )
1252 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeAsEntry" );
1254 // TODO: use lObjArgs
1256 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1257 if ( m_bDisposed )
1258 throw lang::DisposedException(); // TODO
1260 if ( m_nObjectState == -1 )
1262 // the object is still not loaded
1263 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1264 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1267 if ( m_bWaitSaveCompleted )
1268 throw embed::WrongStateException(
1269 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1270 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1272 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
1273 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1274 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1275 if ( m_bIsLink )
1277 m_aNewEntryName = sEntName;
1278 return;
1281 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
1283 sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1284 sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1285 try {
1286 nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
1288 catch ( beans::IllegalTypeException& )
1290 // the container just has an unknown type, use current file format
1292 catch ( uno::Exception& )
1294 OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" );
1299 nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
1301 catch ( beans::IllegalTypeException& )
1303 // the container just has an unknown type, use current file format
1305 catch ( uno::Exception& )
1307 OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" );
1310 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAs" ) );
1312 sal_Bool bTryOptimization = sal_False;
1313 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1315 // StoreVisualReplacement and VisualReplacement args have no sence here
1316 if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
1317 lObjArgs[nInd].Value >>= bTryOptimization;
1320 sal_Bool bSwitchBackToLoaded = sal_False;
1322 // Storing to different format can be done only in running state.
1323 if ( m_nObjectState == embed::EmbedStates::LOADED )
1325 // TODO/LATER: copying is not legal for documents with relative links.
1326 if ( nTargetStorageFormat == nOriginalStorageFormat )
1328 sal_Bool bOptimizationWorks = sal_False;
1329 if ( bTryOptimization )
1333 // try to use optimized copying
1334 uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
1335 uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
1336 xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
1337 bOptimizationWorks = sal_True;
1339 catch( uno::Exception& )
1344 if ( !bOptimizationWorks )
1345 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1347 else
1349 changeState( embed::EmbedStates::RUNNING );
1350 bSwitchBackToLoaded = sal_True;
1354 uno::Reference< embed::XStorage > xSubStorage =
1355 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
1357 if ( !xSubStorage.is() )
1358 throw uno::RuntimeException(); //TODO
1360 if ( m_nObjectState != embed::EmbedStates::LOADED )
1362 aGuard.clear();
1363 // TODO/LATER: support hierarchical name for embedded objects in embedded objects
1364 StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
1365 aGuard.reset();
1367 if ( bSwitchBackToLoaded )
1368 changeState( embed::EmbedStates::LOADED );
1371 m_bWaitSaveCompleted = sal_True;
1372 m_xNewObjectStorage = xSubStorage;
1373 m_xNewParentStorage = xStorage;
1374 m_aNewEntryName = sEntName;
1375 m_aNewDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );
1377 // TODO: register listeners for storages above, in case thay are disposed
1378 // an exception will be thrown on saveCompleted( true )
1380 // TODO: should the listener notification be done here or in saveCompleted?
1383 //------------------------------------------------------
1384 void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew )
1385 throw ( embed::WrongStateException,
1386 uno::Exception,
1387 uno::RuntimeException )
1389 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::saveCompleted" );
1391 ::osl::MutexGuard aGuard( m_aMutex );
1392 if ( m_bDisposed )
1393 throw lang::DisposedException(); // TODO
1395 if ( m_nObjectState == -1 )
1397 // the object is still not loaded
1398 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1399 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1402 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
1403 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1404 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1405 if ( m_bIsLink )
1407 if ( bUseNew )
1408 m_aEntryName = m_aNewEntryName;
1409 m_aNewEntryName = ::rtl::OUString();
1410 return;
1413 // it is allowed to call saveCompleted( false ) for nonstored objects
1414 if ( !m_bWaitSaveCompleted && !bUseNew )
1415 return;
1417 OSL_ENSURE( m_bWaitSaveCompleted, "Unexpected saveCompleted() call!\n" );
1418 if ( !m_bWaitSaveCompleted )
1419 throw io::IOException(); // TODO: illegal call
1421 OSL_ENSURE( m_xNewObjectStorage.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
1422 if ( !m_xNewObjectStorage.is() || !m_xNewParentStorage.is() )
1423 throw uno::RuntimeException(); // TODO: broken internal information
1425 if ( bUseNew )
1427 SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStorage, m_aNewEntryName );
1428 m_aDocMediaDescriptor = m_aNewDocMediaDescriptor;
1430 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1431 if ( xModif.is() )
1432 xModif->setModified( sal_False );
1434 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAsDone" ) );
1436 else
1438 try {
1439 uno::Reference< lang::XComponent > xComponent( m_xNewObjectStorage, uno::UNO_QUERY );
1440 OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
1441 if ( xComponent.is() )
1442 xComponent->dispose();
1444 catch ( uno::Exception& )
1449 m_xNewObjectStorage = uno::Reference< embed::XStorage >();
1450 m_xNewParentStorage = uno::Reference< embed::XStorage >();
1451 m_aNewEntryName = ::rtl::OUString();
1452 m_aNewDocMediaDescriptor.realloc( 0 );
1453 m_bWaitSaveCompleted = sal_False;
1455 if ( bUseNew )
1457 // TODO: notify listeners
1459 if ( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
1461 // TODO: update visual representation
1466 //------------------------------------------------------
1467 sal_Bool SAL_CALL OCommonEmbeddedObject::hasEntry()
1468 throw ( embed::WrongStateException,
1469 uno::RuntimeException )
1471 ::osl::MutexGuard aGuard( m_aMutex );
1472 if ( m_bDisposed )
1473 throw lang::DisposedException(); // TODO
1475 if ( m_bWaitSaveCompleted )
1476 throw embed::WrongStateException(
1477 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1478 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1480 if ( m_xObjectStorage.is() )
1481 return sal_True;
1483 return sal_False;
1486 //------------------------------------------------------
1487 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getEntryName()
1488 throw ( embed::WrongStateException,
1489 uno::RuntimeException )
1491 ::osl::MutexGuard aGuard( m_aMutex );
1492 if ( m_bDisposed )
1493 throw lang::DisposedException(); // TODO
1495 if ( m_nObjectState == -1 )
1497 // the object is still not loaded
1498 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1499 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1502 if ( m_bWaitSaveCompleted )
1503 throw embed::WrongStateException(
1504 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1505 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1507 return m_aEntryName;
1510 //------------------------------------------------------
1511 void SAL_CALL OCommonEmbeddedObject::storeOwn()
1512 throw ( embed::WrongStateException,
1513 io::IOException,
1514 uno::Exception,
1515 uno::RuntimeException )
1517 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeOwn" );
1519 // during switching from Activated to Running and from Running to Loaded states the object will
1520 // ask container to store the object, the container has to make decision
1521 // to do so or not
1523 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1524 if ( m_bDisposed )
1525 throw lang::DisposedException(); // TODO
1527 if ( m_nObjectState == -1 )
1529 // the object is still not loaded
1530 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1531 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1534 if ( m_bWaitSaveCompleted )
1535 throw embed::WrongStateException(
1536 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1537 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1539 if ( m_bReadOnly )
1540 throw io::IOException(); // TODO: access denied
1542 // nothing to do, if the object is in loaded state
1543 if ( m_nObjectState == embed::EmbedStates::LOADED )
1544 return;
1546 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSave" ) );
1548 OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If an object is activated or in running state it must have a document!\n" );
1549 if ( !m_pDocHolder->GetComponent().is() )
1550 throw uno::RuntimeException();
1552 if ( m_bIsLink )
1554 // TODO: just store the document to it's location
1555 uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1556 if ( !xStorable.is() )
1557 throw uno::RuntimeException(); // TODO
1559 // free the main mutex for the storing time
1560 aGuard.clear();
1562 xStorable->store();
1564 aGuard.reset();
1566 else
1568 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
1570 if ( !m_xObjectStorage.is() )
1571 throw io::IOException(); //TODO: access denied
1573 sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1574 try {
1575 nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
1577 catch ( beans::IllegalTypeException& )
1579 // the container just has an unknown type, use current file format
1581 catch ( uno::Exception& )
1583 OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" );
1586 aGuard.clear();
1587 StoreDocToStorage_Impl( m_xObjectStorage, nStorageFormat, GetBaseURL_Impl(), m_aEntryName, sal_True );
1588 aGuard.reset();
1591 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1592 if ( xModif.is() )
1593 xModif->setModified( sal_False );
1595 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveDone" ) );
1598 //------------------------------------------------------
1599 sal_Bool SAL_CALL OCommonEmbeddedObject::isReadonly()
1600 throw ( embed::WrongStateException,
1601 uno::RuntimeException )
1603 ::osl::MutexGuard aGuard( m_aMutex );
1604 if ( m_bDisposed )
1605 throw lang::DisposedException(); // TODO
1607 if ( m_nObjectState == -1 )
1609 // the object is still not loaded
1610 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1611 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1614 if ( m_bWaitSaveCompleted )
1615 throw embed::WrongStateException(
1616 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1617 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1619 return m_bReadOnly;
1622 //------------------------------------------------------
1623 void SAL_CALL OCommonEmbeddedObject::reload(
1624 const uno::Sequence< beans::PropertyValue >& lArguments,
1625 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1626 throw ( lang::IllegalArgumentException,
1627 embed::WrongStateException,
1628 io::IOException,
1629 uno::Exception,
1630 uno::RuntimeException )
1632 // TODO: use lObjArgs
1633 // for now this method is used only to switch readonly state
1635 ::osl::MutexGuard aGuard( m_aMutex );
1636 if ( m_bDisposed )
1637 throw lang::DisposedException(); // TODO
1639 if ( m_nObjectState == -1 )
1641 // the object is still not loaded
1642 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1643 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1646 if ( m_nObjectState != embed::EmbedStates::LOADED )
1648 // the object is still not loaded
1649 throw embed::WrongStateException(
1650 ::rtl::OUString::createFromAscii( "The object must be in loaded state to be reloaded!\n" ),
1651 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1654 if ( m_bWaitSaveCompleted )
1655 throw embed::WrongStateException(
1656 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1657 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1659 if ( m_bIsLink )
1661 // reload of the link
1662 ::rtl::OUString aOldLinkFilter = m_aLinkFilterName;
1664 ::rtl::OUString aNewLinkFilter;
1665 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1667 if ( lArguments[nInd].Name.equalsAscii( "URL" ) )
1669 // the new URL
1670 lArguments[nInd].Value >>= m_aLinkURL;
1671 m_aLinkFilterName = ::rtl::OUString();
1673 else if ( lArguments[nInd].Name.equalsAscii( "FilterName" ) )
1675 lArguments[nInd].Value >>= aNewLinkFilter;
1676 m_aLinkFilterName = ::rtl::OUString();
1680 ::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
1681 if ( !m_aLinkFilterName.getLength() )
1683 if ( aNewLinkFilter.getLength() )
1684 m_aLinkFilterName = aNewLinkFilter;
1685 else
1687 uno::Sequence< beans::PropertyValue > aArgs( 1 );
1688 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
1689 aArgs[0].Value <<= m_aLinkURL;
1690 m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, sal_False );
1694 if ( !aOldLinkFilter.equals( m_aLinkFilterName ) )
1696 uno::Sequence< beans::NamedValue > aObject = aHelper.GetObjectPropsByFilter( m_aLinkFilterName );
1698 // TODO/LATER: probably the document holder could be cleaned explicitly as in the destructor
1699 m_pDocHolder->release();
1700 m_pDocHolder = NULL;
1702 LinkInit_Impl( aObject, lArguments, lObjArgs );
1706 m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );
1708 // TODO: use lObjArgs for StoreVisualReplacement
1709 for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
1710 if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
1712 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
1713 if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
1714 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
1716 break;
1719 // TODO:
1720 // when document allows reloading through API the object can be reloaded not only in loaded state
1722 sal_Bool bOldReadOnlyValue = m_bReadOnly;
1724 m_bReadOnly = sal_False;
1725 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1726 if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
1727 lArguments[nInd].Value >>= m_bReadOnly;
1729 if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLink )
1731 // close own storage
1732 try {
1733 uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
1734 OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
1735 if ( xComponent.is() )
1736 xComponent->dispose();
1738 catch ( uno::Exception& )
1742 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1743 m_xObjectStorage = m_xParentStorage->openStorageElement( m_aEntryName, nStorageMode );
1747 //------------------------------------------------------
1748 void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
1749 const ::rtl::OUString& sEntName )
1750 throw ( lang::IllegalArgumentException,
1751 embed::WrongStateException,
1752 io::IOException,
1753 uno::Exception,
1754 uno::RuntimeException )
1756 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1757 if ( m_bDisposed )
1758 throw lang::DisposedException(); // TODO
1760 if ( !m_bIsLink )
1762 // it must be a linked initialized object
1763 throw embed::WrongStateException(
1764 ::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ),
1765 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1767 #if 0
1768 else
1770 // the current implementation of OOo links does not implement this method since it does not implement
1771 // all the set of interfaces required for OOo embedded object ( XEmbedPersist is not supported ).
1772 throw io::IOException(); // TODO:
1774 #endif
1776 if ( !xStorage.is() )
1777 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
1778 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1779 1 );
1781 if ( !sEntName.getLength() )
1782 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
1783 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1784 2 );
1786 if ( !m_bIsLink || m_nObjectState == -1 )
1788 // it must be a linked initialized object
1789 throw embed::WrongStateException(
1790 ::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ),
1791 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1794 if ( m_bWaitSaveCompleted )
1795 throw embed::WrongStateException(
1796 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1797 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1799 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1800 if ( !xNameAccess.is() )
1801 throw uno::RuntimeException(); //TODO
1803 // detect entry existence
1804 /*sal_Bool bElExists =*/ xNameAccess->hasByName( sEntName );
1806 m_bReadOnly = sal_False;
1807 // sal_Int32 nStorageMode = embed::ElementModes::READWRITE;
1809 if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
1810 SwitchOwnPersistence( xStorage, sEntName );
1812 // for linked object it means that it becomes embedded object
1813 // the document must switch it's persistence also
1815 // TODO/LATER: handle the case when temp doc can not be created
1816 // the document is a new embedded object so it must be marked as modified
1817 uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
1818 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1819 if ( !xModif.is() )
1820 throw uno::RuntimeException();
1823 xModif->setModified( sal_True );
1825 catch( uno::Exception& )
1828 m_pDocHolder->SetComponent( xDocument, m_bReadOnly );
1829 OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If document cant be created, an exception must be thrown!\n" );
1831 if ( m_nObjectState == embed::EmbedStates::LOADED )
1833 // the state is changed and can not be switched to loaded state back without saving
1834 m_nObjectState = embed::EmbedStates::RUNNING;
1835 StateChangeNotification_Impl( sal_False, embed::EmbedStates::LOADED, m_nObjectState, aGuard );
1837 else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
1838 m_pDocHolder->Show();
1840 m_bIsLink = sal_False;
1841 m_aLinkFilterName = ::rtl::OUString();
1842 m_aLinkURL = ::rtl::OUString();
1845 //------------------------------------------------------
1846 sal_Bool SAL_CALL OCommonEmbeddedObject::isLink()
1847 throw ( embed::WrongStateException,
1848 uno::RuntimeException )
1850 ::osl::MutexGuard aGuard( m_aMutex );
1851 if ( m_bDisposed )
1852 throw lang::DisposedException(); // TODO
1854 // Actually this information is clear even in case object is wayting for saveCompleted
1855 // if ( m_bWaitSaveCompleted )
1856 // throw embed::WrongStateException(
1857 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1858 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );
1860 return m_bIsLink;
1863 //------------------------------------------------------
1864 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getLinkURL()
1865 throw ( embed::WrongStateException,
1866 uno::Exception,
1867 uno::RuntimeException )
1869 ::osl::MutexGuard aGuard( m_aMutex );
1870 if ( m_bDisposed )
1871 throw lang::DisposedException(); // TODO
1873 // Actually this information is clear even in case object is wayting for saveCompleted
1874 // if ( m_bWaitSaveCompleted )
1875 // throw embed::WrongStateException(
1876 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1877 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );
1879 if ( !m_bIsLink )
1880 throw embed::WrongStateException(
1881 ::rtl::OUString::createFromAscii( "The object is not a link object!\n" ),
1882 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1884 return m_aLinkURL;