20#include <com/sun/star/container/XChild.hpp>
21#include <com/sun/star/container/XNameAccess.hpp>
22#include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
23#include <com/sun/star/embed/WrongStateException.hpp>
24#include <com/sun/star/embed/XEmbeddedObject.hpp>
25#include <com/sun/star/embed/XEmbedPersist.hpp>
26#include <com/sun/star/embed/XLinkageSupport.hpp>
27#include <com/sun/star/embed/XTransactedObject.hpp>
28#include <com/sun/star/embed/XOptimizedStorage.hpp>
29#include <com/sun/star/embed/EntryInitModes.hpp>
30#include <com/sun/star/io/IOException.hpp>
31#include <com/sun/star/util/XCloseable.hpp>
32#include <com/sun/star/util/XModifiable.hpp>
33#include <com/sun/star/embed/EmbedStates.hpp>
34#include <com/sun/star/beans/XPropertySetInfo.hpp>
35#include <com/sun/star/beans/XPropertySet.hpp>
36#include <com/sun/star/embed/Aspects.hpp>
37#include <com/sun/star/embed/EmbedMisc.hpp>
50#include <unordered_map>
67 uno::WeakReference < uno::XInterface >
m_xModel;
82 "ObjectReplacements", embed::ElementModes::READWRITE );
84 catch (
const uno::Exception&)
87 "ObjectReplacements", embed::ElementModes::READ );
92 throw io::IOException(
"No ObjectReplacements");
101 pImpl->mbOwnsStorage =
true;
102 pImpl->mbUserAllowsLinkUpdate =
true;
103 pImpl->mpTempObjectContainer =
nullptr;
109 pImpl->mxStorage = rStor;
110 pImpl->mbOwnsStorage =
false;
111 pImpl->mbUserAllowsLinkUpdate =
true;
112 pImpl->mpTempObjectContainer =
nullptr;
116 : pImpl(new EmbedImpl)
118 pImpl->mxStorage = rStor;
119 pImpl->mbOwnsStorage =
false;
120 pImpl->mbUserAllowsLinkUpdate =
true;
121 pImpl->mpTempObjectContainer =
nullptr;
129 if (
pImpl->mbOwnsStorage )
130 pImpl->mxStorage->dispose();
132 pImpl->mxStorage = rStor;
133 pImpl->mbOwnsStorage =
false;
138 if ( !
pImpl->mxImageStorage )
143 bool bReadOnlyMode =
true;
144 uno::Reference < beans::XPropertySet > xSet(
pImpl->mxImageStorage,uno::UNO_QUERY);
149 uno::Any aAny = xSet->getPropertyValue(
"OpenMode");
150 if ( aAny >>= nMode )
151 bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
153 if ( !bReadOnlyMode )
155 uno::Reference< embed::XTransactedObject > xTransact(
pImpl->mxImageStorage, uno::UNO_QUERY_THROW );
159 catch (
const uno::Exception&)
171 if (
pImpl->mxImageStorage.is() )
175 pImpl->mxImageStorage->dispose();
176 pImpl->mxImageStorage.clear();
178 catch (
const uno::Exception&)
180 SAL_WARN(
"comphelper.container",
"Problems releasing image substorage!" );
189 if (
pImpl->mbOwnsStorage )
190 pImpl->mxStorage->dispose();
192 delete pImpl->mpTempObjectContainer;
197 for(
const auto& rObj :
pImpl->maNameToObjectMap )
199 uno::Reference < util::XCloseable >
const & xClose = rObj.second;
204 xClose->close(
true );
206 catch (
const uno::Exception&)
219 aStr =
"Object " + OUString::number(
i++ );
234 return !
pImpl->maNameToObjectMap.empty();
239 auto aIt =
pImpl->maNameToObjectMap.find( rName );
240 if (aIt !=
pImpl->maNameToObjectMap.end())
242 if (!
pImpl->mxStorage.is())
244 return pImpl->mxStorage->hasByName(rName);
249 return pImpl->maObjectToNameMap.find(xObj) !=
pImpl->maObjectToNameMap.end();
257 auto aIt =
pImpl->maNameToObjectMap.find( rName );
258 return ( aIt !=
pImpl->maNameToObjectMap.end() );
263 auto it =
pImpl->maObjectToNameMap.find(xObj);
264 if (it ==
pImpl->maObjectToNameMap.end())
266 SAL_WARN(
"comphelper.container",
"Unknown object!" );
272uno::Reference< embed::XEmbeddedObject>
274 const OUString& rName, OUString
const*
const pBaseURL)
276 SAL_WARN_IF( rName.isEmpty(),
"comphelper.container",
"Empty object name!");
278 uno::Reference < embed::XEmbeddedObject > xObj;
279 auto aIt =
pImpl->maNameToObjectMap.find( rName );
281#if OSL_DEBUG_LEVEL > 1
282 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
283 uno::Sequence< OUString>
aSeq = xAccess->getElementNames();
284 const OUString* pIter =
aSeq.getConstArray();
285 const OUString* pEnd = pIter +
aSeq.getLength();
286 for(;pIter != pEnd;++pIter)
290 OSL_ENSURE( aIt !=
pImpl->maNameToObjectMap.end() || xAccess->hasByName(rName),
"Could not return object!" );
294 if ( aIt !=
pImpl->maNameToObjectMap.end() )
295 xObj = (*aIt).second;
297 xObj =
Get_Impl(rName, uno::Reference<embed::XEmbeddedObject>(), pBaseURL);
303 const OUString& rName,
304 const uno::Reference<embed::XEmbeddedObject>& xCopy,
305 OUString
const*
const pBaseURL)
307 uno::Reference < embed::XEmbeddedObject > xObj;
311 uno::Reference < beans::XPropertySet > xSet(
pImpl->mxStorage, uno::UNO_QUERY );
312 bool bReadOnlyMode =
true;
317 uno::Any aAny = xSet->getPropertyValue(
"OpenMode");
318 if ( aAny >>= nMode )
319 bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
325 uno::Sequence< beans::PropertyValue > aObjDescr(1 + (xCopy.is() ? 1 : 0) + (pBaseURL ? 1 : 0));
326 auto itObjDescr = aObjDescr.getArray();
327 itObjDescr->Name =
"Parent";
328 itObjDescr->Value <<=
pImpl->m_xModel.get();
332 itObjDescr->Name =
"DefaultParentBaseURL";
333 itObjDescr->Value <<= *pBaseURL;
338 itObjDescr->Name =
"CloneFrom";
339 itObjDescr->Value <<= xCopy;
343 "ReadOnly", bReadOnlyMode) };
344 xObj.set(
xFactory->createInstanceInitFromEntry(
345 pImpl->mxStorage, rName,
346 aMediaDescr, aObjDescr ), uno::UNO_QUERY );
351 catch (uno::Exception
const& e)
353 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::Get_Impl: exception caught: " << e);
360 const uno::Sequence < beans::PropertyValue >& rArgs, OUString& rNewName, OUString
const* pBaseURL )
362 if ( rNewName.isEmpty() )
368 uno::Reference < embed::XEmbeddedObject > xObj;
373 const size_t nExtraArgs = pBaseURL ? 2 : 1;
374 uno::Sequence< beans::PropertyValue > aObjDescr( rArgs.getLength() + nExtraArgs );
375 auto pObjDescr = aObjDescr.getArray();
376 pObjDescr[0].Name =
"Parent";
377 pObjDescr[0].Value <<=
pImpl->m_xModel.get();
380 pObjDescr[1].Name =
"DefaultParentBaseURL";
381 pObjDescr[1].Value <<= *pBaseURL;
383 std::copy( rArgs.begin(), rArgs.end(), pObjDescr + nExtraArgs );
384 xObj.set(
xFactory->createInstanceInitNew(
385 rClassId, OUString(),
pImpl->mxStorage, rNewName,
386 aObjDescr ), uno::UNO_QUERY );
390 OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
391 "A freshly create object should be running always!" );
393 catch (uno::Exception
const& e)
395 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::CreateEmbeddedObject: exception caught: " << e);
403 return CreateEmbeddedObject( rClassId, uno::Sequence < beans::PropertyValue >(), rNewName, pBaseURL );
408#if OSL_DEBUG_LEVEL > 1
409 SAL_WARN_IF( rName.isEmpty(),
"comphelper.container",
"Added object doesn't have a name!");
410 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
411 uno::Reference < embed::XEmbedPersist > xEmb( xObj, uno::UNO_QUERY );
412 uno::Reference < embed::XLinkageSupport > xLink( xEmb, uno::UNO_QUERY );
414 OSL_ENSURE( !( xEmb.is() && ( !xLink.is() || !xLink->isLink() ) ) || xAccess->hasByName(rName),
415 "Added element not in storage!" );
419 auto aIt =
pImpl->maNameToObjectMap.find( rName );
420 OSL_ENSURE( aIt ==
pImpl->maNameToObjectMap.end(),
"Element already inserted!" );
421 pImpl->maNameToObjectMap[ rName ] = xObj;
422 pImpl->maObjectToNameMap[ xObj ] = rName;
423 uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
424 if ( xChild.is() && xChild->getParent() !=
pImpl->m_xModel.get() )
425 xChild->setParent(
pImpl->m_xModel.get() );
428 if ( !
pImpl->mpTempObjectContainer )
431 auto& rObjectContainer =
pImpl->mpTempObjectContainer->pImpl->maNameToObjectMap;
432 auto aIter = std::find_if(rObjectContainer.begin(), rObjectContainer.end(),
433 [&xObj](
const EmbeddedObjectContainerNameMap::value_type& rEntry) { return rEntry.second == xObj; });
434 if (aIter == rObjectContainer.end())
438 OUString aTempName = aIter->first;
440 uno::Reference < io::XInputStream >
xStream =
pImpl->mpTempObjectContainer->GetGraphicStream( xObj, &aMediaType );
445 pImpl->mpTempObjectContainer->RemoveGraphicStream( aTempName );
449 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
454 pImpl->mpTempObjectContainer->pImpl->mxStorage->removeElement( aTempName );
456 catch (
const uno::Exception&)
462 pImpl->mpTempObjectContainer->pImpl->maObjectToNameMap.erase( aIter->second );
463 pImpl->mpTempObjectContainer->pImpl->maNameToObjectMap.erase( aIter );
467 const uno::Reference < embed::XEmbeddedObject >& xObj, OUString& rName,
bool bCopy,
468 const OUString& rSrcShellID,
const OUString& rDestShellID )
470 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
471 if ( rName.isEmpty() )
474#if OSL_DEBUG_LEVEL > 1
475 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
476 OSL_ENSURE( !xPersist.is() || !xAccess->hasByName(rName),
"Inserting element already present in storage!" );
477 OSL_ENSURE( xPersist.is() || xObj->getCurrentState() == embed::EmbedStates::RUNNING,
"Non persistent object inserted!");
485 uno::Sequence < beans::PropertyValue >
aSeq;
489 {
"SourceShellID",
uno::Any(rSrcShellID) },
490 {
"DestinationShellID",
uno::Any(rDestShellID) }
492 xPersist->storeToEntry(
pImpl->mxStorage, rName,
aSeq, aObjArgs);
498 xPersist->storeAsEntry(
pImpl->mxStorage, rName,
aSeq,
aSeq );
499 xPersist->saveCompleted(
true );
503 catch (uno::Exception
const& e)
505 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::StoreEmbeddedObject: exception caught: " << e);
528 if ( rNewName.isEmpty() )
532 bool bIsStorage =
false;
541 uno::Reference < embed::XStorage > xNewStore =
pImpl->mxStorage->openStorageElement( rNewName, embed::ElementModes::READWRITE );
542 xStore->copyToStorage( xNewStore );
544 catch (
const uno::Exception&)
548 return uno::Reference < embed::XEmbeddedObject >();
553 uno::Reference < io::XStream > xNewStream =
pImpl->mxStorage->openStreamElement( rNewName, embed::ElementModes::READWRITE );
559 uno::Reference< beans::XPropertySet > xProps( xNewStream, uno::UNO_QUERY_THROW );
560 xProps->setPropertyValue(
"MediaType",
561 uno::Any( OUString(
"application/vnd.sun.star.oleobject" ) ) );
563 catch (uno::Exception
const& e)
566 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::InsertEmbeddedObject: exception caught: " << e);
567 return uno::Reference < embed::XEmbeddedObject >();
577 pImpl->mxStorage->removeElement( rNewName );
579 catch (
const uno::Exception&)
588 if ( rNewName.isEmpty() )
591 uno::Reference < embed::XEmbeddedObject > xObj;
595 uno::Sequence< beans::PropertyValue > aObjDescr(pBaseURL ? 2 : 1);
596 auto pObjDescr = aObjDescr.getArray();
597 pObjDescr[0].Name =
"Parent";
598 pObjDescr[0].Value <<=
pImpl->m_xModel.get();
601 pObjDescr[1].Name =
"DefaultParentBaseURL";
602 pObjDescr[1].Value <<= *pBaseURL;
604 xObj.set(
xFactory->createInstanceInitFromMediaDescriptor(
605 pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
606 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
608 OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
609 "A freshly create object should be running always!" );
613 xPersist->storeOwn();
617 catch (
const uno::Exception&)
626 if ( rNewName.isEmpty() )
629 uno::Reference < embed::XEmbeddedObject > xObj;
634 "Parent",
pImpl->m_xModel.get()) };
635 xObj.set(
xFactory->createInstanceLink(
pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
637 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
639 OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
640 "A freshly create object should be running always!" );
644 xPersist->storeOwn();
648 catch (uno::Exception
const& e)
650 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::InsertEmbeddedLink: "
651 "exception caught: " << e);
658 const OUString& aOrigName,
659 const OUString& aTargetName )
661 bool bResult =
false;
663 if ( ( &rSrc !=
this || aOrigName != aTargetName ) && !aOrigName.isEmpty() && !aTargetName.isEmpty() )
666 uno::Reference < io::XInputStream > xGrStream = rSrc.
GetGraphicStream( aOrigName, &aMediaType );
667 if ( xGrStream.is() )
676 const OUString& rSrcShellID,
const OUString& rDestShellID )
678 uno::Reference< embed::XEmbeddedObject > xResult;
685 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY_THROW );
686 aOrigName = xPersist->getEntryName();
688 catch (
const uno::Exception&)
692 if ( rName.isEmpty() )
698 SAL_INFO_IF(rDestShellID.isEmpty(),
"comphelper.container",
699 "SfxObjectShell with no base URL?");
700 xResult =
Get_Impl(rName, xObj, &rDestShellID);
707 uno::Reference< embed::XLinkageSupport > xOrigLinkage( xObj, uno::UNO_QUERY );
708 if ( xOrigLinkage.is() && xOrigLinkage->isLink() )
711 OUString
aURL = xOrigLinkage->getLinkURL();
712 if (
aURL.isEmpty() )
713 throw uno::RuntimeException();
716 uno::Reference < embed::XEmbeddedObjectCreator > xCreator =
722 "Parent",
pImpl->m_xModel.get()) };
723 xResult.set(xCreator->createInstanceLink(
728 uno::UNO_QUERY_THROW );
733 if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
734 xObj->changeState( embed::EmbedStates::RUNNING );
737 uno::Reference< beans::XPropertySet > xOrigProps( xObj->getComponent(), uno::UNO_QUERY_THROW );
740 uno::Reference < embed::XEmbeddedObjectCreator > xCreator =
744 "Parent",
pImpl->m_xModel.get()) };
745 xResult.set(xCreator->createInstanceInitNew(
747 xObj->getClassName(),
751 uno::UNO_QUERY_THROW );
753 if ( xResult->getCurrentState() == embed::EmbedStates::LOADED )
754 xResult->changeState( embed::EmbedStates::RUNNING );
756 uno::Reference< beans::XPropertySet > xTargetProps( xResult->getComponent(), uno::UNO_QUERY_THROW );
759 uno::Reference< beans::XPropertySetInfo > xOrigInfo = xOrigProps->getPropertySetInfo();
760 if ( !xOrigInfo.is() )
761 throw uno::RuntimeException();
763 const uno::Sequence< beans::Property > aPropertiesList = xOrigInfo->getProperties();
764 for (
const auto &
p : aPropertiesList )
768 xTargetProps->setPropertyValue(
770 xOrigProps->getPropertyValue(
p.Name ) );
772 catch (
const beans::PropertyVetoException&)
776 SAL_WARN(
"comphelper.container",
"Could not copy readonly property!" );
784 catch (
const uno::Exception&)
790 xResult->close(
true );
792 catch (
const uno::Exception&)
801 SAL_WARN_IF( !xResult.is(),
"comphelper.container",
"Can not copy embedded object that has no persistence!" );
806 if ( !aOrigName.isEmpty() )
812 if ( xResult->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD )
813 xResult->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT,
814 xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
816 catch (
const uno::Exception&)
835 auto aIt2 = rCnt.
pImpl->maNameToObjectMap.find( rName );
836 OSL_ENSURE( aIt2 == rCnt.
pImpl->maNameToObjectMap.end(),
"Object does already exist in target container!" );
838 if ( aIt2 != rCnt.
pImpl->maNameToObjectMap.end() )
841 uno::Reference < embed::XEmbeddedObject > xObj;
842 auto aIt =
pImpl->maNameToObjectMap.find( rName );
843 if ( aIt !=
pImpl->maNameToObjectMap.end() )
845 xObj = (*aIt).second;
851 OUString
aName( rName );
853 pImpl->maObjectToNameMap.erase( aIt->second );
854 pImpl->maNameToObjectMap.erase( aIt );
855 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
857 pImpl->mxStorage->removeElement( rName );
862 uno::Reference < embed::XStorage > xOld =
pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READ );
863 uno::Reference < embed::XStorage > xNew = rCnt.
pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READWRITE );
864 xOld->copyToStorage( xNew );
872 catch (
const uno::Exception&)
874 SAL_WARN(
"comphelper.container",
"Could not move object!");
880 SAL_WARN(
"comphelper.container",
"Unknown object!");
887 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
890 aName = xPersist->getEntryName();
892#if OSL_DEBUG_LEVEL > 1
893 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
894 uno::Reference < embed::XLinkageSupport > xLink( xPersist, uno::UNO_QUERY );
895 sal_Bool bIsNotEmbedded = !xPersist.is() || ( xLink.is() && xLink->isLink() );
898 OSL_ENSURE( bIsNotEmbedded || xAccess->hasByName(aName),
"Removing element not present in storage!" );
904 if ( xPersist.is() && bKeepToTempStorage )
907 if ( !
pImpl->mpTempObjectContainer )
914 OUString aOrigStorMediaType;
915 uno::Reference< beans::XPropertySet > xStorProps(
pImpl->mxStorage, uno::UNO_QUERY_THROW );
916 static constexpr OUStringLiteral s_sMediaType(u
"MediaType");
917 xStorProps->getPropertyValue( s_sMediaType ) >>= aOrigStorMediaType;
919 SAL_WARN_IF( aOrigStorMediaType.isEmpty(),
"comphelper.container",
"No valuable media type in the storage!" );
921 uno::Reference< beans::XPropertySet > xTargetStorProps(
922 pImpl->mpTempObjectContainer->pImpl->mxStorage,
923 uno::UNO_QUERY_THROW );
924 xTargetStorProps->setPropertyValue( s_sMediaType,
uno::Any( aOrigStorMediaType ) );
926 catch (
const uno::Exception&)
928 SAL_WARN(
"comphelper.container",
"Can not set the new media type to a storage!" );
932 OUString aTempName, aMediaType;
938 if( !
pImpl->mpTempObjectContainer->HasEmbeddedObject(aName) )
941 pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName );
945 pImpl->mpTempObjectContainer->InsertGraphicStream( xStream, aTempName, aMediaType );
948 xObj->changeState( embed::EmbedStates::LOADED );
952 xObj->changeState( embed::EmbedStates::RUNNING );
954 catch (
const uno::Exception&)
959 auto aIter = std::find_if(
pImpl->maNameToObjectMap.begin(),
pImpl->maNameToObjectMap.end(),
960 [&xObj](
const EmbeddedObjectContainerNameMap::value_type& rEntry) { return rEntry.second == xObj; });
961 if (aIter !=
pImpl->maNameToObjectMap.end())
963 pImpl->maObjectToNameMap.erase( aIter->second );
964 pImpl->maNameToObjectMap.erase( aIter );
965 uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
967 xChild->setParent( uno::Reference < uno::XInterface >() );
970 SAL_WARN(
"comphelper.container",
"Object not found for removal!" );
972 if ( !xPersist || !bKeepToTempStorage )
981#if OSL_DEBUG_LEVEL > 1
983 OSL_ENSURE( bIsNotEmbedded ||
pImpl->mxStorage->hasByName( aName ),
"The object has no persistence entry in the storage!" );
985 if ( xPersist.is() &&
pImpl->mxStorage->hasByName( aName ) )
986 pImpl->mxStorage->removeElement( aName );
988 catch (
const uno::Exception&)
990 SAL_WARN(
"comphelper.container",
"Failed to remove object from storage!" );
1001 auto aIter = std::find_if(
pImpl->maNameToObjectMap.begin(),
pImpl->maNameToObjectMap.end(),
1002 [&xObj](
const EmbeddedObjectContainerNameMap::value_type& rEntry) { return rEntry.second == xObj; });
1003 if (aIter ==
pImpl->maNameToObjectMap.end())
1006 pImpl->maObjectToNameMap.erase( aIter->second );
1007 pImpl->maNameToObjectMap.erase( aIter );
1011 xObj->close(
true );
1013 catch (
const uno::Exception&)
1022 uno::Reference < io::XInputStream >
xStream;
1024 SAL_WARN_IF(
aName.isEmpty(),
"comphelper.container",
"Retrieving graphic for unknown object!" );
1025 if ( !
aName.isEmpty() )
1029 uno::Reference < embed::XStorage > xReplacements =
pImpl->GetReplacements();
1030 uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement(
aName, embed::ElementModes::READ );
1031 xStream = xGraphicStream->getInputStream();
1034 uno::Reference < beans::XPropertySet > xSet(
xStream, uno::UNO_QUERY );
1037 uno::Any aAny = xSet->getPropertyValue(
"MediaType");
1038 aAny >>= *pMediaType;
1042 catch (uno::Exception
const& e)
1045 "EmbeddedObjectContainer::GetGraphicStream(): " << e);
1062 uno::Reference < embed::XStorage > xReplacements =
pImpl->GetReplacements();
1065 uno::Reference < io::XOutputStream > xOutStream;
1066 uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( rObjectName,
1067 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
1068 xOutStream = xGraphicStream->getOutputStream();
1070 xOutStream->flush();
1072 uno::Reference< beans::XPropertySet > xPropSet( xGraphicStream, uno::UNO_QUERY_THROW );
1074 xPropSet->setPropertyValue(
"UseCommonStoragePasswordEncryption",
1076 xPropSet->setPropertyValue(
"MediaType",
uno::Any(rMediaType) );
1078 xPropSet->setPropertyValue(
"Compressed",
1081 catch (
const uno::Exception&)
1093 uno::Reference < embed::XStorage > xReplacement =
pImpl->GetReplacements();
1094 uno::Reference < embed::XOptimizedStorage > xOptRepl( xReplacement, uno::UNO_QUERY_THROW );
1097 uno::Sequence< beans::PropertyValue > aProps{
1103 if ( xReplacement->hasByName( rObjectName ) )
1104 xReplacement->removeElement( rObjectName );
1106 xOptRepl->insertStreamElementDirect( rObjectName, rStream, aProps );
1108 catch (
const uno::Exception&)
1121 uno::Reference < embed::XStorage > xReplacements =
pImpl->GetReplacements();
1122 xReplacements->removeElement( rObjectName );
1124 catch (
const uno::Exception&)
1129 void InsertStreamIntoPicturesStorage_Impl(
const uno::Reference< embed::XStorage >& xDocStor,
1130 const uno::Reference< io::XInputStream >& xInStream,
1131 const OUString& aStreamName )
1133 OSL_ENSURE( !aStreamName.isEmpty() && xInStream.is() && xDocStor.is(),
"Misuse of the method!" );
1137 uno::Reference< embed::XStorage > xPictures = xDocStor->openStorageElement(
1139 embed::ElementModes::READWRITE );
1140 uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement(
1142 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
1143 uno::Reference< io::XOutputStream > xOutStream(
1144 xObjReplStr->getInputStream(), uno::UNO_QUERY_THROW );
1147 xOutStream->closeOutput();
1149 uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY );
1150 if ( xTransact.is() )
1151 xTransact->commit();
1153 catch (
const uno::Exception&)
1155 SAL_WARN(
"comphelper.container",
"The images storage is not available!" );
1162 const uno::Reference < embed::XStorage >& _xStorage)
1164 bool bResult =
false;
1169 const OUString* pIter = aNames.getConstArray();
1170 const OUString* pEnd = pIter + aNames.getLength();
1171 for(;pIter != pEnd;++pIter)
1174 SAL_WARN_IF( !xObj.is(),
"comphelper.container",
"An empty entry in the embedded objects list!" );
1177 bool bSwitchBackToLoaded =
false;
1178 uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
1180 uno::Reference < io::XInputStream >
xStream;
1181 OUString aMediaType;
1183 sal_Int32 nCurState = xObj->getCurrentState();
1184 if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
1195 if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
1196 bSwitchBackToLoaded =
true;
1199 embed::Aspects::MSOLE_CONTENT,
1204 if ( _bOasisFormat || (xLink.is() && xLink->isLink()) )
1208 if ( _bOasisFormat )
1211 if ( _bCreateEmbedded
1218 InsertStreamIntoPicturesStorage_Impl( _xStorage,
xStream, *pIter );
1223 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
1224 if ( xPersist.is() )
1226 uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat ? 3 : 4 );
1227 auto pArgs = aArgs.getArray();
1228 pArgs[0].Name =
"StoreVisualReplacement";
1229 pArgs[0].Value <<= !_bOasisFormat;
1232 pArgs[1].Name =
"CanTryOptimization";
1233 pArgs[1].Value <<= !_bCreateEmbedded;
1235 pArgs[2].Name =
"AutoSaveEvent";
1236 pArgs[2].Value <<= _bAutoSaveEvent;
1238 if ( !_bOasisFormat )
1241 pArgs[3].Name =
"VisualReplacement";
1247 xPersist->storeAsEntry( _xStorage, xPersist->getEntryName(), uno::Sequence< beans::PropertyValue >(), aArgs );
1249 catch (
const embed::WrongStateException&)
1251 SAL_WARN(
"comphelper.container",
"failed to store '" << *pIter <<
"'");
1255 if ( bSwitchBackToLoaded )
1257 xObj->changeState( embed::EmbedStates::LOADED );
1264 catch (
const uno::Exception& e)
1268 SAL_WARN(
"comphelper.container",
"failed. Message: " << e);
1272 if ( !_bOasisFormat && bResult )
1277 OUString aObjReplElement(
"ObjectReplacements" );
1278 if ( _xStorage->hasByName( aObjReplElement ) && _xStorage->isStorageElement( aObjReplElement ) )
1279 _xStorage->removeElement( aObjReplElement );
1281 catch (
const uno::Exception&)
1292 bool bResult =
true;
1294 const OUString* pIter = aNames.getConstArray();
1295 const OUString* pEnd = pIter + aNames.getLength();
1296 for(;pIter != pEnd;++pIter)
1301 SAL_WARN_IF( !xObj.is(),
"comphelper.container",
"An empty entry in the embedded objects list!" );
1304 sal_Int32 nCurState = xObj->getCurrentState();
1305 if ( _bOasisFormat && nCurState != embed::EmbedStates::LOADED && nCurState != embed::EmbedStates::RUNNING )
1309 OUString aMediaType;
1312 uno::Reference < io::XInputStream >
xStream =
1314 embed::Aspects::MSOLE_CONTENT,
1332 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
1333 if ( xPersist.is() )
1343 if (_bObjectsOnly && (nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING)
1344 && (
pImpl->mxStorage->isStorageElement( *pIter ) ))
1346 uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
1347 if ( xModifiable.is() && xModifiable->isModified())
1349 xPersist->storeOwn();
1358 xPersist->storeOwn();
1362 catch (
const uno::Exception&)
1370 if ( !_bOasisFormat && !_bObjectsOnly )
1375 uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
1376 if ( xLink.is() && xLink->isLink() )
1378 OUString aMediaType;
1379 uno::Reference < io::XInputStream > xInStream =
GetGraphicStream( xObj, &aMediaType );
1380 if ( xInStream.is() )
1381 InsertStreamIntoPicturesStorage_Impl(
pImpl->mxStorage, xInStream, *pIter );
1384 catch (
const uno::Exception&)
1390 catch (
const uno::Exception&)
1396 if ( bResult && _bOasisFormat )
1399 if ( bResult && !_bObjectsOnly )
1404 OUString aObjReplElement(
"ObjectReplacements" );
1405 if ( !_bOasisFormat &&
pImpl->mxStorage->hasByName( aObjReplElement ) &&
pImpl->mxStorage->isStorageElement( aObjReplElement ) )
1406 pImpl->mxStorage->removeElement( aObjReplElement );
1408 catch (
const uno::Exception&)
1418 sal_Int64 nViewAspect,
1419 const uno::Reference< embed::XEmbeddedObject >& xObj,
1420 OUString* pMediaType )
1422 uno::Reference< io::XInputStream > xInStream;
1428 embed::VisualRepresentation aRep = xObj->getPreferredVisualRepresentation( nViewAspect );
1430 *pMediaType = aRep.Flavor.MimeType;
1432 uno::Sequence < sal_Int8 >
aSeq;
1434 xInStream = new ::comphelper::SequenceInputStream(
aSeq );
1436 catch (
const uno::Exception&)
1446 bool bError =
false;
1448 const OUString* pIter = aNames.getConstArray();
1449 const OUString* pEnd = pIter + aNames.getLength();
1450 for(;pIter != pEnd;++pIter)
1453 SAL_WARN_IF( !xObj.is(),
"comphelper.container",
"An empty entry in the embedded objects list!" );
1456 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
1457 if ( xPersist.is() )
1461 xPersist->setPersistentEntry( _xStorage,
1463 embed::EntryInitModes::NO_INIT,
1464 uno::Sequence< beans::PropertyValue >(),
1465 uno::Sequence< beans::PropertyValue >() );
1468 catch (
const uno::Exception&)
1475 if ( _bClearModifiedFlag )
1480 uno::Reference< util::XModifiable > xModif( xObj->getComponent(), uno::UNO_QUERY_THROW );
1481 if ( xModif->isModified() )
1482 xModif->setModified(
false );
1484 catch (
const uno::Exception&)
1495 return pImpl->mbUserAllowsLinkUpdate;
1500 if(
pImpl->mbUserAllowsLinkUpdate != bNew)
1502 pImpl->mbUserAllowsLinkUpdate = bNew;
OUString CreateUniqueObjectName()
bool StoreAsChildren(bool _bOasisFormat, bool _bCreateEmbedded, bool _bAutoSaveEvent, const css::uno::Reference< css::embed::XStorage > &_xStorage)
bool InsertGraphicStreamDirectly(const css::uno::Reference< css::io::XInputStream > &rStream, const OUString &rObjectName, const OUString &rMediaType)
css::uno::Reference< css::io::XInputStream > GetGraphicStream(const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString *pMediaType=nullptr)
bool MoveEmbeddedObject(const OUString &rName, EmbeddedObjectContainer &)
void CloseEmbeddedObjects()
bool SetPersistentEntries(const css::uno::Reference< css::embed::XStorage > &_xStorage, bool _bClearModifiedFlag=true)
call setPersistentEntry for each embedded object in the container
void RemoveGraphicStream(const OUString &rObjectName)
bool getUserAllowsLinkUpdate() const
EmbeddedObjectContainer()
void AddEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &, const OUString &)
bool HasEmbeddedObject(const OUString &)
bool InsertGraphicStream(const css::uno::Reference< css::io::XInputStream > &rStream, const OUString &rObjectName, const OUString &rMediaType)
css::uno::Reference< css::embed::XEmbeddedObject > Get_Impl(const OUString &, const css::uno::Reference< css::embed::XEmbeddedObject > &xCopy, OUString const *pBaseURL)
bool StoreChildren(bool _bOasisFormat, bool _bObjectsOnly)
bool TryToCopyGraphReplacement(EmbeddedObjectContainer &rSrc, const OUString &aOrigName, const OUString &aTargetName)
void CloseEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &)
~EmbeddedObjectContainer()
OUString GetEmbeddedObjectName(const css::uno::Reference< css::embed::XEmbeddedObject > &) const
css::uno::Reference< css::embed::XEmbeddedObject > InsertEmbeddedLink(const css::uno::Sequence< css::beans::PropertyValue > &, OUString &)
void SwitchPersistence(const css::uno::Reference< css::embed::XStorage > &)
bool HasEmbeddedObjects() const
css::uno::Reference< css::embed::XEmbeddedObject > CopyAndGetEmbeddedObject(EmbeddedObjectContainer &rSrc, const css::uno::Reference< css::embed::XEmbeddedObject > &xObj, OUString &rName, const OUString &rSrcShellID, const OUString &rDestShellID)
void setUserAllowsLinkUpdate(bool bNew)
bool CommitImageSubStorage()
void RemoveEmbeddedObject(const OUString &rName, bool bKeepToTempStorage=true)
static css::uno::Reference< css::io::XInputStream > GetGraphicReplacementStream(sal_Int64 nViewAspect, const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString *pMediaType)
css::uno::Sequence< OUString > GetObjectNames() const
bool StoreEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &xObj, OUString &rName, bool bCopy, const OUString &rSrcShellID, const OUString &rDestShellID)
css::uno::Reference< css::embed::XEmbeddedObject > GetEmbeddedObject(const OUString &, OUString const *pBaseURL=nullptr)
void ReleaseImageSubStorage()
css::uno::Reference< css::embed::XEmbeddedObject > CreateEmbeddedObject(const css::uno::Sequence< sal_Int8 > &, OUString &, OUString const *pBaseURL=nullptr)
std::unique_ptr< EmbedImpl > pImpl
bool HasInstantiatedEmbeddedObject(const OUString &)
bool InsertEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString &)
static css::uno::Reference< css::embed::XStorage > GetStorageFromInputStream(const css::uno::Reference< css::io::XInputStream > &xStream, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
static css::uno::Reference< css::embed::XStorage > GetTemporaryStorage(const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
Reference< XSingleServiceFactory > xFactory
Sequence< sal_Int8 > aSeq
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unordered_map< OUString, uno::Reference< embed::XEmbeddedObject > > EmbeddedObjectContainerNameMap
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
Copy (keys or values) from an associate container into a Sequence.
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
Init list for property sequences.
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Creates a beans::PropertyValue easily, i.e.
const uno::Reference< embed::XStorage > & GetReplacements()
uno::Reference< embed::XStorage > mxImageStorage
std::unordered_map< uno::Reference< embed::XEmbeddedObject >, OUString > maObjectToNameMap
bool mbUserAllowsLinkUpdate
uno::WeakReference< uno::XInterface > m_xModel
uno::Reference< embed::XStorage > mxStorage
EmbeddedObjectContainer * mpTempObjectContainer
EmbeddedObjectContainerNameMap maNameToObjectMap
Reference< XModel > xModel