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>
49 #include <unordered_map>
66 uno::WeakReference < uno::XInterface >
m_xModel;
81 "ObjectReplacements", embed::ElementModes::READWRITE );
83 catch (
const uno::Exception&)
86 "ObjectReplacements", embed::ElementModes::READ );
91 throw io::IOException(
"No ObjectReplacements");
100 pImpl->mbOwnsStorage =
true;
101 pImpl->mbUserAllowsLinkUpdate =
true;
102 pImpl->mpTempObjectContainer =
nullptr;
108 pImpl->mxStorage = rStor;
109 pImpl->mbOwnsStorage =
false;
110 pImpl->mbUserAllowsLinkUpdate =
true;
111 pImpl->mpTempObjectContainer =
nullptr;
115 : pImpl(new EmbedImpl)
117 pImpl->mxStorage = rStor;
118 pImpl->mbOwnsStorage =
false;
119 pImpl->mbUserAllowsLinkUpdate =
true;
120 pImpl->mpTempObjectContainer =
nullptr;
121 pImpl->m_xModel = xModel;
128 if (
pImpl->mbOwnsStorage )
129 pImpl->mxStorage->dispose();
131 pImpl->mxStorage = rStor;
132 pImpl->mbOwnsStorage =
false;
137 if (
pImpl->mxImageStorage.is() )
141 bool bReadOnlyMode =
true;
142 uno::Reference < beans::XPropertySet > xSet(
pImpl->mxImageStorage,uno::UNO_QUERY);
147 uno::Any aAny = xSet->getPropertyValue(
"OpenMode");
148 if ( aAny >>= nMode )
149 bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
151 if ( !bReadOnlyMode )
153 uno::Reference< embed::XTransactedObject > xTransact(
pImpl->mxImageStorage, uno::UNO_QUERY_THROW );
157 catch (
const uno::Exception&)
170 if (
pImpl->mxImageStorage.is() )
174 pImpl->mxImageStorage->dispose();
175 pImpl->mxImageStorage.clear();
177 catch (
const uno::Exception&)
179 SAL_WARN(
"comphelper.container",
"Problems releasing image substorage!" );
188 if (
pImpl->mbOwnsStorage )
189 pImpl->mxStorage->dispose();
191 delete pImpl->mpTempObjectContainer;
196 for(
const auto& rObj :
pImpl->maNameToObjectMap )
198 uno::Reference < util::XCloseable >
const & xClose = rObj.second;
203 xClose->close(
true );
205 catch (
const uno::Exception&)
218 aStr =
"Object " + OUString::number( i++ );
233 return !
pImpl->maNameToObjectMap.empty();
238 auto aIt =
pImpl->maNameToObjectMap.find( rName );
239 if (aIt !=
pImpl->maNameToObjectMap.end())
241 if (!
pImpl->mxStorage.is())
243 return pImpl->mxStorage->hasByName(rName);
248 return pImpl->maObjectToNameMap.find(xObj) !=
pImpl->maObjectToNameMap.end();
256 auto aIt =
pImpl->maNameToObjectMap.find( rName );
257 return ( aIt !=
pImpl->maNameToObjectMap.end() );
262 auto it =
pImpl->maObjectToNameMap.find(xObj);
263 if (it ==
pImpl->maObjectToNameMap.end())
265 SAL_WARN(
"comphelper.container",
"Unknown object!" );
271 uno::Reference< embed::XEmbeddedObject>
273 const OUString& rName, OUString
const*
const pBaseURL)
275 SAL_WARN_IF( rName.isEmpty(),
"comphelper.container",
"Empty object name!");
277 uno::Reference < embed::XEmbeddedObject > xObj;
278 auto aIt =
pImpl->maNameToObjectMap.find( rName );
280 #if OSL_DEBUG_LEVEL > 1
281 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
282 uno::Sequence< OUString>
aSeq = xAccess->getElementNames();
283 const OUString* pIter = aSeq.getConstArray();
284 const OUString* pEnd = pIter + aSeq.getLength();
285 for(;pIter != pEnd;++pIter)
289 OSL_ENSURE( aIt !=
pImpl->maNameToObjectMap.end() || xAccess->hasByName(rName),
"Could not return object!" );
293 if ( aIt !=
pImpl->maNameToObjectMap.end() )
294 xObj = (*aIt).second;
296 xObj =
Get_Impl(rName, uno::Reference<embed::XEmbeddedObject>(), pBaseURL);
302 const OUString& rName,
303 const uno::Reference<embed::XEmbeddedObject>& xCopy,
304 OUString
const*
const pBaseURL)
306 uno::Reference < embed::XEmbeddedObject > xObj;
310 uno::Reference < beans::XPropertySet > xSet(
pImpl->mxStorage, uno::UNO_QUERY );
311 bool bReadOnlyMode =
true;
316 uno::Any aAny = xSet->getPropertyValue(
"OpenMode");
317 if ( aAny >>= nMode )
318 bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
324 uno::Sequence< beans::PropertyValue > aObjDescr(1 + (xCopy.is() ? 1 : 0) + (pBaseURL ? 1 : 0));
325 aObjDescr[0].Name =
"Parent";
326 aObjDescr[0].Value <<=
pImpl->m_xModel.get();
330 aObjDescr[i].Name =
"DefaultParentBaseURL";
331 aObjDescr[i].Value <<= *pBaseURL;
336 aObjDescr[i].Name =
"CloneFrom";
337 aObjDescr[i].Value <<= xCopy;
340 uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
341 aMediaDescr[0].Name =
"ReadOnly";
342 aMediaDescr[0].Value <<= bReadOnlyMode;
343 xObj.set( xFactory->createInstanceInitFromEntry(
344 pImpl->mxStorage, rName,
345 aMediaDescr, aObjDescr ), uno::UNO_QUERY );
350 catch (uno::Exception
const& e)
352 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::Get_Impl: exception caught: " << e);
359 const uno::Sequence < beans::PropertyValue >& rArgs, OUString& rNewName, OUString
const* pBaseURL )
361 if ( rNewName.isEmpty() )
367 uno::Reference < embed::XEmbeddedObject > xObj;
372 const size_t nExtraArgs = pBaseURL ? 2 : 1;
373 uno::Sequence< beans::PropertyValue > aObjDescr( rArgs.getLength() + nExtraArgs );
374 aObjDescr[0].Name =
"Parent";
375 aObjDescr[0].Value <<=
pImpl->m_xModel.get();
378 aObjDescr[1].Name =
"DefaultParentBaseURL";
379 aObjDescr[1].Value <<= *pBaseURL;
381 std::copy( rArgs.begin(), rArgs.end(), aObjDescr.getArray() + nExtraArgs );
382 xObj.set( xFactory->createInstanceInitNew(
383 rClassId, OUString(),
pImpl->mxStorage, rNewName,
384 aObjDescr ), uno::UNO_QUERY );
388 OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
389 "A freshly create object should be running always!" );
391 catch (uno::Exception
const& e)
393 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::CreateEmbeddedObject: exception caught: " << e);
401 return CreateEmbeddedObject( rClassId, uno::Sequence < beans::PropertyValue >(), rNewName, pBaseURL );
406 #if OSL_DEBUG_LEVEL > 1
407 SAL_WARN_IF( rName.isEmpty(),
"comphelper.container",
"Added object doesn't have a name!");
408 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
409 uno::Reference < embed::XEmbedPersist > xEmb( xObj, uno::UNO_QUERY );
410 uno::Reference < embed::XLinkageSupport > xLink( xEmb, uno::UNO_QUERY );
412 OSL_ENSURE( !( xEmb.is() && ( !xLink.is() || !xLink->isLink() ) ) || xAccess->hasByName(rName),
413 "Added element not in storage!" );
417 auto aIt =
pImpl->maNameToObjectMap.find( rName );
418 OSL_ENSURE( aIt ==
pImpl->maNameToObjectMap.end(),
"Element already inserted!" );
419 pImpl->maNameToObjectMap[ rName ] = xObj;
420 pImpl->maObjectToNameMap[ xObj ] = rName;
421 uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
422 if ( xChild.is() && xChild->getParent() !=
pImpl->m_xModel.get() )
423 xChild->setParent(
pImpl->m_xModel.get() );
426 if ( !
pImpl->mpTempObjectContainer )
429 auto& rObjectContainer =
pImpl->mpTempObjectContainer->pImpl->maNameToObjectMap;
430 auto aIter = std::find_if(rObjectContainer.begin(), rObjectContainer.end(),
431 [&xObj](
const EmbeddedObjectContainerNameMap::value_type& rEntry) {
return rEntry.second == xObj; });
432 if (aIter == rObjectContainer.end())
436 OUString aTempName = aIter->first;
438 uno::Reference < io::XInputStream >
xStream =
pImpl->mpTempObjectContainer->GetGraphicStream( xObj, &aMediaType );
443 pImpl->mpTempObjectContainer->RemoveGraphicStream( aTempName );
447 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
452 pImpl->mpTempObjectContainer->pImpl->mxStorage->removeElement( aTempName );
454 catch (
const uno::Exception&)
460 pImpl->mpTempObjectContainer->pImpl->maObjectToNameMap.erase( aIter->second );
461 pImpl->mpTempObjectContainer->pImpl->maNameToObjectMap.erase( aIter );
465 const uno::Reference < embed::XEmbeddedObject >& xObj, OUString& rName,
bool bCopy,
466 const OUString& rSrcShellID,
const OUString& rDestShellID )
468 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
469 if ( rName.isEmpty() )
472 #if OSL_DEBUG_LEVEL > 1
473 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
474 OSL_ENSURE( !xPersist.is() || !xAccess->hasByName(rName),
"Inserting element already present in storage!" );
475 OSL_ENSURE( xPersist.is() || xObj->getCurrentState() == embed::EmbedStates::RUNNING,
"Non persistent object inserted!");
483 uno::Sequence < beans::PropertyValue >
aSeq;
487 {
"SourceShellID",
uno::Any(rSrcShellID) },
488 {
"DestinationShellID",
uno::Any(rDestShellID) }
490 xPersist->storeToEntry(
pImpl->mxStorage, rName, aSeq, aObjArgs);
496 xPersist->storeAsEntry(
pImpl->mxStorage, rName, aSeq, aSeq );
497 xPersist->saveCompleted(
true );
501 catch (uno::Exception
const& e)
503 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::StoreEmbeddedObject: exception caught: " << e);
526 if ( rNewName.isEmpty() )
530 bool bIsStorage =
false;
539 uno::Reference < embed::XStorage > xNewStore =
pImpl->mxStorage->openStorageElement( rNewName, embed::ElementModes::READWRITE );
540 xStore->copyToStorage( xNewStore );
542 catch (
const uno::Exception&)
546 return uno::Reference < embed::XEmbeddedObject >();
551 uno::Reference < io::XStream > xNewStream =
pImpl->mxStorage->openStreamElement( rNewName, embed::ElementModes::READWRITE );
557 uno::Reference< beans::XPropertySet > xProps( xNewStream, uno::UNO_QUERY_THROW );
558 xProps->setPropertyValue(
"MediaType",
559 uno::Any( OUString(
"application/vnd.sun.star.oleobject" ) ) );
561 catch (uno::Exception
const& e)
564 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::InsertEmbeddedObject: exception caught: " << e);
565 return uno::Reference < embed::XEmbeddedObject >();
575 pImpl->mxStorage->removeElement( rNewName );
577 catch (
const uno::Exception&)
586 if ( rNewName.isEmpty() )
589 uno::Reference < embed::XEmbeddedObject > xObj;
593 uno::Sequence< beans::PropertyValue > aObjDescr(pBaseURL ? 2 : 1);
594 aObjDescr[0].Name =
"Parent";
595 aObjDescr[0].Value <<=
pImpl->m_xModel.get();
598 aObjDescr[1].Name =
"DefaultParentBaseURL";
599 aObjDescr[1].Value <<= *pBaseURL;
601 xObj.set( xFactory->createInstanceInitFromMediaDescriptor(
602 pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
603 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
605 OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
606 "A freshly create object should be running always!" );
610 xPersist->storeOwn();
614 catch (
const uno::Exception&)
623 if ( rNewName.isEmpty() )
626 uno::Reference < embed::XEmbeddedObject > xObj;
630 uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
631 aObjDescr[0].Name =
"Parent";
632 aObjDescr[0].Value <<=
pImpl->m_xModel.get();
633 xObj.set( xFactory->createInstanceLink(
pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
635 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
637 OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
638 "A freshly create object should be running always!" );
642 xPersist->storeOwn();
646 catch (uno::Exception
const& e)
648 SAL_WARN(
"comphelper.container",
"EmbeddedObjectContainer::InsertEmbeddedLink: "
649 "exception caught: " << e);
656 const OUString& aOrigName,
657 const OUString& aTargetName )
659 bool bResult =
false;
661 if ( ( &rSrc !=
this || aOrigName != aTargetName ) && !aOrigName.isEmpty() && !aTargetName.isEmpty() )
664 uno::Reference < io::XInputStream > xGrStream = rSrc.
GetGraphicStream( aOrigName, &aMediaType );
665 if ( xGrStream.is() )
674 const OUString& rSrcShellID,
const OUString& rDestShellID )
676 uno::Reference< embed::XEmbeddedObject > xResult;
683 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY_THROW );
684 aOrigName = xPersist->getEntryName();
686 catch (
const uno::Exception&)
690 if ( rName.isEmpty() )
696 SAL_INFO_IF(rDestShellID.isEmpty(),
"comphelper.container",
697 "SfxObjectShell with no base URL?");
698 xResult =
Get_Impl(rName, xObj, &rDestShellID);
705 uno::Reference< embed::XLinkageSupport > xOrigLinkage( xObj, uno::UNO_QUERY );
706 if ( xOrigLinkage.is() && xOrigLinkage->isLink() )
709 OUString
aURL = xOrigLinkage->getLinkURL();
710 if ( aURL.isEmpty() )
711 throw uno::RuntimeException();
714 uno::Reference < embed::XEmbeddedObjectCreator > xCreator =
717 uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
718 aMediaDescr[0].Name =
"URL";
719 aMediaDescr[0].Value <<= aURL;
720 uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
721 aObjDescr[0].Name =
"Parent";
722 aObjDescr[0].Value <<=
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 =
743 uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
744 aObjDescr[0].Name =
"Parent";
745 aObjDescr[0].Value <<=
pImpl->m_xModel.get();
746 xResult.set(xCreator->createInstanceInitNew(
748 xObj->getClassName(),
752 uno::UNO_QUERY_THROW );
754 if ( xResult->getCurrentState() == embed::EmbedStates::LOADED )
755 xResult->changeState( embed::EmbedStates::RUNNING );
757 uno::Reference< beans::XPropertySet > xTargetProps( xResult->getComponent(), uno::UNO_QUERY_THROW );
760 uno::Reference< beans::XPropertySetInfo > xOrigInfo = xOrigProps->getPropertySetInfo();
761 if ( !xOrigInfo.is() )
762 throw uno::RuntimeException();
764 const uno::Sequence< beans::Property > aPropertiesList = xOrigInfo->getProperties();
765 for (
const auto &
p : aPropertiesList )
769 xTargetProps->setPropertyValue(
771 xOrigProps->getPropertyValue(
p.Name ) );
773 catch (
const beans::PropertyVetoException&)
777 SAL_WARN(
"comphelper.container",
"Could not copy readonly property!" );
785 catch (
const uno::Exception&)
791 xResult->close(
true );
793 catch (
const uno::Exception&)
802 SAL_WARN_IF( !xResult.is(),
"comphelper.container",
"Can not copy embedded object that has no persistence!" );
807 if ( !aOrigName.isEmpty() )
813 if ( xResult->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD )
814 xResult->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT,
815 xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
817 catch (
const uno::Exception&)
836 auto aIt2 = rCnt.
pImpl->maNameToObjectMap.find( rName );
837 OSL_ENSURE( aIt2 == rCnt.
pImpl->maNameToObjectMap.end(),
"Object does already exist in target container!" );
839 if ( aIt2 != rCnt.
pImpl->maNameToObjectMap.end() )
842 uno::Reference < embed::XEmbeddedObject > xObj;
843 auto aIt =
pImpl->maNameToObjectMap.find( rName );
844 if ( aIt !=
pImpl->maNameToObjectMap.end() )
846 xObj = (*aIt).second;
852 OUString
aName( rName );
854 pImpl->maObjectToNameMap.erase( aIt->second );
855 pImpl->maNameToObjectMap.erase( aIt );
856 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
858 pImpl->mxStorage->removeElement( rName );
863 uno::Reference < embed::XStorage > xOld =
pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READ );
864 uno::Reference < embed::XStorage > xNew = rCnt.
pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READWRITE );
865 xOld->copyToStorage( xNew );
873 catch (
const uno::Exception&)
875 SAL_WARN(
"comphelper.container",
"Could not move object!");
881 SAL_WARN(
"comphelper.container",
"Unknown object!");
888 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
891 aName = xPersist->getEntryName();
893 #if OSL_DEBUG_LEVEL > 1
894 uno::Reference < container::XNameAccess > xAccess(
pImpl->mxStorage, uno::UNO_QUERY );
895 uno::Reference < embed::XLinkageSupport > xLink( xPersist, uno::UNO_QUERY );
896 sal_Bool bIsNotEmbedded = !xPersist.is() || ( xLink.is() && xLink->isLink() );
899 OSL_ENSURE( bIsNotEmbedded || xAccess->hasByName(aName),
"Removing element not present in storage!" );
905 if ( xPersist.is() && bKeepToTempStorage )
908 if ( !
pImpl->mpTempObjectContainer )
915 OUString aOrigStorMediaType;
916 uno::Reference< beans::XPropertySet > xStorProps(
pImpl->mxStorage, uno::UNO_QUERY_THROW );
917 static constexpr OUStringLiteral s_sMediaType(u
"MediaType");
918 xStorProps->getPropertyValue( s_sMediaType ) >>= aOrigStorMediaType;
920 SAL_WARN_IF( aOrigStorMediaType.isEmpty(),
"comphelper.container",
"No valuable media type in the storage!" );
922 uno::Reference< beans::XPropertySet > xTargetStorProps(
923 pImpl->mpTempObjectContainer->pImpl->mxStorage,
924 uno::UNO_QUERY_THROW );
925 xTargetStorProps->setPropertyValue( s_sMediaType,
uno::Any( aOrigStorMediaType ) );
927 catch (
const uno::Exception&)
929 SAL_WARN(
"comphelper.container",
"Can not set the new media type to a storage!" );
933 OUString aTempName, aMediaType;
939 if( !
pImpl->mpTempObjectContainer->HasEmbeddedObject(aName) )
942 pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName );
946 pImpl->mpTempObjectContainer->InsertGraphicStream( xStream, aTempName, aMediaType );
949 xObj->changeState( embed::EmbedStates::LOADED );
953 xObj->changeState( embed::EmbedStates::RUNNING );
955 catch (
const uno::Exception&)
960 auto aIter = std::find_if(
pImpl->maNameToObjectMap.begin(),
pImpl->maNameToObjectMap.end(),
961 [&xObj](
const EmbeddedObjectContainerNameMap::value_type& rEntry) {
return rEntry.second == xObj; });
962 if (aIter !=
pImpl->maNameToObjectMap.end())
964 pImpl->maObjectToNameMap.erase( aIter->second );
965 pImpl->maNameToObjectMap.erase( aIter );
966 uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
968 xChild->setParent( uno::Reference < uno::XInterface >() );
971 SAL_WARN(
"comphelper.container",
"Object not found for removal!" );
973 if ( xPersist.is() && 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!" );
1002 auto aIter = std::find_if(
pImpl->maNameToObjectMap.begin(),
pImpl->maNameToObjectMap.end(),
1003 [&xObj](
const EmbeddedObjectContainerNameMap::value_type& rEntry) {
return rEntry.second == xObj; });
1004 if (aIter ==
pImpl->maNameToObjectMap.end())
1007 pImpl->maObjectToNameMap.erase( aIter->second );
1008 pImpl->maNameToObjectMap.erase( aIter );
1012 xObj->close(
true );
1014 catch (
const uno::Exception&)
1023 uno::Reference < io::XInputStream > xStream;
1025 SAL_WARN_IF( aName.isEmpty(),
"comphelper.container",
"Retrieving graphic for unknown object!" );
1026 if ( !aName.isEmpty() )
1030 uno::Reference < embed::XStorage > xReplacements =
pImpl->GetReplacements();
1031 uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( aName, embed::ElementModes::READ );
1032 xStream = xGraphicStream->getInputStream();
1035 uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
1038 uno::Any aAny = xSet->getPropertyValue(
"MediaType");
1039 aAny >>= *pMediaType;
1043 catch (uno::Exception
const& e)
1046 "EmbeddedObjectContainer::GetGraphicStream(): " << e);
1063 uno::Reference < embed::XStorage > xReplacements =
pImpl->GetReplacements();
1066 uno::Reference < io::XOutputStream > xOutStream;
1067 uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( rObjectName,
1068 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
1069 xOutStream = xGraphicStream->getOutputStream();
1071 xOutStream->flush();
1073 uno::Reference< beans::XPropertySet > xPropSet( xGraphicStream, uno::UNO_QUERY_THROW );
1075 xPropSet->setPropertyValue(
"UseCommonStoragePasswordEncryption",
1077 xPropSet->setPropertyValue(
"MediaType",
uno::Any(rMediaType) );
1079 xPropSet->setPropertyValue(
"Compressed",
1082 catch (
const uno::Exception&)
1094 uno::Reference < embed::XStorage > xReplacement =
pImpl->GetReplacements();
1095 uno::Reference < embed::XOptimizedStorage > xOptRepl( xReplacement, uno::UNO_QUERY_THROW );
1098 uno::Sequence< beans::PropertyValue > aProps( 3 );
1099 aProps[0].Name =
"MediaType";
1100 aProps[0].Value <<= rMediaType;
1101 aProps[1].Name =
"UseCommonStoragePasswordEncryption";
1102 aProps[1].Value <<=
true;
1103 aProps[2].Name =
"Compressed";
1104 aProps[2].Value <<=
true;
1106 if ( xReplacement->hasByName( rObjectName ) )
1107 xReplacement->removeElement( rObjectName );
1109 xOptRepl->insertStreamElementDirect( rObjectName, rStream, aProps );
1111 catch (
const uno::Exception&)
1124 uno::Reference < embed::XStorage > xReplacements =
pImpl->GetReplacements();
1125 xReplacements->removeElement( rObjectName );
1127 catch (
const uno::Exception&)
1132 void InsertStreamIntoPicturesStorage_Impl(
const uno::Reference< embed::XStorage >& xDocStor,
1133 const uno::Reference< io::XInputStream >& xInStream,
1134 const OUString& aStreamName )
1136 OSL_ENSURE( !aStreamName.isEmpty() && xInStream.is() && xDocStor.is(),
"Misuse of the method!" );
1140 uno::Reference< embed::XStorage > xPictures = xDocStor->openStorageElement(
1142 embed::ElementModes::READWRITE );
1143 uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement(
1145 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
1146 uno::Reference< io::XOutputStream > xOutStream(
1147 xObjReplStr->getInputStream(), uno::UNO_QUERY_THROW );
1150 xOutStream->closeOutput();
1152 uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY );
1153 if ( xTransact.is() )
1154 xTransact->commit();
1156 catch (
const uno::Exception&)
1158 SAL_WARN(
"comphelper.container",
"The images storage is not available!" );
1166 bool bResult =
false;
1171 const OUString* pIter = aNames.getConstArray();
1172 const OUString* pEnd = pIter + aNames.getLength();
1173 for(;pIter != pEnd;++pIter)
1176 SAL_WARN_IF( !xObj.is(),
"comphelper.container",
"An empty entry in the embedded objects list!" );
1179 bool bSwitchBackToLoaded =
false;
1180 uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
1182 uno::Reference < io::XInputStream > xStream;
1183 OUString aMediaType;
1185 sal_Int32 nCurState = xObj->getCurrentState();
1186 if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
1197 if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
1198 bSwitchBackToLoaded =
true;
1201 embed::Aspects::MSOLE_CONTENT,
1206 if ( _bOasisFormat || (xLink.is() && xLink->isLink()) )
1210 if ( _bOasisFormat )
1213 if ( _bCreateEmbedded
1220 InsertStreamIntoPicturesStorage_Impl( _xStorage, xStream, *pIter );
1225 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
1226 if ( xPersist.is() )
1228 uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat ? 2 : 3 );
1229 aArgs[0].Name =
"StoreVisualReplacement";
1230 aArgs[0].Value <<= !_bOasisFormat;
1233 aArgs[1].Name =
"CanTryOptimization";
1234 aArgs[1].Value <<= !_bCreateEmbedded;
1235 if ( !_bOasisFormat )
1238 aArgs[2].Name =
"VisualReplacement";
1239 aArgs[2].Value <<= xStream;
1244 xPersist->storeAsEntry( _xStorage, xPersist->getEntryName(), uno::Sequence< beans::PropertyValue >(), aArgs );
1246 catch (
const embed::WrongStateException&)
1248 SAL_WARN(
"comphelper.container",
"failed to store '" << *pIter <<
"'");
1252 if ( bSwitchBackToLoaded )
1254 xObj->changeState( embed::EmbedStates::LOADED );
1261 catch (
const uno::Exception& e)
1265 SAL_WARN(
"comphelper.container",
"failed. Message: " << e);
1269 if ( !_bOasisFormat && bResult )
1274 OUString aObjReplElement(
"ObjectReplacements" );
1275 if ( _xStorage->hasByName( aObjReplElement ) && _xStorage->isStorageElement( aObjReplElement ) )
1276 _xStorage->removeElement( aObjReplElement );
1278 catch (
const uno::Exception&)
1289 bool bResult =
true;
1291 const OUString* pIter = aNames.getConstArray();
1292 const OUString* pEnd = pIter + aNames.getLength();
1293 for(;pIter != pEnd;++pIter)
1298 SAL_WARN_IF( !xObj.is(),
"comphelper.container",
"An empty entry in the embedded objects list!" );
1301 sal_Int32 nCurState = xObj->getCurrentState();
1302 if ( _bOasisFormat && nCurState != embed::EmbedStates::LOADED && nCurState != embed::EmbedStates::RUNNING )
1306 OUString aMediaType;
1309 uno::Reference < io::XInputStream > xStream =
1311 embed::Aspects::MSOLE_CONTENT,
1329 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
1330 if ( xPersist.is() )
1340 if (_bObjectsOnly && (nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING)
1341 && (
pImpl->mxStorage->isStorageElement( *pIter ) ))
1343 uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
1344 if ( xModifiable.is() && xModifiable->isModified())
1346 xPersist->storeOwn();
1355 xPersist->storeOwn();
1359 catch (
const uno::Exception&)
1367 if ( !_bOasisFormat && !_bObjectsOnly )
1372 uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
1373 if ( xLink.is() && xLink->isLink() )
1375 OUString aMediaType;
1376 uno::Reference < io::XInputStream > xInStream =
GetGraphicStream( xObj, &aMediaType );
1377 if ( xInStream.is() )
1378 InsertStreamIntoPicturesStorage_Impl(
pImpl->mxStorage, xInStream, *pIter );
1381 catch (
const uno::Exception&)
1387 catch (
const uno::Exception&)
1393 if ( bResult && _bOasisFormat )
1396 if ( bResult && !_bObjectsOnly )
1401 OUString aObjReplElement(
"ObjectReplacements" );
1402 if ( !_bOasisFormat &&
pImpl->mxStorage->hasByName( aObjReplElement ) &&
pImpl->mxStorage->isStorageElement( aObjReplElement ) )
1403 pImpl->mxStorage->removeElement( aObjReplElement );
1405 catch (
const uno::Exception&)
1415 sal_Int64 nViewAspect,
1416 const uno::Reference< embed::XEmbeddedObject >& xObj,
1417 OUString* pMediaType )
1419 uno::Reference< io::XInputStream > xInStream;
1425 embed::VisualRepresentation aRep = xObj->getPreferredVisualRepresentation( nViewAspect );
1427 *pMediaType = aRep.Flavor.MimeType;
1429 uno::Sequence < sal_Int8 >
aSeq;
1431 xInStream = new ::comphelper::SequenceInputStream( aSeq );
1433 catch (
const uno::Exception&)
1443 bool bError =
false;
1445 const OUString* pIter = aNames.getConstArray();
1446 const OUString* pEnd = pIter + aNames.getLength();
1447 for(;pIter != pEnd;++pIter)
1450 SAL_WARN_IF( !xObj.is(),
"comphelper.container",
"An empty entry in the embedded objects list!" );
1453 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
1454 if ( xPersist.is() )
1458 xPersist->setPersistentEntry( _xStorage,
1460 embed::EntryInitModes::NO_INIT,
1461 uno::Sequence< beans::PropertyValue >(),
1462 uno::Sequence< beans::PropertyValue >() );
1465 catch (
const uno::Exception&)
1472 if ( _bClearModifiedFlag )
1477 uno::Reference< util::XModifiable > xModif( xObj->getComponent(), uno::UNO_QUERY_THROW );
1478 if ( xModif->isModified() )
1479 xModif->setModified(
false );
1481 catch (
const uno::Exception&)
1492 return pImpl->mbUserAllowsLinkUpdate;
1497 if(
pImpl->mbUserAllowsLinkUpdate != bNew)
1499 pImpl->mbUserAllowsLinkUpdate = bNew;
css::uno::Reference< css::embed::XEmbeddedObject > CreateEmbeddedObject(const css::uno::Sequence< sal_Int8 > &, OUString &, OUString const *pBaseURL=nullptr)
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 >())
EmbeddedObjectContainerNameMap maNameToObjectMap
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
bool HasEmbeddedObjects() const
#define SAL_INFO_IF(condition, area, stream)
bool StoreAsChildren(bool _bOasisFormat, bool _bCreateEmbedded, const css::uno::Reference< css::embed::XStorage > &_xStorage)
void CloseEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &)
void AddEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &, const OUString &)
EmbeddedObjectContainer * mpTempObjectContainer
bool HasEmbeddedObject(const OUString &)
css::uno::Reference< css::embed::XEmbeddedObject > InsertEmbeddedLink(const css::uno::Sequence< css::beans::PropertyValue > &, OUString &)
css::uno::Reference< css::embed::XEmbeddedObject > Get_Impl(const OUString &, const css::uno::Reference< css::embed::XEmbeddedObject > &xCopy, OUString const *pBaseURL)
EmbeddedObjectContainer()
void ReleaseImageSubStorage()
css::uno::Reference< css::io::XInputStream > GetGraphicStream(const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString *pMediaType=nullptr)
void SwitchPersistence(const css::uno::Reference< css::embed::XStorage > &)
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
Init list for property sequences.
OUString CreateUniqueObjectName()
std::unordered_map< uno::Reference< embed::XEmbeddedObject >, OUString > maObjectToNameMap
static css::uno::Reference< css::embed::XStorage > GetTemporaryStorage(const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
bool CommitImageSubStorage()
bool getUserAllowsLinkUpdate() const
bool SetPersistentEntries(const css::uno::Reference< css::embed::XStorage > &_xStorage, bool _bClearModifiedFlag=true)
call setPersistentEntry for each embedded object in the container
bool InsertGraphicStream(const css::uno::Reference< css::io::XInputStream > &rStream, const OUString &rObjectName, const OUString &rMediaType)
uno::Reference< embed::XStorage > mxStorage
std::unique_ptr< EmbedImpl > pImpl
bool StoreChildren(bool _bOasisFormat, bool _bObjectsOnly)
bool HasInstantiatedEmbeddedObject(const OUString &)
void CloseEmbeddedObjects()
uno::WeakReference< uno::XInterface > m_xModel
uno::Reference< embed::XStorage > mxImageStorage
OUString GetEmbeddedObjectName(const css::uno::Reference< css::embed::XEmbeddedObject > &) const
css::uno::Reference< css::embed::XEmbeddedObject > GetEmbeddedObject(const OUString &, OUString const *pBaseURL=nullptr)
void RemoveEmbeddedObject(const OUString &rName, bool bKeepToTempStorage=true)
void setUserAllowsLinkUpdate(bool bNew)
bool mbUserAllowsLinkUpdate
#define SAL_WARN_IF(condition, area, stream)
const uno::Reference< embed::XStorage > & GetReplacements()
bool InsertGraphicStreamDirectly(const css::uno::Reference< css::io::XInputStream > &rStream, const OUString &rObjectName, const OUString &rMediaType)
#define SAL_INFO(area, stream)
~EmbeddedObjectContainer()
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.
Sequence< sal_Int8 > aSeq
bool InsertEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString &)
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)
bool StoreEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &xObj, OUString &rName, bool bCopy, const OUString &rSrcShellID, const OUString &rDestShellID)
#define SAL_WARN(area, stream)
Reference< XSingleServiceFactory > xFactory
static css::uno::Reference< css::io::XInputStream > GetGraphicReplacementStream(sal_Int64 nViewAspect, const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString *pMediaType)
std::unordered_map< OUString, uno::Reference< embed::XEmbeddedObject > > EmbeddedObjectContainerNameMap
void RemoveGraphicStream(const OUString &rObjectName)
bool TryToCopyGraphReplacement(EmbeddedObjectContainer &rSrc, const OUString &aOrigName, const OUString &aTargetName)
bool MoveEmbeddedObject(const OUString &rName, EmbeddedObjectContainer &)
css::uno::Sequence< OUString > GetObjectNames() const
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
Copy (keys or values) from an associate container into a Sequence.