1dde7d3faSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file 5dde7d3faSAndrew Rist * distributed with this work for additional information 6dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the 8dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance 9dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing, 14dde7d3faSAndrew Rist * software distributed under the License is distributed on an 15dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the 17dde7d3faSAndrew Rist * specific language governing permissions and limitations 18dde7d3faSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20dde7d3faSAndrew Rist *************************************************************/ 21dde7d3faSAndrew Rist 22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 23cdf0e10cSrcweir #include "precompiled_comphelper.hxx" 24cdf0e10cSrcweir #include <com/sun/star/container/XChild.hpp> 25cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp> 26*716c984aSArrigo Marchiori #include <com/sun/star/document/XLinkAuthorizer.hpp> 27cdf0e10cSrcweir #include <com/sun/star/embed/XEmbedObjectCreator.hpp> 28cdf0e10cSrcweir #include <com/sun/star/embed/XLinkCreator.hpp> 29cdf0e10cSrcweir #include <com/sun/star/embed/XEmbedPersist.hpp> 30cdf0e10cSrcweir #include <com/sun/star/embed/XLinkageSupport.hpp> 31cdf0e10cSrcweir #include <com/sun/star/embed/XTransactedObject.hpp> 32cdf0e10cSrcweir #include <com/sun/star/embed/XOptimizedStorage.hpp> 33cdf0e10cSrcweir #include <com/sun/star/embed/EntryInitModes.hpp> 34cdf0e10cSrcweir #include <com/sun/star/util/XCloseable.hpp> 35cdf0e10cSrcweir #include <com/sun/star/util/XModifiable.hpp> 36cdf0e10cSrcweir #include <com/sun/star/embed/EmbedStates.hpp> 37cdf0e10cSrcweir #include <com/sun/star/datatransfer/XTransferable.hpp> 38cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySetInfo.hpp> 39cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 40cdf0e10cSrcweir #include <com/sun/star/embed/Aspects.hpp> 41cdf0e10cSrcweir #include <com/sun/star/embed/EmbedMisc.hpp> 42cdf0e10cSrcweir 43cdf0e10cSrcweir #include <comphelper/seqstream.hxx> 44cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 45cdf0e10cSrcweir #include <comphelper/storagehelper.hxx> 46cdf0e10cSrcweir #include <comphelper/embeddedobjectcontainer.hxx> 47cdf0e10cSrcweir #include <comphelper/sequence.hxx> 48cdf0e10cSrcweir #include <cppuhelper/weakref.hxx> 49cdf0e10cSrcweir #include <hash_map> 50cdf0e10cSrcweir #include <algorithm> 51cdf0e10cSrcweir 52cdf0e10cSrcweir #include <rtl/logfile.hxx> 53cdf0e10cSrcweir 54cdf0e10cSrcweir using namespace ::com::sun::star; 55cdf0e10cSrcweir 56cdf0e10cSrcweir namespace comphelper 57cdf0e10cSrcweir { 58cdf0e10cSrcweir 59cdf0e10cSrcweir struct hashObjectName_Impl 60cdf0e10cSrcweir { 61cdf0e10cSrcweir size_t operator()(const ::rtl::OUString Str) const 62cdf0e10cSrcweir { 63cdf0e10cSrcweir return (size_t)Str.hashCode(); 64cdf0e10cSrcweir } 65cdf0e10cSrcweir }; 66cdf0e10cSrcweir 67cdf0e10cSrcweir struct eqObjectName_Impl 68cdf0e10cSrcweir { 69cdf0e10cSrcweir sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const 70cdf0e10cSrcweir { 71cdf0e10cSrcweir return ( Str1 == Str2 ); 72cdf0e10cSrcweir } 73cdf0e10cSrcweir }; 74cdf0e10cSrcweir 75cdf0e10cSrcweir typedef std::hash_map 76cdf0e10cSrcweir < 77cdf0e10cSrcweir ::rtl::OUString, 78cdf0e10cSrcweir ::com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >, 79cdf0e10cSrcweir hashObjectName_Impl, 80cdf0e10cSrcweir eqObjectName_Impl 81cdf0e10cSrcweir > 82cdf0e10cSrcweir EmbeddedObjectContainerNameMap; 83cdf0e10cSrcweir 84cdf0e10cSrcweir struct EmbedImpl 85cdf0e10cSrcweir { 86cdf0e10cSrcweir // TODO/LATER: remove objects from temp. Container storage when object is disposed 87cdf0e10cSrcweir EmbeddedObjectContainerNameMap maObjectContainer; 88cdf0e10cSrcweir uno::Reference < embed::XStorage > mxStorage; 89cdf0e10cSrcweir EmbeddedObjectContainer* mpTempObjectContainer; 90cdf0e10cSrcweir uno::Reference < embed::XStorage > mxImageStorage; 91cdf0e10cSrcweir uno::WeakReference < uno::XInterface > m_xModel; 92cdf0e10cSrcweir //EmbeddedObjectContainerNameMap maTempObjectContainer; 93cdf0e10cSrcweir //uno::Reference < embed::XStorage > mxTempStorage; 94963c6022SArmin Le Grand 95963c6022SArmin Le Grand /// bitfield 96963c6022SArmin Le Grand bool mbOwnsStorage : 1; 97963c6022SArmin Le Grand bool mbUserAllowsLinkUpdate : 1; 98cdf0e10cSrcweir 99cdf0e10cSrcweir const uno::Reference < embed::XStorage >& GetReplacements(); 100cdf0e10cSrcweir }; 101cdf0e10cSrcweir 102cdf0e10cSrcweir const uno::Reference < embed::XStorage >& EmbedImpl::GetReplacements() 103cdf0e10cSrcweir { 104cdf0e10cSrcweir if ( !mxImageStorage.is() ) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir try 107cdf0e10cSrcweir { 108cdf0e10cSrcweir mxImageStorage = mxStorage->openStorageElement( 109cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "ObjectReplacements" ), embed::ElementModes::READWRITE ); 110cdf0e10cSrcweir } 111cdf0e10cSrcweir catch ( uno::Exception& ) 112cdf0e10cSrcweir { 113cdf0e10cSrcweir mxImageStorage = mxStorage->openStorageElement( 114cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "ObjectReplacements" ), embed::ElementModes::READ ); 115cdf0e10cSrcweir } 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir if ( !mxImageStorage.is() ) 119cdf0e10cSrcweir throw io::IOException(); 120cdf0e10cSrcweir 121cdf0e10cSrcweir return mxImageStorage; 122cdf0e10cSrcweir } 123cdf0e10cSrcweir 124cdf0e10cSrcweir EmbeddedObjectContainer::EmbeddedObjectContainer() 125cdf0e10cSrcweir { 126cdf0e10cSrcweir pImpl = new EmbedImpl; 127cdf0e10cSrcweir pImpl->mxStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 128963c6022SArmin Le Grand pImpl->mbOwnsStorage = true; 129ae6fcd72SPatricia Shanahan pImpl->mbUserAllowsLinkUpdate = true; 130cdf0e10cSrcweir pImpl->mpTempObjectContainer = 0; 131cdf0e10cSrcweir } 132cdf0e10cSrcweir 133cdf0e10cSrcweir EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir pImpl = new EmbedImpl; 136cdf0e10cSrcweir pImpl->mxStorage = rStor; 137963c6022SArmin Le Grand pImpl->mbOwnsStorage = false; 138ae6fcd72SPatricia Shanahan pImpl->mbUserAllowsLinkUpdate = true; 139cdf0e10cSrcweir pImpl->mpTempObjectContainer = 0; 140cdf0e10cSrcweir } 141cdf0e10cSrcweir 142cdf0e10cSrcweir EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor, const uno::Reference < uno::XInterface >& xModel ) 143cdf0e10cSrcweir { 144cdf0e10cSrcweir pImpl = new EmbedImpl; 145cdf0e10cSrcweir pImpl->mxStorage = rStor; 146963c6022SArmin Le Grand pImpl->mbOwnsStorage = false; 147ae6fcd72SPatricia Shanahan pImpl->mbUserAllowsLinkUpdate = true; 148cdf0e10cSrcweir pImpl->mpTempObjectContainer = 0; 149cdf0e10cSrcweir pImpl->m_xModel = xModel; 150cdf0e10cSrcweir } 151cdf0e10cSrcweir 152cdf0e10cSrcweir void EmbeddedObjectContainer::SwitchPersistence( const uno::Reference < embed::XStorage >& rStor ) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir ReleaseImageSubStorage(); 155cdf0e10cSrcweir 156963c6022SArmin Le Grand if ( pImpl->mbOwnsStorage ) 157cdf0e10cSrcweir pImpl->mxStorage->dispose(); 158cdf0e10cSrcweir 159cdf0e10cSrcweir pImpl->mxStorage = rStor; 160963c6022SArmin Le Grand pImpl->mbOwnsStorage = false; 161cdf0e10cSrcweir } 162cdf0e10cSrcweir 163cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::CommitImageSubStorage() 164cdf0e10cSrcweir { 165cdf0e10cSrcweir if ( pImpl->mxImageStorage.is() ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir try 168cdf0e10cSrcweir { 169cdf0e10cSrcweir sal_Bool bReadOnlyMode = sal_True; 170cdf0e10cSrcweir uno::Reference < beans::XPropertySet > xSet(pImpl->mxImageStorage,uno::UNO_QUERY); 171cdf0e10cSrcweir if ( xSet.is() ) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir // get the open mode from the parent storage 174cdf0e10cSrcweir sal_Int32 nMode = 0; 175cdf0e10cSrcweir uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("OpenMode") ); 176cdf0e10cSrcweir if ( aAny >>= nMode ) 177cdf0e10cSrcweir bReadOnlyMode = !(nMode & embed::ElementModes::WRITE ); 178cdf0e10cSrcweir } // if ( xSet.is() ) 179cdf0e10cSrcweir if ( !bReadOnlyMode ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir uno::Reference< embed::XTransactedObject > xTransact( pImpl->mxImageStorage, uno::UNO_QUERY_THROW ); 182cdf0e10cSrcweir xTransact->commit(); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir } 185cdf0e10cSrcweir catch( uno::Exception& ) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir return sal_False; 188cdf0e10cSrcweir } 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir return sal_True; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir 194cdf0e10cSrcweir void EmbeddedObjectContainer::ReleaseImageSubStorage() 195cdf0e10cSrcweir { 196cdf0e10cSrcweir CommitImageSubStorage(); 197cdf0e10cSrcweir 198cdf0e10cSrcweir if ( pImpl->mxImageStorage.is() ) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir try 201cdf0e10cSrcweir { 202cdf0e10cSrcweir pImpl->mxImageStorage->dispose(); 203cdf0e10cSrcweir pImpl->mxImageStorage = uno::Reference< embed::XStorage >(); 204cdf0e10cSrcweir } 205cdf0e10cSrcweir catch( uno::Exception& ) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir OSL_ASSERT( "Problems releasing image substorage!\n" ); 208cdf0e10cSrcweir } 209cdf0e10cSrcweir } 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir EmbeddedObjectContainer::~EmbeddedObjectContainer() 213cdf0e10cSrcweir { 214cdf0e10cSrcweir ReleaseImageSubStorage(); 215cdf0e10cSrcweir 216963c6022SArmin Le Grand if ( pImpl->mbOwnsStorage ) 217cdf0e10cSrcweir pImpl->mxStorage->dispose(); 218cdf0e10cSrcweir 219cdf0e10cSrcweir delete pImpl->mpTempObjectContainer; 220cdf0e10cSrcweir delete pImpl; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir 223cdf0e10cSrcweir void EmbeddedObjectContainer::CloseEmbeddedObjects() 224cdf0e10cSrcweir { 225cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 226cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir uno::Reference < util::XCloseable > xClose( (*aIt).second, uno::UNO_QUERY ); 229cdf0e10cSrcweir if ( xClose.is() ) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir try 232cdf0e10cSrcweir { 233cdf0e10cSrcweir xClose->close( sal_True ); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir catch ( uno::Exception& ) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir } 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir aIt++; 241cdf0e10cSrcweir } 242cdf0e10cSrcweir } 243cdf0e10cSrcweir 244cdf0e10cSrcweir ::rtl::OUString EmbeddedObjectContainer::CreateUniqueObjectName() 245cdf0e10cSrcweir { 246cdf0e10cSrcweir ::rtl::OUString aPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") ); 247cdf0e10cSrcweir ::rtl::OUString aStr; 248cdf0e10cSrcweir sal_Int32 i=1; 249cdf0e10cSrcweir do 250cdf0e10cSrcweir { 251cdf0e10cSrcweir aStr = aPersistName; 252cdf0e10cSrcweir aStr += ::rtl::OUString::valueOf( i++ ); 253cdf0e10cSrcweir } 254cdf0e10cSrcweir while( HasEmbeddedObject( aStr ) ); 255cdf0e10cSrcweir // TODO/LATER: should we consider deleted objects? 256cdf0e10cSrcweir 257cdf0e10cSrcweir return aStr; 258cdf0e10cSrcweir } 259cdf0e10cSrcweir 260cdf0e10cSrcweir uno::Sequence < ::rtl::OUString > EmbeddedObjectContainer::GetObjectNames() 261cdf0e10cSrcweir { 262cdf0e10cSrcweir uno::Sequence < ::rtl::OUString > aSeq( pImpl->maObjectContainer.size() ); 263cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 264cdf0e10cSrcweir sal_Int32 nIdx=0; 265cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 266cdf0e10cSrcweir aSeq[nIdx++] = (*aIt++).first; 267cdf0e10cSrcweir return aSeq; 268cdf0e10cSrcweir } 269cdf0e10cSrcweir 270cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::HasEmbeddedObjects() 271cdf0e10cSrcweir { 272cdf0e10cSrcweir return pImpl->maObjectContainer.size() != 0; 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const ::rtl::OUString& rName ) 276cdf0e10cSrcweir { 277cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); 278cdf0e10cSrcweir if ( aIt == pImpl->maObjectContainer.end() ) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); 281cdf0e10cSrcweir return xAccess->hasByName(rName); 282cdf0e10cSrcweir } 283cdf0e10cSrcweir else 284cdf0e10cSrcweir return sal_True; 285cdf0e10cSrcweir } 286cdf0e10cSrcweir 287cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj ) 288cdf0e10cSrcweir { 289cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 290cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 291cdf0e10cSrcweir { 292cdf0e10cSrcweir if ( (*aIt).second == xObj ) 293cdf0e10cSrcweir return sal_True; 294cdf0e10cSrcweir else 295cdf0e10cSrcweir aIt++; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir return sal_False; 299cdf0e10cSrcweir } 300cdf0e10cSrcweir 301cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::HasInstantiatedEmbeddedObject( const ::rtl::OUString& rName ) 302cdf0e10cSrcweir { 303cdf0e10cSrcweir // allows to detect whether the object was already instantiated 304cdf0e10cSrcweir // currently the filter instantiate it on loading, so this method allows 305cdf0e10cSrcweir // to avoid objects pointing to the same persistence 306cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); 307cdf0e10cSrcweir return ( aIt != pImpl->maObjectContainer.end() ); 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir ::rtl::OUString EmbeddedObjectContainer::GetEmbeddedObjectName( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj ) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 313cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir if ( (*aIt).second == xObj ) 316cdf0e10cSrcweir return (*aIt).first; 317cdf0e10cSrcweir else 318cdf0e10cSrcweir aIt++; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir OSL_ENSURE( 0, "Unknown object!" ); 322cdf0e10cSrcweir return ::rtl::OUString(); 323cdf0e10cSrcweir } 324cdf0e10cSrcweir 325cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::GetEmbeddedObject( const ::rtl::OUString& rName ) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetEmbeddedObject" ); 328cdf0e10cSrcweir 32949b34792SHerbert Dürr OSL_ENSURE( !rName.isEmpty(), "Empty object name!"); 330cdf0e10cSrcweir 331cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj; 332cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); 333cdf0e10cSrcweir 334cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 335cdf0e10cSrcweir uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); 336cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> aSeq = xAccess->getElementNames(); 337cdf0e10cSrcweir const ::rtl::OUString* pIter = aSeq.getConstArray(); 338cdf0e10cSrcweir const ::rtl::OUString* pEnd = pIter + aSeq.getLength(); 339cdf0e10cSrcweir for(;pIter != pEnd;++pIter) 340cdf0e10cSrcweir { 341cdf0e10cSrcweir (void)*pIter; 342cdf0e10cSrcweir } 343cdf0e10cSrcweir OSL_ENSURE( aIt != pImpl->maObjectContainer.end() || xAccess->hasByName(rName), "Could not return object!" ); 344cdf0e10cSrcweir #endif 345cdf0e10cSrcweir 346cdf0e10cSrcweir // check if object was already created 347cdf0e10cSrcweir if ( aIt != pImpl->maObjectContainer.end() ) 348cdf0e10cSrcweir xObj = (*aIt).second; 349cdf0e10cSrcweir else 350cdf0e10cSrcweir xObj = Get_Impl( rName, uno::Reference < embed::XEmbeddedObject >() ); 351cdf0e10cSrcweir 352cdf0e10cSrcweir return xObj; 353cdf0e10cSrcweir } 354cdf0e10cSrcweir 355cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::Get_Impl( const ::rtl::OUString& rName, const uno::Reference < embed::XEmbeddedObject >& xCopy ) 356cdf0e10cSrcweir { 357cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj; 358cdf0e10cSrcweir try 359cdf0e10cSrcweir { 360cdf0e10cSrcweir // create the object from the storage 361cdf0e10cSrcweir uno::Reference < beans::XPropertySet > xSet( pImpl->mxStorage, uno::UNO_QUERY ); 362cdf0e10cSrcweir sal_Bool bReadOnlyMode = sal_True; 363cdf0e10cSrcweir if ( xSet.is() ) 364cdf0e10cSrcweir { 365cdf0e10cSrcweir // get the open mode from the parent storage 366cdf0e10cSrcweir sal_Int32 nMode = 0; 367cdf0e10cSrcweir uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("OpenMode") ); 368cdf0e10cSrcweir if ( aAny >>= nMode ) 369cdf0e10cSrcweir bReadOnlyMode = !(nMode & embed::ElementModes::WRITE ); 370cdf0e10cSrcweir } 371cdf0e10cSrcweir 372cdf0e10cSrcweir // object was not added until now - should happen only by calling this method from "inside" 373cdf0e10cSrcweir //TODO/LATER: it would be good to detect an error when an object should be created already, but isn't (not an "inside" call) 374cdf0e10cSrcweir uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( 375cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); 376cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aObjDescr( xCopy.is() ? 2 : 1 ); 377cdf0e10cSrcweir aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); 378cdf0e10cSrcweir aObjDescr[0].Value <<= pImpl->m_xModel.get(); 379cdf0e10cSrcweir if ( xCopy.is() ) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir aObjDescr[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CloneFrom" ) ); 382cdf0e10cSrcweir aObjDescr[1].Value <<= xCopy; 383cdf0e10cSrcweir } 384cdf0e10cSrcweir 385cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aMediaDescr( 1 ); 386cdf0e10cSrcweir aMediaDescr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")); 387cdf0e10cSrcweir aMediaDescr[0].Value <<= bReadOnlyMode; 388cdf0e10cSrcweir xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromEntry( 389cdf0e10cSrcweir pImpl->mxStorage, rName, 390cdf0e10cSrcweir aMediaDescr, aObjDescr ), uno::UNO_QUERY ); 391cdf0e10cSrcweir 392cdf0e10cSrcweir // insert object into my list 393cdf0e10cSrcweir AddEmbeddedObject( xObj, rName ); 394cdf0e10cSrcweir } 395cdf0e10cSrcweir catch ( uno::Exception& ) 396cdf0e10cSrcweir { 397cdf0e10cSrcweir } 398cdf0e10cSrcweir 399cdf0e10cSrcweir return xObj; 400cdf0e10cSrcweir } 401cdf0e10cSrcweir 402cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId, 403cdf0e10cSrcweir const uno::Sequence < beans::PropertyValue >& rArgs, ::rtl::OUString& rNewName ) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CreateEmbeddedObject" ); 406cdf0e10cSrcweir 40749b34792SHerbert Dürr if ( rNewName.isEmpty() ) 408cdf0e10cSrcweir rNewName = CreateUniqueObjectName(); 409cdf0e10cSrcweir 410cdf0e10cSrcweir OSL_ENSURE( !HasEmbeddedObject(rNewName), "Object to create already exists!"); 411cdf0e10cSrcweir 412cdf0e10cSrcweir // create object from classid by inserting it into storage 413cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj; 414cdf0e10cSrcweir try 415cdf0e10cSrcweir { 416cdf0e10cSrcweir uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( 417cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); 418cdf0e10cSrcweir 419cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aObjDescr( rArgs.getLength() + 1 ); 420cdf0e10cSrcweir aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); 421cdf0e10cSrcweir aObjDescr[0].Value <<= pImpl->m_xModel.get(); 422cdf0e10cSrcweir ::std::copy( rArgs.getConstArray(), rArgs.getConstArray() + rArgs.getLength(), aObjDescr.getArray() + 1 ); 423cdf0e10cSrcweir xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew( 424cdf0e10cSrcweir rClassId, ::rtl::OUString(), pImpl->mxStorage, rNewName, 425cdf0e10cSrcweir aObjDescr ), uno::UNO_QUERY ); 426cdf0e10cSrcweir 427cdf0e10cSrcweir AddEmbeddedObject( xObj, rNewName ); 428cdf0e10cSrcweir 429cdf0e10cSrcweir OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED, 430cdf0e10cSrcweir "A freshly create object should be running always!\n" ); 431cdf0e10cSrcweir } 432cdf0e10cSrcweir catch ( uno::Exception& ) 433cdf0e10cSrcweir { 434cdf0e10cSrcweir } 435cdf0e10cSrcweir 436cdf0e10cSrcweir return xObj; 437cdf0e10cSrcweir } 438cdf0e10cSrcweir 439cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId, ::rtl::OUString& rNewName ) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir return CreateEmbeddedObject( rClassId, uno::Sequence < beans::PropertyValue >(), rNewName ); 442cdf0e10cSrcweir } 443cdf0e10cSrcweir 444cdf0e10cSrcweir void EmbeddedObjectContainer::AddEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, const ::rtl::OUString& rName ) 445cdf0e10cSrcweir { 446cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::AddEmbeddedObject" ); 447cdf0e10cSrcweir 448cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 44949b34792SHerbert Dürr OSL_ENSURE( !rName.isEmpty(), "Added object doesn't have a name!"); 450cdf0e10cSrcweir uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); 451cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xEmb( xObj, uno::UNO_QUERY ); 452cdf0e10cSrcweir uno::Reference < embed::XLinkageSupport > xLink( xEmb, uno::UNO_QUERY ); 45307a3d7f1SPedro Giffuni // if the object has a persistence and the object is not a link than it must have persistence entry in the storage 454cdf0e10cSrcweir OSL_ENSURE( !( xEmb.is() && ( !xLink.is() || !xLink->isLink() ) ) || xAccess->hasByName(rName), 455cdf0e10cSrcweir "Added element not in storage!" ); 456cdf0e10cSrcweir #endif 457cdf0e10cSrcweir 458cdf0e10cSrcweir // remember object - it needs to be in storage already 459cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); 460cdf0e10cSrcweir OSL_ENSURE( aIt == pImpl->maObjectContainer.end(), "Element already inserted!" ); 461cdf0e10cSrcweir pImpl->maObjectContainer[ rName ] = xObj; 462cdf0e10cSrcweir uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY ); 463cdf0e10cSrcweir if ( xChild.is() && xChild->getParent() != pImpl->m_xModel.get() ) 464cdf0e10cSrcweir xChild->setParent( pImpl->m_xModel.get() ); 465cdf0e10cSrcweir 466cdf0e10cSrcweir // look for object in temorary container 467cdf0e10cSrcweir if ( pImpl->mpTempObjectContainer ) 468cdf0e10cSrcweir { 469cdf0e10cSrcweir aIt = pImpl->mpTempObjectContainer->pImpl->maObjectContainer.begin(); 470cdf0e10cSrcweir while ( aIt != pImpl->mpTempObjectContainer->pImpl->maObjectContainer.end() ) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir if ( (*aIt).second == xObj ) 473cdf0e10cSrcweir { 474cdf0e10cSrcweir // copy replacement image from temporary container (if there is any) 475cdf0e10cSrcweir ::rtl::OUString aTempName = (*aIt).first; 476cdf0e10cSrcweir ::rtl::OUString aMediaType; 477cdf0e10cSrcweir uno::Reference < io::XInputStream > xStream = pImpl->mpTempObjectContainer->GetGraphicStream( xObj, &aMediaType ); 478cdf0e10cSrcweir if ( xStream.is() ) 479cdf0e10cSrcweir { 480cdf0e10cSrcweir InsertGraphicStream( xStream, rName, aMediaType ); 481cdf0e10cSrcweir xStream = 0; 482cdf0e10cSrcweir pImpl->mpTempObjectContainer->RemoveGraphicStream( aTempName ); 483cdf0e10cSrcweir } 484cdf0e10cSrcweir 485cdf0e10cSrcweir // remove object from storage of temporary container 486cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 487cdf0e10cSrcweir if ( xPersist.is() ) 488cdf0e10cSrcweir { 489cdf0e10cSrcweir try 490cdf0e10cSrcweir { 491cdf0e10cSrcweir pImpl->mpTempObjectContainer->pImpl->mxStorage->removeElement( aTempName ); 492cdf0e10cSrcweir } 493cdf0e10cSrcweir catch ( uno::Exception& ) 494cdf0e10cSrcweir { 495cdf0e10cSrcweir } 496cdf0e10cSrcweir } 497cdf0e10cSrcweir 498cdf0e10cSrcweir // temp. container needs to forget the object 499cdf0e10cSrcweir pImpl->mpTempObjectContainer->pImpl->maObjectContainer.erase( aIt ); 500cdf0e10cSrcweir break; 501cdf0e10cSrcweir } 502cdf0e10cSrcweir else 503cdf0e10cSrcweir aIt++; 504cdf0e10cSrcweir } 505cdf0e10cSrcweir } 506cdf0e10cSrcweir } 507cdf0e10cSrcweir 508cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::StoreEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName, sal_Bool bCopy ) 509cdf0e10cSrcweir { 510cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::StoreEmbeddedObject" ); 511cdf0e10cSrcweir 512cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 51349b34792SHerbert Dürr if ( rName.isEmpty() ) 514cdf0e10cSrcweir rName = CreateUniqueObjectName(); 515cdf0e10cSrcweir 516cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 517cdf0e10cSrcweir uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); 518cdf0e10cSrcweir OSL_ENSURE( !xPersist.is() || !xAccess->hasByName(rName), "Inserting element already present in storage!" ); 519cdf0e10cSrcweir OSL_ENSURE( xPersist.is() || xObj->getCurrentState() == embed::EmbedStates::RUNNING, "Non persistent object inserted!"); 520cdf0e10cSrcweir #endif 521cdf0e10cSrcweir 522cdf0e10cSrcweir // insert objects' storage into the container storage (if object has one) 523cdf0e10cSrcweir try 524cdf0e10cSrcweir { 525cdf0e10cSrcweir if ( xPersist.is() ) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir uno::Sequence < beans::PropertyValue > aSeq; 528cdf0e10cSrcweir if ( bCopy ) 529cdf0e10cSrcweir xPersist->storeToEntry( pImpl->mxStorage, rName, aSeq, aSeq ); 530cdf0e10cSrcweir else 531cdf0e10cSrcweir { 5322cdca4f8Smseidel // TODO/LATER: possible optimization, don't store immediately 533cdf0e10cSrcweir //xPersist->setPersistentEntry( pImpl->mxStorage, rName, embed::EntryInitModes::ENTRY_NO_INIT, aSeq, aSeq ); 534cdf0e10cSrcweir xPersist->storeAsEntry( pImpl->mxStorage, rName, aSeq, aSeq ); 535cdf0e10cSrcweir xPersist->saveCompleted( sal_True ); 536cdf0e10cSrcweir } 537cdf0e10cSrcweir } 538cdf0e10cSrcweir } 539cdf0e10cSrcweir catch ( uno::Exception& ) 540cdf0e10cSrcweir { 541cdf0e10cSrcweir // TODO/LATER: better error recovery should keep storage intact 542cdf0e10cSrcweir return sal_False; 543cdf0e10cSrcweir } 544cdf0e10cSrcweir 545cdf0e10cSrcweir return sal_True; 546cdf0e10cSrcweir } 547cdf0e10cSrcweir 548cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) 549cdf0e10cSrcweir { 550cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( Object )" ); 551cdf0e10cSrcweir // store it into the container storage 552cdf0e10cSrcweir if ( StoreEmbeddedObject( xObj, rName, sal_False ) ) 553cdf0e10cSrcweir { 554cdf0e10cSrcweir // remember object 555cdf0e10cSrcweir AddEmbeddedObject( xObj, rName ); 556cdf0e10cSrcweir return sal_True; 557cdf0e10cSrcweir } 558cdf0e10cSrcweir else 559cdf0e10cSrcweir return sal_False; 560cdf0e10cSrcweir } 561cdf0e10cSrcweir 562cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < io::XInputStream >& xStm, ::rtl::OUString& rNewName ) 563cdf0e10cSrcweir { 564cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( InputStream )" ); 565cdf0e10cSrcweir 56649b34792SHerbert Dürr if ( rNewName.isEmpty() ) 567cdf0e10cSrcweir rNewName = CreateUniqueObjectName(); 568cdf0e10cSrcweir 569cdf0e10cSrcweir // store it into the container storage 570cdf0e10cSrcweir sal_Bool bIsStorage = sal_False; 571cdf0e10cSrcweir try 572cdf0e10cSrcweir { 573cdf0e10cSrcweir // first try storage persistence 574cdf0e10cSrcweir uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm ); 575cdf0e10cSrcweir 576cdf0e10cSrcweir // storage was created from stream successfully 577cdf0e10cSrcweir bIsStorage = sal_True; 578cdf0e10cSrcweir 579cdf0e10cSrcweir uno::Reference < embed::XStorage > xNewStore = pImpl->mxStorage->openStorageElement( rNewName, embed::ElementModes::READWRITE ); 580cdf0e10cSrcweir xStore->copyToStorage( xNewStore ); 581cdf0e10cSrcweir } 582cdf0e10cSrcweir catch ( uno::Exception& ) 583cdf0e10cSrcweir { 584cdf0e10cSrcweir if ( bIsStorage ) 585cdf0e10cSrcweir // it is storage persistence, but opening of new substorage or copying to it failed 586cdf0e10cSrcweir return uno::Reference < embed::XEmbeddedObject >(); 587cdf0e10cSrcweir 588cdf0e10cSrcweir // stream didn't contain a storage, now try stream persistence 589cdf0e10cSrcweir try 590cdf0e10cSrcweir { 591cdf0e10cSrcweir uno::Reference < io::XStream > xNewStream = pImpl->mxStorage->openStreamElement( rNewName, embed::ElementModes::READWRITE ); 592cdf0e10cSrcweir ::comphelper::OStorageHelper::CopyInputToOutput( xStm, xNewStream->getOutputStream() ); 593cdf0e10cSrcweir 594cdf0e10cSrcweir // No mediatype is provided so the default for OLE objects value is used 595cdf0e10cSrcweir // it is correct so for now, but what if somebody introduces a new stream based embedded object? 596cdf0e10cSrcweir // Probably introducing of such an object must be restricted ( a storage must be used! ). 597cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xProps( xNewStream, uno::UNO_QUERY_THROW ); 598cdf0e10cSrcweir xProps->setPropertyValue( 599cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), 600cdf0e10cSrcweir uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) ); 601cdf0e10cSrcweir } 602cdf0e10cSrcweir catch ( uno::Exception& ) 603cdf0e10cSrcweir { 604cdf0e10cSrcweir // complete disaster! 605cdf0e10cSrcweir return uno::Reference < embed::XEmbeddedObject >(); 606cdf0e10cSrcweir } 607cdf0e10cSrcweir } 608cdf0e10cSrcweir 609cdf0e10cSrcweir // stream was copied into the container storage in either way, now try to open something form it 610cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xRet = GetEmbeddedObject( rNewName ); 611cdf0e10cSrcweir try 612cdf0e10cSrcweir { 613cdf0e10cSrcweir if ( !xRet.is() ) 614cdf0e10cSrcweir // no object could be created, so withdraw insertion 615cdf0e10cSrcweir pImpl->mxStorage->removeElement( rNewName ); 616cdf0e10cSrcweir } 617cdf0e10cSrcweir catch ( uno::Exception& ) 618cdf0e10cSrcweir { 619cdf0e10cSrcweir } 620cdf0e10cSrcweir 621cdf0e10cSrcweir return xRet; 622cdf0e10cSrcweir } 623cdf0e10cSrcweir 624cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName ) 625cdf0e10cSrcweir { 626cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( MediaDescriptor )" ); 627cdf0e10cSrcweir 62849b34792SHerbert Dürr if ( rNewName.isEmpty() ) 629cdf0e10cSrcweir rNewName = CreateUniqueObjectName(); 630cdf0e10cSrcweir 631cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj; 632cdf0e10cSrcweir try 633cdf0e10cSrcweir { 634cdf0e10cSrcweir uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( 635cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); 636cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); 637cdf0e10cSrcweir aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); 638cdf0e10cSrcweir aObjDescr[0].Value <<= pImpl->m_xModel.get(); 639cdf0e10cSrcweir xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromMediaDescriptor( 640cdf0e10cSrcweir pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY ); 641cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 642cdf0e10cSrcweir 643cdf0e10cSrcweir OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED, 644cdf0e10cSrcweir "A freshly create object should be running always!\n" ); 645cdf0e10cSrcweir 646cdf0e10cSrcweir // possible optimization: store later! 647cdf0e10cSrcweir if ( xPersist.is()) 648cdf0e10cSrcweir xPersist->storeOwn(); 649cdf0e10cSrcweir 650cdf0e10cSrcweir AddEmbeddedObject( xObj, rNewName ); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir catch ( uno::Exception& ) 653cdf0e10cSrcweir { 654cdf0e10cSrcweir } 655cdf0e10cSrcweir 656cdf0e10cSrcweir return xObj; 657cdf0e10cSrcweir } 658cdf0e10cSrcweir 659cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedLink( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName ) 660cdf0e10cSrcweir { 661cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedLink" ); 662cdf0e10cSrcweir 66349b34792SHerbert Dürr if ( rNewName.isEmpty() ) 664cdf0e10cSrcweir rNewName = CreateUniqueObjectName(); 665cdf0e10cSrcweir 666cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj; 667cdf0e10cSrcweir try 668cdf0e10cSrcweir { 669cdf0e10cSrcweir uno::Reference < embed::XLinkCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( 670cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); 671cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); 672cdf0e10cSrcweir aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); 673*716c984aSArrigo Marchiori uno::Any model( pImpl->m_xModel.get() ); 674*716c984aSArrigo Marchiori aObjDescr[0].Value <<= model; 675*716c984aSArrigo Marchiori // The call to XLinkCreator::createInstanceLink() will open the link. 676*716c984aSArrigo Marchiori // We must request for authorization now. And we need the URL for that. 677*716c984aSArrigo Marchiori ::rtl::OUString aURL; 678*716c984aSArrigo Marchiori for ( sal_Int32 i = 0; i < aMedium.getLength(); i++ ) 679*716c984aSArrigo Marchiori if ( aMedium[i].Name.equalsAscii( "URL" ) ) 680*716c984aSArrigo Marchiori aMedium[i].Value >>= aURL; 681*716c984aSArrigo Marchiori uno::Reference< com::sun::star::document::XLinkAuthorizer > xLinkAuthorizer( model, uno::UNO_QUERY ); 682*716c984aSArrigo Marchiori if ( xLinkAuthorizer.is() ) { 683*716c984aSArrigo Marchiori if ( !xLinkAuthorizer->authorizeLinks( aURL ) ) 684*716c984aSArrigo Marchiori throw uno::RuntimeException(); 685*716c984aSArrigo Marchiori } 686cdf0e10cSrcweir xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceLink( 687cdf0e10cSrcweir pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY ); 688cdf0e10cSrcweir 689cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 690cdf0e10cSrcweir 691cdf0e10cSrcweir OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED, 692cdf0e10cSrcweir "A freshly create object should be running always!\n" ); 693cdf0e10cSrcweir 694cdf0e10cSrcweir // possible optimization: store later! 695cdf0e10cSrcweir if ( xPersist.is()) 696cdf0e10cSrcweir xPersist->storeOwn(); 697cdf0e10cSrcweir 698cdf0e10cSrcweir AddEmbeddedObject( xObj, rNewName ); 699cdf0e10cSrcweir } 700cdf0e10cSrcweir catch ( uno::Exception& ) 701cdf0e10cSrcweir { 702cdf0e10cSrcweir } 703cdf0e10cSrcweir 704cdf0e10cSrcweir return xObj; 705cdf0e10cSrcweir } 706cdf0e10cSrcweir 707cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::TryToCopyGraphReplacement( EmbeddedObjectContainer& rSrc, 708cdf0e10cSrcweir const ::rtl::OUString& aOrigName, 709cdf0e10cSrcweir const ::rtl::OUString& aTargetName ) 710cdf0e10cSrcweir { 711cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::TryToCopyGraphReplacement" ); 712cdf0e10cSrcweir 713cdf0e10cSrcweir sal_Bool bResult = sal_False; 714cdf0e10cSrcweir 71549b34792SHerbert Dürr if ( ( &rSrc != this || !aOrigName.equals( aTargetName ) ) && !aOrigName.isEmpty() && !aTargetName.isEmpty() ) 716cdf0e10cSrcweir { 717cdf0e10cSrcweir ::rtl::OUString aMediaType; 718cdf0e10cSrcweir uno::Reference < io::XInputStream > xGrStream = rSrc.GetGraphicStream( aOrigName, &aMediaType ); 719cdf0e10cSrcweir if ( xGrStream.is() ) 720cdf0e10cSrcweir bResult = InsertGraphicStream( xGrStream, aTargetName, aMediaType ); 721cdf0e10cSrcweir } 722cdf0e10cSrcweir 723cdf0e10cSrcweir return bResult; 724cdf0e10cSrcweir } 725cdf0e10cSrcweir 726cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::CopyEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) 727cdf0e10cSrcweir { 728cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyEmbeddedObject" ); 729cdf0e10cSrcweir 730cdf0e10cSrcweir OSL_ENSURE( sal_False, 731cdf0e10cSrcweir "This method is depricated! Use EmbeddedObjectContainer::CopyAndGetEmbeddedObject() to copy object!\n" ); 732cdf0e10cSrcweir 733cdf0e10cSrcweir // get the object name before(!) it is assigned to a new storage 734cdf0e10cSrcweir ::rtl::OUString aOrigName; 735cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 736cdf0e10cSrcweir if ( xPersist.is() ) 737cdf0e10cSrcweir aOrigName = xPersist->getEntryName(); 738cdf0e10cSrcweir 73949b34792SHerbert Dürr if ( rName.isEmpty() ) 740cdf0e10cSrcweir rName = CreateUniqueObjectName(); 741cdf0e10cSrcweir 742cdf0e10cSrcweir if ( StoreEmbeddedObject( xObj, rName, sal_True ) ) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir TryToCopyGraphReplacement( rSrc, aOrigName, rName ); 745cdf0e10cSrcweir return sal_True; 746cdf0e10cSrcweir } 747cdf0e10cSrcweir 748cdf0e10cSrcweir return sal_False; 749cdf0e10cSrcweir } 750cdf0e10cSrcweir 751cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CopyAndGetEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) 752cdf0e10cSrcweir { 753cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyAndGetEmbeddedObject" ); 754cdf0e10cSrcweir 755cdf0e10cSrcweir uno::Reference< embed::XEmbeddedObject > xResult; 756cdf0e10cSrcweir 757cdf0e10cSrcweir // TODO/LATER: For now only objects that implement XEmbedPersist have a replacement image, it might change in future 758cdf0e10cSrcweir // do an incompatible change so that object name is provided in all the move and copy methods 759cdf0e10cSrcweir ::rtl::OUString aOrigName; 760cdf0e10cSrcweir try 761cdf0e10cSrcweir { 762cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY_THROW ); 763cdf0e10cSrcweir aOrigName = xPersist->getEntryName(); 764cdf0e10cSrcweir } 765cdf0e10cSrcweir catch( uno::Exception& ) 766cdf0e10cSrcweir {} 767cdf0e10cSrcweir 76849b34792SHerbert Dürr if ( rName.isEmpty() ) 769cdf0e10cSrcweir rName = CreateUniqueObjectName(); 770cdf0e10cSrcweir 77107a3d7f1SPedro Giffuni // objects without persistence are not really stored by the method 772cdf0e10cSrcweir if ( xObj.is() && StoreEmbeddedObject( xObj, rName, sal_True ) ) 773cdf0e10cSrcweir { 774cdf0e10cSrcweir xResult = Get_Impl( rName, xObj); 775cdf0e10cSrcweir if ( !xResult.is() ) 776cdf0e10cSrcweir { 777cdf0e10cSrcweir // this is a case when object has no real persistence 778cdf0e10cSrcweir // in such cases a new object should be explicitly created and initialized with the data of the old one 779cdf0e10cSrcweir try 780cdf0e10cSrcweir { 781cdf0e10cSrcweir uno::Reference< embed::XLinkageSupport > xOrigLinkage( xObj, uno::UNO_QUERY ); 782cdf0e10cSrcweir if ( xOrigLinkage.is() && xOrigLinkage->isLink() ) 783cdf0e10cSrcweir { 784cdf0e10cSrcweir // this is a OOo link, it has no persistence 785cdf0e10cSrcweir ::rtl::OUString aURL = xOrigLinkage->getLinkURL(); 78649b34792SHerbert Dürr if ( aURL.isEmpty() ) 787cdf0e10cSrcweir throw uno::RuntimeException(); 788cdf0e10cSrcweir 789cdf0e10cSrcweir // create new linked object from the URL the link is based on 790cdf0e10cSrcweir uno::Reference < embed::XLinkCreator > xCreator( 791cdf0e10cSrcweir ::comphelper::getProcessServiceFactory()->createInstance( 792cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ), 793cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 794cdf0e10cSrcweir 795cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aMediaDescr( 1 ); 796cdf0e10cSrcweir aMediaDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 797cdf0e10cSrcweir aMediaDescr[0].Value <<= aURL; 798cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); 799cdf0e10cSrcweir aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); 800cdf0e10cSrcweir aObjDescr[0].Value <<= pImpl->m_xModel.get(); 801cdf0e10cSrcweir xResult = uno::Reference < embed::XEmbeddedObject >( 802cdf0e10cSrcweir xCreator->createInstanceLink( 803cdf0e10cSrcweir pImpl->mxStorage, 804cdf0e10cSrcweir rName, 805cdf0e10cSrcweir aMediaDescr, 806cdf0e10cSrcweir aObjDescr ), 807cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 808cdf0e10cSrcweir } 809cdf0e10cSrcweir else 810cdf0e10cSrcweir { 811cdf0e10cSrcweir // the component is required for copying of this object 812cdf0e10cSrcweir if ( xObj->getCurrentState() == embed::EmbedStates::LOADED ) 813cdf0e10cSrcweir xObj->changeState( embed::EmbedStates::RUNNING ); 814cdf0e10cSrcweir 815cdf0e10cSrcweir // this must be an object based on properties, otherwise we can not copy it currently 816cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xOrigProps( xObj->getComponent(), uno::UNO_QUERY_THROW ); 817cdf0e10cSrcweir 81807a3d7f1SPedro Giffuni // use object class ID to create a new one and transfer all the properties 819cdf0e10cSrcweir uno::Reference < embed::XEmbedObjectCreator > xCreator( 820cdf0e10cSrcweir ::comphelper::getProcessServiceFactory()->createInstance( 821cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ), 822cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 823cdf0e10cSrcweir 824cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); 825cdf0e10cSrcweir aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); 826cdf0e10cSrcweir aObjDescr[0].Value <<= pImpl->m_xModel.get(); 827cdf0e10cSrcweir xResult = uno::Reference < embed::XEmbeddedObject >( 828cdf0e10cSrcweir xCreator->createInstanceInitNew( 829cdf0e10cSrcweir xObj->getClassID(), 830cdf0e10cSrcweir xObj->getClassName(), 831cdf0e10cSrcweir pImpl->mxStorage, 832cdf0e10cSrcweir rName, 833cdf0e10cSrcweir aObjDescr ), 834cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 835cdf0e10cSrcweir 836cdf0e10cSrcweir if ( xResult->getCurrentState() == embed::EmbedStates::LOADED ) 837cdf0e10cSrcweir xResult->changeState( embed::EmbedStates::RUNNING ); 838cdf0e10cSrcweir 839cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xTargetProps( xResult->getComponent(), uno::UNO_QUERY_THROW ); 840cdf0e10cSrcweir 841cdf0e10cSrcweir // copy all the properties from xOrigProps to xTargetProps 842cdf0e10cSrcweir uno::Reference< beans::XPropertySetInfo > xOrigInfo = xOrigProps->getPropertySetInfo(); 843cdf0e10cSrcweir if ( !xOrigInfo.is() ) 844cdf0e10cSrcweir throw uno::RuntimeException(); 845cdf0e10cSrcweir 846cdf0e10cSrcweir uno::Sequence< beans::Property > aPropertiesList = xOrigInfo->getProperties(); 847cdf0e10cSrcweir for ( sal_Int32 nInd = 0; nInd < aPropertiesList.getLength(); nInd++ ) 848cdf0e10cSrcweir { 849cdf0e10cSrcweir try 850cdf0e10cSrcweir { 851cdf0e10cSrcweir xTargetProps->setPropertyValue( 852cdf0e10cSrcweir aPropertiesList[nInd].Name, 853cdf0e10cSrcweir xOrigProps->getPropertyValue( aPropertiesList[nInd].Name ) ); 854cdf0e10cSrcweir } 855cdf0e10cSrcweir catch( beans::PropertyVetoException& ) 856cdf0e10cSrcweir { 857cdf0e10cSrcweir // impossibility to copy readonly property is not treated as an error for now 858cdf0e10cSrcweir // but the assertion is helpful to detect such scenarios and review them 859cdf0e10cSrcweir OSL_ENSURE( sal_False, "Could not copy readonly property!\n" ); 860cdf0e10cSrcweir } 861cdf0e10cSrcweir } 862cdf0e10cSrcweir } 863cdf0e10cSrcweir 864cdf0e10cSrcweir if ( xResult.is() ) 865cdf0e10cSrcweir AddEmbeddedObject( xResult, rName ); 866cdf0e10cSrcweir } 867cdf0e10cSrcweir catch( uno::Exception& ) 868cdf0e10cSrcweir { 869cdf0e10cSrcweir if ( xResult.is() ) 870cdf0e10cSrcweir { 871cdf0e10cSrcweir try 872cdf0e10cSrcweir { 873cdf0e10cSrcweir xResult->close( sal_True ); 874cdf0e10cSrcweir } 875cdf0e10cSrcweir catch( uno::Exception& ) 876cdf0e10cSrcweir {} 877cdf0e10cSrcweir xResult = uno::Reference< embed::XEmbeddedObject >(); 878cdf0e10cSrcweir } 879cdf0e10cSrcweir } 880cdf0e10cSrcweir } 881cdf0e10cSrcweir } 882cdf0e10cSrcweir 88307a3d7f1SPedro Giffuni OSL_ENSURE( xResult.is(), "Can not copy embedded object that has no persistence!\n" ); 884cdf0e10cSrcweir 885cdf0e10cSrcweir if ( xResult.is() ) 886cdf0e10cSrcweir { 887cdf0e10cSrcweir // the object is successfully copied, try to copy graphical replacement 88849b34792SHerbert Dürr if ( !aOrigName.isEmpty() ) 889cdf0e10cSrcweir TryToCopyGraphReplacement( rSrc, aOrigName, rName ); 890cdf0e10cSrcweir 891cdf0e10cSrcweir // the object might need the size to be set 892cdf0e10cSrcweir try 893cdf0e10cSrcweir { 894cdf0e10cSrcweir if ( xResult->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD ) 895cdf0e10cSrcweir xResult->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, 896cdf0e10cSrcweir xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) ); 897cdf0e10cSrcweir } 898cdf0e10cSrcweir catch( uno::Exception& ) 899cdf0e10cSrcweir {} 900cdf0e10cSrcweir } 901cdf0e10cSrcweir 902cdf0e10cSrcweir return xResult; 903cdf0e10cSrcweir } 904cdf0e10cSrcweir 905cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) 906cdf0e10cSrcweir { 907cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Object )" ); 908cdf0e10cSrcweir 909cdf0e10cSrcweir // get the object name before(!) it is assigned to a new storage 910cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 911cdf0e10cSrcweir ::rtl::OUString aName; 912cdf0e10cSrcweir if ( xPersist.is() ) 913cdf0e10cSrcweir aName = xPersist->getEntryName(); 914cdf0e10cSrcweir 915cdf0e10cSrcweir // now move the object to the new container; the returned name is the new persist name in this container 916cdf0e10cSrcweir sal_Bool bRet; 917cdf0e10cSrcweir 918cdf0e10cSrcweir try 919cdf0e10cSrcweir { 920cdf0e10cSrcweir bRet = InsertEmbeddedObject( xObj, rName ); 921cdf0e10cSrcweir if ( bRet ) 922cdf0e10cSrcweir TryToCopyGraphReplacement( rSrc, aName, rName ); 923cdf0e10cSrcweir } 924cdf0e10cSrcweir catch ( uno::Exception& e ) 925cdf0e10cSrcweir { 926cdf0e10cSrcweir (void)e; 927cdf0e10cSrcweir OSL_ENSURE( sal_False, "Failed to insert embedded object into storage!" ); 928cdf0e10cSrcweir bRet = sal_False; 929cdf0e10cSrcweir } 930cdf0e10cSrcweir 931cdf0e10cSrcweir if ( bRet ) 932cdf0e10cSrcweir { 933cdf0e10cSrcweir // now remove the object from the former container 934cdf0e10cSrcweir bRet = sal_False; 935cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = rSrc.pImpl->maObjectContainer.begin(); 936cdf0e10cSrcweir while ( aIt != rSrc.pImpl->maObjectContainer.end() ) 937cdf0e10cSrcweir { 938cdf0e10cSrcweir if ( (*aIt).second == xObj ) 939cdf0e10cSrcweir { 940cdf0e10cSrcweir rSrc.pImpl->maObjectContainer.erase( aIt ); 941cdf0e10cSrcweir bRet = sal_True; 942cdf0e10cSrcweir break; 943cdf0e10cSrcweir } 944cdf0e10cSrcweir 945cdf0e10cSrcweir aIt++; 946cdf0e10cSrcweir } 947cdf0e10cSrcweir 948cdf0e10cSrcweir OSL_ENSURE( bRet, "Object not found for removal!" ); 949cdf0e10cSrcweir if ( xPersist.is() ) 950cdf0e10cSrcweir { 951cdf0e10cSrcweir // now it's time to remove the storage from the container storage 952cdf0e10cSrcweir try 953cdf0e10cSrcweir { 954cdf0e10cSrcweir if ( xPersist.is() ) 955cdf0e10cSrcweir rSrc.pImpl->mxStorage->removeElement( aName ); 956cdf0e10cSrcweir } 957cdf0e10cSrcweir catch ( uno::Exception& ) 958cdf0e10cSrcweir { 959cdf0e10cSrcweir OSL_ENSURE( sal_False, "Failed to remove object from storage!" ); 960cdf0e10cSrcweir bRet = sal_False; 961cdf0e10cSrcweir } 962cdf0e10cSrcweir } 963cdf0e10cSrcweir 964cdf0e10cSrcweir // rSrc.RemoveGraphicStream( aName ); 965cdf0e10cSrcweir } 966cdf0e10cSrcweir 967cdf0e10cSrcweir return bRet; 968cdf0e10cSrcweir } 969cdf0e10cSrcweir 9706170fa3cSArmin Le Grand //sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose ) 9716170fa3cSArmin Le Grand // #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+ 9726170fa3cSArmin Le Grand sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose, sal_Bool bKeepToTempStorage ) 973cdf0e10cSrcweir { 974cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Name )" ); 975cdf0e10cSrcweir 976cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( rName ); 977cdf0e10cSrcweir if ( xObj.is() ) 9786170fa3cSArmin Le Grand //return RemoveEmbeddedObject( xObj, bClose ); 9796170fa3cSArmin Le Grand return RemoveEmbeddedObject( xObj, bClose, bKeepToTempStorage ); 980cdf0e10cSrcweir else 981cdf0e10cSrcweir return sal_False; 982cdf0e10cSrcweir } 983cdf0e10cSrcweir 984cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( const ::rtl::OUString& rName, EmbeddedObjectContainer& rCnt ) 985cdf0e10cSrcweir { 986cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Name )" ); 987cdf0e10cSrcweir 988cdf0e10cSrcweir // find object entry 989cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt2 = rCnt.pImpl->maObjectContainer.find( rName ); 990cdf0e10cSrcweir OSL_ENSURE( aIt2 == rCnt.pImpl->maObjectContainer.end(), "Object does already exist in target container!" ); 991cdf0e10cSrcweir 992cdf0e10cSrcweir if ( aIt2 != rCnt.pImpl->maObjectContainer.end() ) 993cdf0e10cSrcweir return sal_False; 994cdf0e10cSrcweir 995cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj; 996cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); 997cdf0e10cSrcweir if ( aIt != pImpl->maObjectContainer.end() ) 998cdf0e10cSrcweir { 999cdf0e10cSrcweir xObj = (*aIt).second; 1000cdf0e10cSrcweir try 1001cdf0e10cSrcweir { 1002cdf0e10cSrcweir if ( xObj.is() ) 1003cdf0e10cSrcweir { 1004cdf0e10cSrcweir // move object 1005cdf0e10cSrcweir ::rtl::OUString aName( rName ); 1006cdf0e10cSrcweir rCnt.InsertEmbeddedObject( xObj, aName ); 1007cdf0e10cSrcweir pImpl->maObjectContainer.erase( aIt ); 1008cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 1009cdf0e10cSrcweir if ( xPersist.is() ) 1010cdf0e10cSrcweir pImpl->mxStorage->removeElement( rName ); 1011cdf0e10cSrcweir } 1012cdf0e10cSrcweir else 1013cdf0e10cSrcweir { 1014cdf0e10cSrcweir // copy storages; object *must* have persistence! 1015cdf0e10cSrcweir uno::Reference < embed::XStorage > xOld = pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READ ); 1016cdf0e10cSrcweir uno::Reference < embed::XStorage > xNew = rCnt.pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READWRITE ); 1017cdf0e10cSrcweir xOld->copyToStorage( xNew ); 1018cdf0e10cSrcweir } 1019cdf0e10cSrcweir 1020cdf0e10cSrcweir rCnt.TryToCopyGraphReplacement( *this, rName, rName ); 1021cdf0e10cSrcweir // RemoveGraphicStream( rName ); 1022cdf0e10cSrcweir 1023cdf0e10cSrcweir return sal_True; 1024cdf0e10cSrcweir } 1025cdf0e10cSrcweir catch ( uno::Exception& ) 1026cdf0e10cSrcweir { 1027cdf0e10cSrcweir OSL_ENSURE(0,"Could not move object!"); 1028cdf0e10cSrcweir return sal_False; 1029cdf0e10cSrcweir } 1030cdf0e10cSrcweir 1031cdf0e10cSrcweir } 1032cdf0e10cSrcweir else 1033cdf0e10cSrcweir OSL_ENSURE(0,"Unknown object!"); 1034cdf0e10cSrcweir return sal_False; 1035cdf0e10cSrcweir } 1036cdf0e10cSrcweir 10376170fa3cSArmin Le Grand //sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose ) 10386170fa3cSArmin Le Grand // #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+ 10396170fa3cSArmin Le Grand sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose, sal_Bool bKeepToTempStorage ) 1040cdf0e10cSrcweir { 1041cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Object )" ); 1042cdf0e10cSrcweir 1043cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 1044cdf0e10cSrcweir ::rtl::OUString aName; 1045cdf0e10cSrcweir if ( xPersist.is() ) 1046cdf0e10cSrcweir aName = xPersist->getEntryName(); 1047cdf0e10cSrcweir 1048cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1049cdf0e10cSrcweir uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); 1050cdf0e10cSrcweir uno::Reference < embed::XLinkageSupport > xLink( xPersist, uno::UNO_QUERY ); 1051cdf0e10cSrcweir sal_Bool bIsNotEmbedded = !xPersist.is() || xLink.is() && xLink->isLink(); 1052cdf0e10cSrcweir 105307a3d7f1SPedro Giffuni // if the object has a persistence and the object is not a link than it must have persistence entry in the storage 1054cdf0e10cSrcweir OSL_ENSURE( bIsNotEmbedded || xAccess->hasByName(aName), "Removing element not present in storage!" ); 1055cdf0e10cSrcweir #endif 1056cdf0e10cSrcweir 1057cdf0e10cSrcweir // try to close it if permitted 1058cdf0e10cSrcweir if ( bClose ) 1059cdf0e10cSrcweir { 1060cdf0e10cSrcweir uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY ); 1061cdf0e10cSrcweir try 1062cdf0e10cSrcweir { 1063cdf0e10cSrcweir xClose->close( sal_True ); 1064cdf0e10cSrcweir } 1065cdf0e10cSrcweir catch ( util::CloseVetoException& ) 1066cdf0e10cSrcweir { 1067cdf0e10cSrcweir bClose = sal_False; 1068cdf0e10cSrcweir } 1069cdf0e10cSrcweir } 1070cdf0e10cSrcweir 1071cdf0e10cSrcweir if ( !bClose ) 1072cdf0e10cSrcweir { 1073cdf0e10cSrcweir // somebody still needs the object, so we must assign a temporary persistence 1074cdf0e10cSrcweir try 1075cdf0e10cSrcweir { 10766170fa3cSArmin Le Grand // if ( xPersist.is() ) 10776170fa3cSArmin Le Grand if ( xPersist.is() && bKeepToTempStorage ) // #i119941 1078cdf0e10cSrcweir { 1079cdf0e10cSrcweir /* 1080cdf0e10cSrcweir // TODO/LATER: needs storage handling! Why not letting the object do it?! 1081cdf0e10cSrcweir if ( !pImpl->mxTempStorage.is() ) 1082cdf0e10cSrcweir pImpl->mxTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 1083cdf0e10cSrcweir uno::Sequence < beans::PropertyValue > aSeq; 1084cdf0e10cSrcweir 1085cdf0e10cSrcweir ::rtl::OUString aTmpPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") ); 1086cdf0e10cSrcweir aTmpPersistName += ::rtl::OUString::valueOf( (sal_Int32) pImpl->maTempObjectContainer.size() ); 1087cdf0e10cSrcweir 1088cdf0e10cSrcweir xPersist->storeAsEntry( pImpl->mxTempStorage, aTmpPersistName, aSeq, aSeq ); 1089cdf0e10cSrcweir xPersist->saveCompleted( sal_True ); 1090cdf0e10cSrcweir 1091cdf0e10cSrcweir pImpl->maTempObjectContainer[ aTmpPersistName ] = uno::Reference < embed::XEmbeddedObject >(); 1092cdf0e10cSrcweir */ 1093cdf0e10cSrcweir 1094cdf0e10cSrcweir if ( !pImpl->mpTempObjectContainer ) 1095cdf0e10cSrcweir { 1096cdf0e10cSrcweir pImpl->mpTempObjectContainer = new EmbeddedObjectContainer(); 1097cdf0e10cSrcweir try 1098cdf0e10cSrcweir { 1099cdf0e10cSrcweir // TODO/LATER: in future probably the temporary container will have two storages ( of two formats ) 1100cdf0e10cSrcweir // the media type will be provided with object insertion 1101cdf0e10cSrcweir ::rtl::OUString aOrigStorMediaType; 1102cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xStorProps( pImpl->mxStorage, uno::UNO_QUERY_THROW ); 1103cdf0e10cSrcweir static const ::rtl::OUString s_sMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType")); 1104cdf0e10cSrcweir xStorProps->getPropertyValue( s_sMediaType ) >>= aOrigStorMediaType; 1105cdf0e10cSrcweir 110649b34792SHerbert Dürr OSL_ENSURE( !aOrigStorMediaType.isEmpty(), "No valuable media type in the storage!\n" ); 1107cdf0e10cSrcweir 1108cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xTargetStorProps( 1109cdf0e10cSrcweir pImpl->mpTempObjectContainer->pImpl->mxStorage, 1110cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 1111cdf0e10cSrcweir xTargetStorProps->setPropertyValue( s_sMediaType,uno::makeAny( aOrigStorMediaType ) ); 1112cdf0e10cSrcweir } 1113cdf0e10cSrcweir catch( uno::Exception& ) 1114cdf0e10cSrcweir { 1115cdf0e10cSrcweir OSL_ENSURE( sal_False, "Can not set the new media type to a storage!\n" ); 1116cdf0e10cSrcweir } 1117cdf0e10cSrcweir } 1118cdf0e10cSrcweir 1119cdf0e10cSrcweir ::rtl::OUString aTempName, aMediaType; 1120cdf0e10cSrcweir pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName ); 1121cdf0e10cSrcweir 1122cdf0e10cSrcweir uno::Reference < io::XInputStream > xStream = GetGraphicStream( xObj, &aMediaType ); 1123cdf0e10cSrcweir if ( xStream.is() ) 1124cdf0e10cSrcweir pImpl->mpTempObjectContainer->InsertGraphicStream( xStream, aTempName, aMediaType ); 1125cdf0e10cSrcweir 1126cdf0e10cSrcweir // object is stored, so at least it can be set to loaded state 1127cdf0e10cSrcweir xObj->changeState( embed::EmbedStates::LOADED ); 1128cdf0e10cSrcweir } 1129cdf0e10cSrcweir else 1130cdf0e10cSrcweir // objects without persistence need to stay in running state if they shall not be closed 1131cdf0e10cSrcweir xObj->changeState( embed::EmbedStates::RUNNING ); 1132cdf0e10cSrcweir } 1133cdf0e10cSrcweir catch ( uno::Exception& ) 1134cdf0e10cSrcweir { 1135cdf0e10cSrcweir return sal_False; 1136cdf0e10cSrcweir } 1137cdf0e10cSrcweir } 1138cdf0e10cSrcweir 1139cdf0e10cSrcweir sal_Bool bFound = sal_False; 1140cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 1141cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 1142cdf0e10cSrcweir { 1143cdf0e10cSrcweir if ( (*aIt).second == xObj ) 1144cdf0e10cSrcweir { 1145cdf0e10cSrcweir pImpl->maObjectContainer.erase( aIt ); 1146cdf0e10cSrcweir bFound = sal_True; 1147cdf0e10cSrcweir uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY ); 1148cdf0e10cSrcweir if ( xChild.is() ) 1149cdf0e10cSrcweir xChild->setParent( uno::Reference < uno::XInterface >() ); 1150cdf0e10cSrcweir break; 1151cdf0e10cSrcweir } 1152cdf0e10cSrcweir 1153cdf0e10cSrcweir aIt++; 1154cdf0e10cSrcweir } 1155cdf0e10cSrcweir 1156cdf0e10cSrcweir OSL_ENSURE( bFound, "Object not found for removal!" ); 11576170fa3cSArmin Le Grand // if ( xPersist.is() ) 11586170fa3cSArmin Le Grand if ( xPersist.is() && bKeepToTempStorage ) // #i119941 1159cdf0e10cSrcweir { 1160cdf0e10cSrcweir // remove replacement image (if there is one) 1161cdf0e10cSrcweir RemoveGraphicStream( aName ); 1162cdf0e10cSrcweir 1163cdf0e10cSrcweir // now it's time to remove the storage from the container storage 1164cdf0e10cSrcweir try 1165cdf0e10cSrcweir { 1166cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 116707a3d7f1SPedro Giffuni // if the object has a persistence and the object is not a link than it must have persistence entry in storage 1168cdf0e10cSrcweir OSL_ENSURE( bIsNotEmbedded || pImpl->mxStorage->hasByName( aName ), "The object has no persistence entry in the storage!" ); 1169cdf0e10cSrcweir #endif 1170cdf0e10cSrcweir if ( xPersist.is() && pImpl->mxStorage->hasByName( aName ) ) 1171cdf0e10cSrcweir pImpl->mxStorage->removeElement( aName ); 1172cdf0e10cSrcweir } 1173cdf0e10cSrcweir catch ( uno::Exception& ) 1174cdf0e10cSrcweir { 1175cdf0e10cSrcweir OSL_ENSURE( sal_False, "Failed to remove object from storage!" ); 1176cdf0e10cSrcweir return sal_False; 1177cdf0e10cSrcweir } 1178cdf0e10cSrcweir } 1179cdf0e10cSrcweir 1180cdf0e10cSrcweir return sal_True; 1181cdf0e10cSrcweir } 1182cdf0e10cSrcweir 1183cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::CloseEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj ) 1184cdf0e10cSrcweir { 1185cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CloseEmbeddedObject" ); 1186cdf0e10cSrcweir 1187cdf0e10cSrcweir // disconnect the object from the container and close it if possible 1188cdf0e10cSrcweir 1189cdf0e10cSrcweir sal_Bool bFound = sal_False; 1190cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 1191cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 1192cdf0e10cSrcweir { 1193cdf0e10cSrcweir if ( (*aIt).second == xObj ) 1194cdf0e10cSrcweir { 1195cdf0e10cSrcweir pImpl->maObjectContainer.erase( aIt ); 1196cdf0e10cSrcweir bFound = sal_True; 1197cdf0e10cSrcweir break; 1198cdf0e10cSrcweir } 1199cdf0e10cSrcweir 1200cdf0e10cSrcweir aIt++; 1201cdf0e10cSrcweir } 1202cdf0e10cSrcweir 1203cdf0e10cSrcweir if ( bFound ) 1204cdf0e10cSrcweir { 1205cdf0e10cSrcweir uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY ); 1206cdf0e10cSrcweir try 1207cdf0e10cSrcweir { 1208cdf0e10cSrcweir xClose->close( sal_True ); 1209cdf0e10cSrcweir } 1210cdf0e10cSrcweir catch ( uno::Exception& ) 1211cdf0e10cSrcweir { 1212cdf0e10cSrcweir // it is no problem if the object is already closed 1213cdf0e10cSrcweir // TODO/LATER: what if the object can not be closed? 1214cdf0e10cSrcweir } 1215cdf0e10cSrcweir } 1216cdf0e10cSrcweir 1217cdf0e10cSrcweir return bFound; 1218cdf0e10cSrcweir } 1219cdf0e10cSrcweir 1220cdf0e10cSrcweir uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::rtl::OUString& aName, rtl::OUString* pMediaType ) 1221cdf0e10cSrcweir { 1222cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Name )" ); 1223cdf0e10cSrcweir 1224cdf0e10cSrcweir uno::Reference < io::XInputStream > xStream; 1225cdf0e10cSrcweir 122649b34792SHerbert Dürr OSL_ENSURE( !aName.isEmpty(), "Retrieving graphic for unknown object!" ); 122749b34792SHerbert Dürr if ( !aName.isEmpty() ) 1228cdf0e10cSrcweir { 1229cdf0e10cSrcweir try 1230cdf0e10cSrcweir { 1231cdf0e10cSrcweir uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements(); 1232cdf0e10cSrcweir uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( aName, embed::ElementModes::READ ); 1233cdf0e10cSrcweir xStream = xGraphicStream->getInputStream(); 1234cdf0e10cSrcweir if ( pMediaType ) 1235cdf0e10cSrcweir { 1236cdf0e10cSrcweir uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY ); 1237cdf0e10cSrcweir if ( xSet.is() ) 1238cdf0e10cSrcweir { 1239cdf0e10cSrcweir uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("MediaType") ); 1240cdf0e10cSrcweir aAny >>= *pMediaType; 1241cdf0e10cSrcweir } 1242cdf0e10cSrcweir } 1243cdf0e10cSrcweir } 1244cdf0e10cSrcweir catch ( uno::Exception& ) 1245cdf0e10cSrcweir { 1246cdf0e10cSrcweir } 1247cdf0e10cSrcweir } 1248cdf0e10cSrcweir 1249cdf0e10cSrcweir return xStream; 1250cdf0e10cSrcweir } 1251cdf0e10cSrcweir 1252cdf0e10cSrcweir uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, rtl::OUString* pMediaType ) 1253cdf0e10cSrcweir { 1254cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Object )" ); 1255cdf0e10cSrcweir 1256cdf0e10cSrcweir // get the object name 1257cdf0e10cSrcweir ::rtl::OUString aName; 1258cdf0e10cSrcweir EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); 1259cdf0e10cSrcweir while ( aIt != pImpl->maObjectContainer.end() ) 1260cdf0e10cSrcweir { 1261cdf0e10cSrcweir if ( (*aIt).second == xObj ) 1262cdf0e10cSrcweir { 1263cdf0e10cSrcweir aName = (*aIt).first; 1264cdf0e10cSrcweir break; 1265cdf0e10cSrcweir } 1266cdf0e10cSrcweir 1267cdf0e10cSrcweir aIt++; 1268cdf0e10cSrcweir } 1269cdf0e10cSrcweir 1270cdf0e10cSrcweir // try to load it from the container storage 1271cdf0e10cSrcweir return GetGraphicStream( aName, pMediaType ); 1272cdf0e10cSrcweir } 1273cdf0e10cSrcweir 1274cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::InsertGraphicStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType ) 1275cdf0e10cSrcweir { 1276cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStream" ); 1277cdf0e10cSrcweir 1278cdf0e10cSrcweir try 1279cdf0e10cSrcweir { 1280cdf0e10cSrcweir uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements(); 1281cdf0e10cSrcweir 1282cdf0e10cSrcweir // store it into the subfolder 1283cdf0e10cSrcweir uno::Reference < io::XOutputStream > xOutStream; 1284cdf0e10cSrcweir uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( rObjectName, 1285cdf0e10cSrcweir embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); 1286cdf0e10cSrcweir xOutStream = xGraphicStream->getOutputStream(); 1287cdf0e10cSrcweir ::comphelper::OStorageHelper::CopyInputToOutput( rStream, xOutStream ); 1288cdf0e10cSrcweir xOutStream->flush(); 1289cdf0e10cSrcweir 1290cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xPropSet( xGraphicStream, uno::UNO_QUERY ); 1291cdf0e10cSrcweir if ( !xPropSet.is() ) 1292cdf0e10cSrcweir throw uno::RuntimeException(); 1293cdf0e10cSrcweir 1294cdf0e10cSrcweir xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" ), 1295cdf0e10cSrcweir uno::makeAny( (sal_Bool)sal_True ) ); 1296cdf0e10cSrcweir uno::Any aAny; 1297cdf0e10cSrcweir aAny <<= rMediaType; 1298cdf0e10cSrcweir xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii("MediaType"), aAny ); 1299cdf0e10cSrcweir 1300cdf0e10cSrcweir xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii( "Compressed" ), 1301cdf0e10cSrcweir uno::makeAny( (sal_Bool)sal_True ) ); 1302cdf0e10cSrcweir } 1303cdf0e10cSrcweir catch( uno::Exception& ) 1304cdf0e10cSrcweir { 1305cdf0e10cSrcweir return sal_False; 1306cdf0e10cSrcweir } 1307cdf0e10cSrcweir 1308cdf0e10cSrcweir return sal_True; 1309cdf0e10cSrcweir } 1310cdf0e10cSrcweir 1311cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::InsertGraphicStreamDirectly( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType ) 1312cdf0e10cSrcweir { 1313cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStreamDirectly" ); 1314cdf0e10cSrcweir 1315cdf0e10cSrcweir try 1316cdf0e10cSrcweir { 1317cdf0e10cSrcweir uno::Reference < embed::XStorage > xReplacement = pImpl->GetReplacements(); 1318cdf0e10cSrcweir uno::Reference < embed::XOptimizedStorage > xOptRepl( xReplacement, uno::UNO_QUERY_THROW ); 1319cdf0e10cSrcweir 1320cdf0e10cSrcweir // store it into the subfolder 1321cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aProps( 3 ); 1322cdf0e10cSrcweir aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); 1323cdf0e10cSrcweir aProps[0].Value <<= rMediaType; 1324cdf0e10cSrcweir aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ); 1325cdf0e10cSrcweir aProps[1].Value <<= (sal_Bool)sal_True; 1326cdf0e10cSrcweir aProps[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ); 1327cdf0e10cSrcweir aProps[2].Value <<= (sal_Bool)sal_True; 1328cdf0e10cSrcweir 1329cdf0e10cSrcweir if ( xReplacement->hasByName( rObjectName ) ) 1330cdf0e10cSrcweir xReplacement->removeElement( rObjectName ); 1331cdf0e10cSrcweir 1332cdf0e10cSrcweir xOptRepl->insertStreamElementDirect( rObjectName, rStream, aProps ); 1333cdf0e10cSrcweir } 1334cdf0e10cSrcweir catch( uno::Exception& ) 1335cdf0e10cSrcweir { 1336cdf0e10cSrcweir return sal_False; 1337cdf0e10cSrcweir } 1338cdf0e10cSrcweir 1339cdf0e10cSrcweir return sal_True; 1340cdf0e10cSrcweir } 1341cdf0e10cSrcweir 1342cdf0e10cSrcweir 1343cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::RemoveGraphicStream( const ::rtl::OUString& rObjectName ) 1344cdf0e10cSrcweir { 1345cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveGraphicStream" ); 1346cdf0e10cSrcweir 1347cdf0e10cSrcweir try 1348cdf0e10cSrcweir { 1349cdf0e10cSrcweir uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements(); 1350cdf0e10cSrcweir xReplacements->removeElement( rObjectName ); 1351cdf0e10cSrcweir } 1352cdf0e10cSrcweir catch( uno::Exception& ) 1353cdf0e10cSrcweir { 1354cdf0e10cSrcweir return sal_False; 1355cdf0e10cSrcweir } 1356cdf0e10cSrcweir 1357cdf0e10cSrcweir return sal_True; 1358cdf0e10cSrcweir } 1359cdf0e10cSrcweir namespace { 1360cdf0e10cSrcweir void InsertStreamIntoPicturesStorage_Impl( const uno::Reference< embed::XStorage >& xDocStor, 1361cdf0e10cSrcweir const uno::Reference< io::XInputStream >& xInStream, 1362cdf0e10cSrcweir const ::rtl::OUString& aStreamName ) 1363cdf0e10cSrcweir { 136449b34792SHerbert Dürr OSL_ENSURE( !aStreamName.isEmpty() && xInStream.is() && xDocStor.is(), "Misuse of the method!\n" ); 1365cdf0e10cSrcweir 1366cdf0e10cSrcweir try 1367cdf0e10cSrcweir { 1368cdf0e10cSrcweir uno::Reference< embed::XStorage > xPictures = xDocStor->openStorageElement( 1369cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ), 1370cdf0e10cSrcweir embed::ElementModes::READWRITE ); 1371cdf0e10cSrcweir uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement( 1372cdf0e10cSrcweir aStreamName, 1373cdf0e10cSrcweir embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); 1374cdf0e10cSrcweir uno::Reference< io::XOutputStream > xOutStream( 1375cdf0e10cSrcweir xObjReplStr->getInputStream(), uno::UNO_QUERY_THROW ); 1376cdf0e10cSrcweir 1377cdf0e10cSrcweir ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xOutStream ); 1378cdf0e10cSrcweir xOutStream->closeOutput(); 1379cdf0e10cSrcweir 1380cdf0e10cSrcweir uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY ); 1381cdf0e10cSrcweir if ( xTransact.is() ) 1382cdf0e10cSrcweir xTransact->commit(); 1383cdf0e10cSrcweir } 1384cdf0e10cSrcweir catch( uno::Exception& ) 1385cdf0e10cSrcweir { 1386cdf0e10cSrcweir OSL_ENSURE( sal_False, "The pictures storage is not available!\n" ); 1387cdf0e10cSrcweir } 1388cdf0e10cSrcweir } 1389cdf0e10cSrcweir 1390cdf0e10cSrcweir } 1391cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1392cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::StoreAsChildren(sal_Bool _bOasisFormat,sal_Bool _bCreateEmbedded,const uno::Reference < embed::XStorage >& _xStorage) 1393cdf0e10cSrcweir { 1394cdf0e10cSrcweir sal_Bool bResult = sal_False; 1395cdf0e10cSrcweir try 1396cdf0e10cSrcweir { 1397cdf0e10cSrcweir comphelper::EmbeddedObjectContainer aCnt( _xStorage ); 1398cdf0e10cSrcweir const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames(); 1399cdf0e10cSrcweir const ::rtl::OUString* pIter = aNames.getConstArray(); 1400cdf0e10cSrcweir const ::rtl::OUString* pEnd = pIter + aNames.getLength(); 1401cdf0e10cSrcweir for(;pIter != pEnd;++pIter) 1402cdf0e10cSrcweir { 1403cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter ); 1404cdf0e10cSrcweir OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); 1405cdf0e10cSrcweir if ( xObj.is() ) 1406cdf0e10cSrcweir { 1407cdf0e10cSrcweir sal_Bool bSwitchBackToLoaded = sal_False; 1408cdf0e10cSrcweir uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY ); 1409cdf0e10cSrcweir 1410cdf0e10cSrcweir uno::Reference < io::XInputStream > xStream; 1411cdf0e10cSrcweir ::rtl::OUString aMediaType; 1412cdf0e10cSrcweir 1413cdf0e10cSrcweir sal_Int32 nCurState = xObj->getCurrentState(); 1414cdf0e10cSrcweir if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING ) 1415cdf0e10cSrcweir { 1416cdf0e10cSrcweir // means that the object is not active 1417cdf0e10cSrcweir // copy replacement image from old to new container 1418cdf0e10cSrcweir xStream = GetGraphicStream( xObj, &aMediaType ); 1419cdf0e10cSrcweir } 1420cdf0e10cSrcweir 1421963c6022SArmin Le Grand if ( !xStream.is() && getUserAllowsLinkUpdate() ) 1422cdf0e10cSrcweir { 1423cdf0e10cSrcweir // the image must be regenerated 1424cdf0e10cSrcweir // TODO/LATER: another aspect could be used 1425cdf0e10cSrcweir if ( xObj->getCurrentState() == embed::EmbedStates::LOADED ) 1426cdf0e10cSrcweir bSwitchBackToLoaded = sal_True; 1427cdf0e10cSrcweir 1428cdf0e10cSrcweir xStream = GetGraphicReplacementStream( 1429cdf0e10cSrcweir embed::Aspects::MSOLE_CONTENT, 1430cdf0e10cSrcweir xObj, 1431cdf0e10cSrcweir &aMediaType ); 1432cdf0e10cSrcweir } 1433cdf0e10cSrcweir 1434cdf0e10cSrcweir if ( _bOasisFormat || (xLink.is() && xLink->isLink()) ) 1435cdf0e10cSrcweir { 1436cdf0e10cSrcweir if ( xStream.is() ) 1437cdf0e10cSrcweir { 1438cdf0e10cSrcweir if ( _bOasisFormat ) 1439cdf0e10cSrcweir { 1440cdf0e10cSrcweir // if it is an embedded object or the optimized inserting fails the normal inserting should be done 1441cdf0e10cSrcweir if ( _bCreateEmbedded 1442cdf0e10cSrcweir || !aCnt.InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) ) 1443cdf0e10cSrcweir aCnt.InsertGraphicStream( xStream, *pIter, aMediaType ); 1444cdf0e10cSrcweir } 1445cdf0e10cSrcweir else 1446cdf0e10cSrcweir { 1447cdf0e10cSrcweir // it is a linked object exported into SO7 format 1448cdf0e10cSrcweir InsertStreamIntoPicturesStorage_Impl( _xStorage, xStream, *pIter ); 1449cdf0e10cSrcweir } 1450cdf0e10cSrcweir } 1451cdf0e10cSrcweir } 1452cdf0e10cSrcweir 1453cdf0e10cSrcweir uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 1454cdf0e10cSrcweir if ( xPersist.is() ) 1455cdf0e10cSrcweir { 1456cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat ? 2 : 3 ); 1457cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StoreVisualReplacement" ) ); 1458cdf0e10cSrcweir aArgs[0].Value <<= (sal_Bool)( !_bOasisFormat ); 1459cdf0e10cSrcweir 1460cdf0e10cSrcweir // if it is an embedded object or the optimized inserting fails the normal inserting should be done 1461cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanTryOptimization" ) ); 1462cdf0e10cSrcweir aArgs[1].Value <<= !_bCreateEmbedded; 1463cdf0e10cSrcweir if ( !_bOasisFormat ) 1464cdf0e10cSrcweir { 1465cdf0e10cSrcweir // if object has no cached replacement it will use this one 1466cdf0e10cSrcweir aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualReplacement" ) ); 1467cdf0e10cSrcweir aArgs[2].Value <<= xStream; 1468cdf0e10cSrcweir } 1469cdf0e10cSrcweir 1470cdf0e10cSrcweir xPersist->storeAsEntry( _xStorage, 1471cdf0e10cSrcweir xPersist->getEntryName(), 1472cdf0e10cSrcweir uno::Sequence< beans::PropertyValue >(), 1473cdf0e10cSrcweir aArgs ); 1474cdf0e10cSrcweir } 1475cdf0e10cSrcweir 1476cdf0e10cSrcweir if ( bSwitchBackToLoaded ) 1477cdf0e10cSrcweir // switch back to loaded state; that way we have a minimum cache confusion 1478cdf0e10cSrcweir xObj->changeState( embed::EmbedStates::LOADED ); 1479cdf0e10cSrcweir } 1480cdf0e10cSrcweir } 1481cdf0e10cSrcweir 1482cdf0e10cSrcweir bResult = aCnt.CommitImageSubStorage(); 1483cdf0e10cSrcweir 1484cdf0e10cSrcweir } 1485cdf0e10cSrcweir catch ( uno::Exception& ) 1486cdf0e10cSrcweir { 1487cdf0e10cSrcweir // TODO/LATER: error handling 1488cdf0e10cSrcweir bResult = sal_False; 1489cdf0e10cSrcweir } 1490cdf0e10cSrcweir 1491cdf0e10cSrcweir // the old SO6 format does not store graphical replacements 1492cdf0e10cSrcweir if ( !_bOasisFormat && bResult ) 1493cdf0e10cSrcweir { 1494cdf0e10cSrcweir try 1495cdf0e10cSrcweir { 14962cdca4f8Smseidel // the substorage still can not be locked by the embedded object container 1497cdf0e10cSrcweir ::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) ); 1498cdf0e10cSrcweir if ( _xStorage->hasByName( aObjReplElement ) && _xStorage->isStorageElement( aObjReplElement ) ) 1499cdf0e10cSrcweir _xStorage->removeElement( aObjReplElement ); 1500cdf0e10cSrcweir } 1501cdf0e10cSrcweir catch ( uno::Exception& ) 1502cdf0e10cSrcweir { 1503cdf0e10cSrcweir // TODO/LATER: error handling; 1504cdf0e10cSrcweir bResult = sal_False; 1505cdf0e10cSrcweir } 1506cdf0e10cSrcweir } 1507cdf0e10cSrcweir return bResult; 1508cdf0e10cSrcweir } 1509cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1510cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::StoreChildren(sal_Bool _bOasisFormat,sal_Bool _bObjectsOnly) 1511cdf0e10cSrcweir { 1512cdf0e10cSrcweir sal_Bool bResult = sal_True; 1513cdf0e10cSrcweir const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames(); 1514cdf0e10cSrcweir const ::rtl::OUString* pIter = aNames.getConstArray(); 1515cdf0e10cSrcweir const ::rtl::OUString* pEnd = pIter + aNames.getLength(); 1516cdf0e10cSrcweir for(;pIter != pEnd;++pIter) 1517cdf0e10cSrcweir { 1518cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter ); 1519cdf0e10cSrcweir OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); 1520cdf0e10cSrcweir if ( xObj.is() ) 1521cdf0e10cSrcweir { 1522cdf0e10cSrcweir sal_Int32 nCurState = xObj->getCurrentState(); 1523cdf0e10cSrcweir if ( _bOasisFormat && nCurState != embed::EmbedStates::LOADED && nCurState != embed::EmbedStates::RUNNING ) 1524cdf0e10cSrcweir { 1525cdf0e10cSrcweir // means that the object is active 1526cdf0e10cSrcweir // the image must be regenerated 1527cdf0e10cSrcweir ::rtl::OUString aMediaType; 1528cdf0e10cSrcweir 1529cdf0e10cSrcweir // TODO/LATER: another aspect could be used 1530cdf0e10cSrcweir uno::Reference < io::XInputStream > xStream = 1531cdf0e10cSrcweir GetGraphicReplacementStream( 1532cdf0e10cSrcweir embed::Aspects::MSOLE_CONTENT, 1533cdf0e10cSrcweir xObj, 1534cdf0e10cSrcweir &aMediaType ); 1535cdf0e10cSrcweir if ( xStream.is() ) 1536cdf0e10cSrcweir { 1537cdf0e10cSrcweir if ( !InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) ) 1538cdf0e10cSrcweir InsertGraphicStream( xStream, *pIter, aMediaType ); 1539cdf0e10cSrcweir } 1540cdf0e10cSrcweir } 1541cdf0e10cSrcweir 1542cdf0e10cSrcweir // TODO/LATER: currently the object by default does not cache replacement image 1543cdf0e10cSrcweir // that means that if somebody loads SO7 document and store its objects using 1544cdf0e10cSrcweir // this method the images might be lost. 1545cdf0e10cSrcweir // Currently this method is only used on storing to alien formats, that means 1546cdf0e10cSrcweir // that SO7 documents storing does not use it, and all other filters are 1547cdf0e10cSrcweir // based on OASIS format. But if it changes the method must be fixed. The fix 1548cdf0e10cSrcweir // must be done only on demand since it can affect performance. 1549cdf0e10cSrcweir 1550cdf0e10cSrcweir uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 1551cdf0e10cSrcweir if ( xPersist.is() ) 1552cdf0e10cSrcweir { 1553cdf0e10cSrcweir try 1554cdf0e10cSrcweir { 1555cdf0e10cSrcweir // TODO/LATER: only storing if changed! 155608c6ef97SAndre Fischer //xPersist->storeOwn(); //commented, i120168 155708c6ef97SAndre Fischer 15582aed5233Smseidel // begin:all charts will be persisted as xml format on disk when saving, which is time consuming. 155908c6ef97SAndre Fischer // '_bObjectsOnly' mean we are storing to alien formats. 156008c6ef97SAndre Fischer // 'isStorageElement' mean current object is NOT an MS OLE format. (may also include in future), i120168 156108c6ef97SAndre Fischer if (_bObjectsOnly && (nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING) 156208c6ef97SAndre Fischer && (pImpl->mxStorage->isStorageElement( *pIter ) )) 156308c6ef97SAndre Fischer { 156408c6ef97SAndre Fischer uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY ); 156508c6ef97SAndre Fischer if ( xModifiable.is() && xModifiable->isModified()) 156608c6ef97SAndre Fischer { 1567cdf0e10cSrcweir xPersist->storeOwn(); 1568cdf0e10cSrcweir } 156908c6ef97SAndre Fischer else 157008c6ef97SAndre Fischer { 157107a3d7f1SPedro Giffuni // do nothing. Embedded model is not modified, no need to persist. 157208c6ef97SAndre Fischer } 157308c6ef97SAndre Fischer } 157407a3d7f1SPedro Giffuni else // the embedded object is in active status, always store back it. 157508c6ef97SAndre Fischer { 157608c6ef97SAndre Fischer xPersist->storeOwn(); 157708c6ef97SAndre Fischer } 157808c6ef97SAndre Fischer // end i120168 157908c6ef97SAndre Fischer } 1580cdf0e10cSrcweir catch( uno::Exception& ) 1581cdf0e10cSrcweir { 1582cdf0e10cSrcweir // TODO/LATER: error handling 1583cdf0e10cSrcweir bResult = sal_False; 1584cdf0e10cSrcweir break; 1585cdf0e10cSrcweir } 1586cdf0e10cSrcweir } 1587cdf0e10cSrcweir 1588cdf0e10cSrcweir if ( !_bOasisFormat && !_bObjectsOnly ) 1589cdf0e10cSrcweir { 1590cdf0e10cSrcweir // copy replacement images for linked objects 1591cdf0e10cSrcweir try 1592cdf0e10cSrcweir { 1593cdf0e10cSrcweir uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY ); 1594cdf0e10cSrcweir if ( xLink.is() && xLink->isLink() ) 1595cdf0e10cSrcweir { 1596cdf0e10cSrcweir ::rtl::OUString aMediaType; 1597cdf0e10cSrcweir uno::Reference < io::XInputStream > xInStream = GetGraphicStream( xObj, &aMediaType ); 1598cdf0e10cSrcweir if ( xInStream.is() ) 1599cdf0e10cSrcweir InsertStreamIntoPicturesStorage_Impl( pImpl->mxStorage, xInStream, *pIter ); 1600cdf0e10cSrcweir } 1601cdf0e10cSrcweir } 1602cdf0e10cSrcweir catch( uno::Exception& ) 1603cdf0e10cSrcweir { 1604cdf0e10cSrcweir } 1605cdf0e10cSrcweir } 1606cdf0e10cSrcweir } 1607cdf0e10cSrcweir } 1608cdf0e10cSrcweir 1609cdf0e10cSrcweir if ( bResult && _bOasisFormat ) 1610cdf0e10cSrcweir bResult = CommitImageSubStorage(); 1611cdf0e10cSrcweir 1612cdf0e10cSrcweir if ( bResult && !_bObjectsOnly ) 1613cdf0e10cSrcweir { 1614cdf0e10cSrcweir try 1615cdf0e10cSrcweir { 1616cdf0e10cSrcweir ReleaseImageSubStorage(); 1617cdf0e10cSrcweir ::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) ); 1618cdf0e10cSrcweir if ( !_bOasisFormat && pImpl->mxStorage->hasByName( aObjReplElement ) && pImpl->mxStorage->isStorageElement( aObjReplElement ) ) 1619cdf0e10cSrcweir pImpl->mxStorage->removeElement( aObjReplElement ); 1620cdf0e10cSrcweir } 1621cdf0e10cSrcweir catch( uno::Exception& ) 1622cdf0e10cSrcweir { 1623cdf0e10cSrcweir // TODO/LATER: error handling 1624cdf0e10cSrcweir bResult = sal_False; 1625cdf0e10cSrcweir } 1626cdf0e10cSrcweir } 1627cdf0e10cSrcweir return bResult; 1628cdf0e10cSrcweir } 1629cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1630cdf0e10cSrcweir uno::Reference< io::XInputStream > EmbeddedObjectContainer::GetGraphicReplacementStream( 1631cdf0e10cSrcweir sal_Int64 nViewAspect, 1632cdf0e10cSrcweir const uno::Reference< embed::XEmbeddedObject >& xObj, 1633cdf0e10cSrcweir ::rtl::OUString* pMediaType ) 1634cdf0e10cSrcweir { 1635cdf0e10cSrcweir uno::Reference< io::XInputStream > xInStream; 1636cdf0e10cSrcweir if ( xObj.is() ) 1637cdf0e10cSrcweir { 1638cdf0e10cSrcweir try 1639cdf0e10cSrcweir { 1640cdf0e10cSrcweir // retrieving of the visual representation can switch object to running state 1641cdf0e10cSrcweir embed::VisualRepresentation aRep = xObj->getPreferredVisualRepresentation( nViewAspect ); 1642cdf0e10cSrcweir if ( pMediaType ) 1643cdf0e10cSrcweir *pMediaType = aRep.Flavor.MimeType; 1644cdf0e10cSrcweir 1645cdf0e10cSrcweir uno::Sequence < sal_Int8 > aSeq; 1646cdf0e10cSrcweir aRep.Data >>= aSeq; 1647cdf0e10cSrcweir xInStream = new ::comphelper::SequenceInputStream( aSeq ); 1648cdf0e10cSrcweir } 1649cdf0e10cSrcweir catch ( uno::Exception& ) 1650cdf0e10cSrcweir { 1651cdf0e10cSrcweir } 1652cdf0e10cSrcweir } 1653cdf0e10cSrcweir 1654cdf0e10cSrcweir return xInStream; 1655cdf0e10cSrcweir } 1656cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1657cdf0e10cSrcweir sal_Bool EmbeddedObjectContainer::SetPersistentEntries(const uno::Reference< embed::XStorage >& _xStorage,bool _bClearModifedFlag) 1658cdf0e10cSrcweir { 1659cdf0e10cSrcweir sal_Bool bError = sal_False; 1660cdf0e10cSrcweir const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames(); 1661cdf0e10cSrcweir const ::rtl::OUString* pIter = aNames.getConstArray(); 1662cdf0e10cSrcweir const ::rtl::OUString* pEnd = pIter + aNames.getLength(); 1663cdf0e10cSrcweir for(;pIter != pEnd;++pIter) 1664cdf0e10cSrcweir { 1665cdf0e10cSrcweir uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter ); 1666cdf0e10cSrcweir OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); 1667cdf0e10cSrcweir if ( xObj.is() ) 1668cdf0e10cSrcweir { 1669cdf0e10cSrcweir uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 1670cdf0e10cSrcweir if ( xPersist.is() ) 1671cdf0e10cSrcweir { 1672cdf0e10cSrcweir try 1673cdf0e10cSrcweir { 1674cdf0e10cSrcweir xPersist->setPersistentEntry( _xStorage, 1675cdf0e10cSrcweir *pIter, 1676cdf0e10cSrcweir embed::EntryInitModes::NO_INIT, 1677cdf0e10cSrcweir uno::Sequence< beans::PropertyValue >(), 1678cdf0e10cSrcweir uno::Sequence< beans::PropertyValue >() ); 1679cdf0e10cSrcweir 1680cdf0e10cSrcweir } 1681cdf0e10cSrcweir catch( uno::Exception& ) 1682cdf0e10cSrcweir { 1683cdf0e10cSrcweir // TODO/LATER: error handling 1684cdf0e10cSrcweir bError = sal_True; 1685cdf0e10cSrcweir break; 1686cdf0e10cSrcweir } 1687cdf0e10cSrcweir } 1688cdf0e10cSrcweir if ( _bClearModifedFlag ) 1689cdf0e10cSrcweir { 1690cdf0e10cSrcweir // if this method is used as part of SaveCompleted the object must stay unmodified after execution 1691cdf0e10cSrcweir try 1692cdf0e10cSrcweir { 1693cdf0e10cSrcweir uno::Reference< util::XModifiable > xModif( xObj->getComponent(), uno::UNO_QUERY_THROW ); 1694cdf0e10cSrcweir if ( xModif->isModified() ) 1695cdf0e10cSrcweir xModif->setModified( sal_False ); 1696cdf0e10cSrcweir } 1697cdf0e10cSrcweir catch( uno::Exception& ) 1698cdf0e10cSrcweir { 1699cdf0e10cSrcweir } 1700cdf0e10cSrcweir } 1701cdf0e10cSrcweir } 1702cdf0e10cSrcweir } 1703cdf0e10cSrcweir return bError; 1704cdf0e10cSrcweir } 1705963c6022SArmin Le Grand 1706963c6022SArmin Le Grand bool EmbeddedObjectContainer::getUserAllowsLinkUpdate() const 1707963c6022SArmin Le Grand { 1708963c6022SArmin Le Grand return pImpl->mbUserAllowsLinkUpdate; 1709963c6022SArmin Le Grand } 1710963c6022SArmin Le Grand 1711963c6022SArmin Le Grand void EmbeddedObjectContainer::setUserAllowsLinkUpdate(bool bNew) 1712963c6022SArmin Le Grand { 1713963c6022SArmin Le Grand if(pImpl->mbUserAllowsLinkUpdate != bNew) 1714963c6022SArmin Le Grand { 1715963c6022SArmin Le Grand pImpl->mbUserAllowsLinkUpdate = bNew; 1716963c6022SArmin Le Grand } 1717963c6022SArmin Le Grand } 1718963c6022SArmin Le Grand 1719cdf0e10cSrcweir } 17202cdca4f8Smseidel 17212cdca4f8Smseidel /* vim: set noet sw=4 ts=4: */ 1722