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