diff options
-rw-r--r-- | svx/inc/xmleohlp.hxx | 173 | ||||
-rw-r--r-- | svx/prj/d.lst | 1 | ||||
-rw-r--r-- | svx/source/xml/makefile.mk | 10 | ||||
-rw-r--r-- | svx/source/xml/xmleohlp.cxx | 577 |
4 files changed, 757 insertions, 4 deletions
diff --git a/svx/inc/xmleohlp.hxx b/svx/inc/xmleohlp.hxx new file mode 100644 index 000000000000..d55b9cffee55 --- /dev/null +++ b/svx/inc/xmleohlp.hxx @@ -0,0 +1,173 @@ +/************************************************************************* + * + * $RCSfile: xmleohlp.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: mib $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _XMLEOHLP_HXX +#define _XMLEOHLP_HXX + +#ifndef _CPPUHELPER_COMPBASE1_HXX_ +#include <cppuhelper/compbase1.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _SVSTOR_HXX +#include <so3/svstor.hxx> +#endif +#ifndef __SGI_STL_VECTOR +#include <stl/vector> +#endif + +#ifndef _COM_SUN_STAR_DOCUMENT_XEMBEDDEDOBJECTRESOLVER_HPP_ +#include <com/sun/star/document/XEmbeddedObjectResolver.hpp> +#endif + +// ----------------------------- +// - SvXMLEmbeddedObjectHelper - +// ----------------------------- + +enum SvXMLEmbeddedObjectHelperMode +{ + EMBEDDEDOBJECTHELPER_MODE_READ = 0, + EMBEDDEDOBJECTHELPER_MODE_WRITE = 1 +}; + +// ----------------------------- +// - SvXMLEmbeddedObjectHelper - +// ----------------------------- + +class SvPersist; +class SvGlobalName; + +class SvXMLEmbeddedObjectHelper : public ::cppu::WeakComponentImplHelper1< ::com::sun::star::document::XEmbeddedObjectResolver > +{ +private: + + typedef ::_STL::vector< ::rtl::OUString > URLVector; + + ::osl::Mutex maMutex; + + const ::rtl::OUString maDefaultContainerStorageName; + ::rtl::OUString maCurContainerStorageName; + + URLVector maEmbeddedObjectURLs; + + SvStorage* mpRootStorage; // package + SvPersist* mpDocPersist; + SvStorageRef mxContainerStorage; // container sub package for + // objects + SvGlobalName** mpGlobalNameMap; + + + SvXMLEmbeddedObjectHelperMode meCreateMode; + void* mpDummy1; + void* mpDummy2; + BOOL mbDirect : 1; + + sal_Bool ImplGetStorageNames( + const ::rtl::OUString& rURLStr, + ::rtl::OUString& rContainerStorageName, + ::rtl::OUString& rObjectStorageName, + sal_Bool bInternalToExternal ) const; + sal_uInt16 ImplGetFlags( + const SvGlobalName& rClassId ) const; + SvStorageRef ImplGetContainerStorage( + const ::rtl::OUString& rStorageName ); + SvStorageRef ImplGetObjectStorage( + const ::rtl::OUString& rContainerStorageName, + const ::rtl::OUString& rObjectStorageName, + sal_Bool bUCBStorage ); + String ImplGetUniqueName( SvStorage* pStg, + const sal_Char* p ) const; + sal_Bool ImplReadObject( + const ::rtl::OUString& rContainerStorageName, + const ::rtl::OUString& rObjName, + const SvGlobalName *pClassId ); + sal_Bool ImplWriteObject( + const ::rtl::OUString& rContainerStorageName, + const ::rtl::OUString& rObjName ); + ::rtl::OUString ImplInsertEmbeddedObjectURL( + const ::rtl::OUString& rURLStr ); + +protected: + + SvXMLEmbeddedObjectHelper(); + ~SvXMLEmbeddedObjectHelper(); + void Init( SvStorage& rRootStorage, + SvPersist& rDocPersist, + SvXMLEmbeddedObjectHelperMode eCreateMode, + sal_Bool bDirect ); + +public: + + static SvXMLEmbeddedObjectHelper* Create( + SvStorage& rRootStorage, + SvPersist& rDocPersist, + SvXMLEmbeddedObjectHelperMode eCreateMode, + sal_Bool bDirect = sal_True ); + static void Destroy( SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper ); + + void Flush(); + + // XEmbeddedObjectResolver + virtual ::rtl::OUString SAL_CALL resolveEmbeddedObjectURL( const ::rtl::OUString& aURL ) throw(::com::sun::star::uno::RuntimeException); +}; + +#endif diff --git a/svx/prj/d.lst b/svx/prj/d.lst index 3b25fa0eabb6..9f3c22e44fe4 100644 --- a/svx/prj/d.lst +++ b/svx/prj/d.lst @@ -561,6 +561,7 @@ hedabu: ..\inc\scriptspaceitem.hxx %_DEST%\inc%_EXT%\svx\scriptspaceitem.hxx hedabu: ..\inc\hngpnctitem.hxx %_DEST%\inc%_EXT%\svx\hngpnctitem.hxx hedabu: ..\inc\forbiddenruleitem.hxx %_DEST%\inc%_EXT%\svx\forbiddenruleitem.hxx hedabu: ..\inc\xmlgrhlp.hxx %_DEST%\inc%_EXT%\svx\xmlgrhlp.hxx +hedabu: ..\inc\xmleohlp.hxx %_DEST%\inc%_EXT%\svx\xmleohlp.hxx ..\xml\SvxDrawPage.xml %_DEST%\xml%_EXT%\SvxDrawPage.xml ..\xml\SvxGraphicObject.xml %_DEST%\xml%_EXT%\SvxGraphicObject.xml diff --git a/svx/source/xml/makefile.mk b/svx/source/xml/makefile.mk index 8732bf56adec..675792414305 100644 --- a/svx/source/xml/makefile.mk +++ b/svx/source/xml/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.1 $ +# $Revision: 1.2 $ # -# last change: $Author: ka $ $Date: 2000-11-30 07:32:41 $ +# last change: $Author: mib $ $Date: 2001-01-26 11:22:09 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -71,10 +71,12 @@ TARGET=xml # --- Files -------------------------------------------------------- SLOFILES = \ - $(SLO)$/xmlgrhlp.obj + $(SLO)$/xmlgrhlp.obj \ + $(SLO)$/xmleohlp.obj EXCEPTIONSFILES = \ - $(SLO)$/xmlgrhlp.obj + $(SLO)$/xmlgrhlp.obj \ + $(SLO)$/xmleohlp.obj # --- Targets -------------------------------------------------------------- diff --git a/svx/source/xml/xmleohlp.cxx b/svx/source/xml/xmleohlp.cxx new file mode 100644 index 000000000000..b93c943f063f --- /dev/null +++ b/svx/source/xml/xmleohlp.cxx @@ -0,0 +1,577 @@ +/************************************************************************* + * + * $RCSfile: xmleohlp.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: mib $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdio.h> + +#ifndef _DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _SO_CLSIDS_HXX +#include <so3/clsids.hxx> +#endif +#ifndef _PERSIST_HXX +#include <so3/persist.hxx> +#endif +#ifndef _EMBOBJ_HXX +#include <so3/embobj.hxx> +#endif + +#ifndef _XMLEOHLP_HXX +#include "xmleohlp.hxx" +#endif + +// ----------- +// - Defines - +// ----------- + +using namespace ::rtl; +using namespace ::osl; +using namespace ::cppu; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::uno; + +#define XML_CONTAINERSTORAGE_NAME "Objects" +#define XML_EMBEDDEDOBJECT_URL_BASE "vnd.sun.star.EmbeddedObject:" + +#define EO_FLAG_STAR_OBJECT 0x0001 +#define EO_FLAG_UCB_STORAGE 0x0002 +#define EO_FLAG_NEEDS_CONVERSION 0x0004 + +struct ClassNameInfo +{ + struct GUIDDummy + { + sal_uInt32 n1; + sal_uInt16 n2, n3; + sal_uInt8 n4, n5, n6, n7, n8, n9, n10, n11; + } aGUID; + sal_uInt16 nFlags; +}; + +typedef SvGlobalName *SvGlobalNamePtr; + +static ClassNameInfo aFlagsMap[] = +{ + { SO3_SM_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SCH_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SIM_CLASSID_50 , EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SDRAW_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SIMPRESS_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SC_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SW_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SWWEB_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SWGLOB_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + + { SO3_SM_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SCH_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SIM_CLASSID_40 , EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SIMPRESS_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SC_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SW_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SWWEB_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SWGLOB_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + + { SO3_SM_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SCH_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SIM_CLASSID_30 , EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SIMPRESS_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SC_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }, + { SO3_SW_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION } +}; + +// ----------------------------- +// - SvXMLEmbeddedObjectHelper - +// ----------------------------- + +SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper() : + WeakComponentImplHelper1< XEmbeddedObjectResolver >( maMutex ), + maDefaultContainerStorageName( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME) ), + mpRootStorage( 0 ), + mpDocPersist( 0 ), + mpGlobalNameMap( 0 ), + meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ) +{ +} + +// ----------------------------------------------------------------------------- + +SvXMLEmbeddedObjectHelper::~SvXMLEmbeddedObjectHelper() +{ + if( mpGlobalNameMap ) + { + size_t nCount = sizeof(aFlagsMap)/sizeof(ClassNameInfo); + SvGlobalNamePtr *p = mpGlobalNameMap; + while( nCount-- ) + delete *p++; + + delete mpGlobalNameMap; + } +} + +// ----------------------------------------------------------------------------- + +sal_Bool SvXMLEmbeddedObjectHelper::ImplGetStorageNames( + const OUString& rURLStr, + OUString& rContainerStorageName, + OUString& rObjectStorageName, + sal_Bool bInternalToExternal ) const +{ + // internal URL: vnd.sun.star.EmbeddedObject:<object-name> + // or: vnd.sun.star.EmbeddedObject:<path>/<object-name> + // external URL: #./<path>/<object-name> + // or: #<path>/<object-name> + // or: #<object-name> + // currently, path may only consist of a single directory name + sal_Bool bRet = sal_False; + + if( !rURLStr.getLength() ) + return sal_False; + + if( bInternalToExternal ) + { + sal_Int32 nPos = rURLStr.indexOf( ':' ); + if( -1 == nPos || + 0 != rURLStr.compareToAscii( XML_EMBEDDEDOBJECT_URL_BASE, + sizeof( XML_EMBEDDEDOBJECT_URL_BASE ) -1 ) ) + return sal_False; + + sal_Int32 nPathStart = nPos + 1; + nPos = rURLStr.lastIndexOf( '/' ); + if( -1 == nPos ) + { + rContainerStorageName = maDefaultContainerStorageName; + rObjectStorageName = rURLStr.copy( nPathStart ); + } + else if( nPos > nPathStart ) + { + rContainerStorageName = rURLStr.copy( nPathStart, nPos-nPathStart); + rObjectStorageName = rURLStr.copy( nPos+1 ); + } + else + return sal_False; + } + else + { + if( '#' != rURLStr[0 ] ) + return sal_False; + + sal_Int32 nPos = rURLStr.lastIndexOf( '/' ); + if( -1 == nPos ) + { + rContainerStorageName = OUString(); + rObjectStorageName = rURLStr.copy( 1 ); + } + else + { + sal_Int32 nPathStart = 1; + if( 0 == rURLStr.compareToAscii( "#./", 3 ) ) + nPathStart = 3; + rContainerStorageName = rURLStr.copy( nPathStart, nPos-nPathStart); + rObjectStorageName = rURLStr.copy( nPos+1 ); + } + } + + if( -1 != rContainerStorageName.indexOf( '/' ) ) + { + DBG_ERROR( "SvXMLEmbeddedObjectHelper: invalid path name" ); + return sal_False; + } + + return sal_True; +} + + +// ----------------------------------------------------------------------------- + +sal_uInt16 SvXMLEmbeddedObjectHelper::ImplGetFlags( + const SvGlobalName& rClassId ) const +{ + size_t nCount = sizeof(aFlagsMap)/sizeof(ClassNameInfo); + + if( !mpGlobalNameMap ) + { + ((SvXMLEmbeddedObjectHelper *)this)->mpGlobalNameMap = + new SvGlobalNamePtr[nCount]; + size_t i = nCount; + SvGlobalNamePtr *p = (SvGlobalNamePtr *)mpGlobalNameMap; + while( i-- ) + *p++ = 0; + } + + sal_uInt16 nFlags = 0; + SvGlobalNamePtr *pNames = (SvGlobalNamePtr *)mpGlobalNameMap; + const ClassNameInfo *pInfo = aFlagsMap; + while( nCount-- ) + { + if( !*pNames ) + *pNames = new SvGlobalName( pInfo->aGUID.n1, pInfo->aGUID.n2, + pInfo->aGUID.n3, pInfo->aGUID.n4, + pInfo->aGUID.n5, pInfo->aGUID.n6, + pInfo->aGUID.n7, pInfo->aGUID.n8, + pInfo->aGUID.n9, pInfo->aGUID.n10, + pInfo->aGUID.n11 ); + if( **pNames == rClassId ) + { + nFlags = pInfo->nFlags; + break; + } + pNames++; + pInfo++; + } + + return nFlags; +} + +SvStorageRef SvXMLEmbeddedObjectHelper::ImplGetContainerStorage( + const OUString& rStorageName ) +{ + DBG_ASSERT( -1 == rStorageName.indexOf( '/' ) && + -1 == rStorageName.indexOf( '\\' ), + "nested embedded storages aren't supported" ); + if( !mxContainerStorage.Is() || + ( rStorageName != maCurContainerStorageName ) ) + { + if( mxContainerStorage.Is() && + EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) + mxContainerStorage->Commit(); + + StreamMode eMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode + ? STREAM_STD_READWRITE + : STREAM_STD_READ; + mxContainerStorage = mpRootStorage->OpenUCBStorage( rStorageName, + eMode ); + maCurContainerStorageName = rStorageName; + } + + return mxContainerStorage; +} + +// ----------------------------------------------------------------------------- + +SvStorageRef SvXMLEmbeddedObjectHelper::ImplGetObjectStorage( + const OUString& rContainerStorageName, + const OUString& rObjectStorageName, + sal_Bool bUCBStorage ) +{ + SvStorageRef xObjStor; + SvStorageRef xCntnrStor( ImplGetContainerStorage( rContainerStorageName ) ); + if( xCntnrStor.Is() ) + { + StreamMode eMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode + ? STREAM_STD_READWRITE + : STREAM_STD_READ; + if( bUCBStorage ) + xObjStor = xCntnrStor->OpenUCBStorage( rObjectStorageName, eMode ); + else + xObjStor = xCntnrStor->OpenStorage( rObjectStorageName, eMode ); + } + + return xObjStor; +} + +// ----------------------------------------------------------------------------- + +String SvXMLEmbeddedObjectHelper::ImplGetUniqueName( SvStorage* pStg, + const sal_Char* p ) const +{ + String aName; + sal_Char cBuf[ 32 ]; + + static ULONG nId = (ULONG) cBuf; + + nId++; + for( ;; ) + { + sprintf( cBuf, "%s%08lX", p, nId ); + aName.AssignAscii( cBuf ); + if( !pStg->IsContained( aName ) ) + break; + nId++; + } + return aName; +} + +sal_Bool SvXMLEmbeddedObjectHelper::ImplReadObject( + const OUString& rContainerStorageName, + const OUString& rObjName, + const SvGlobalName *pClassId ) +{ + SvStorageRef xDocStor( mpDocPersist->GetStorage() ); + + String aObjName( rObjName ); + String aSrcObjName( aObjName ); + + // Is the object name unique? + if( mpDocPersist->GetObjectList() ) + { + sal_uInt32 nCount = mpDocPersist->GetObjectList()->Count(); + for( sal_uInt32 i = 0; i < nCount; i++ ) + { + SvInfoObject* pTst = mpDocPersist->GetObjectList()->GetObject(i); + // TODO: unicode: is this correct? + if( aObjName.EqualsIgnoreCaseAscii( pTst->GetObjName() ) || + aObjName.EqualsIgnoreCaseAscii( pTst->GetStorageName() ) ) + { + aObjName = ImplGetUniqueName( xDocStor, "Obj" ); + break; + } + } + } + + SvStorageRef xCntnrStor( ImplGetContainerStorage( + rContainerStorageName ) ); + if( !xCntnrStor.Is() ) + return sal_False; + + if( !xCntnrStor->CopyTo( aSrcObjName, xDocStor, aObjName ) ) + return sal_False; + + SvGlobalName aClassId; + if( pClassId ) + { + aClassId = *pClassId; + } + else + { + SvStorageRef xObjStor( ImplGetObjectStorage( rContainerStorageName, + aSrcObjName, sal_False ) ); + aClassId = xObjStor->GetClassName(); + } + + SvInfoObjectRef xInfo = new SvEmbeddedInfoObject( aObjName, aClassId ); + mpDocPersist->Insert( xInfo ); + + return sal_True; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SvXMLEmbeddedObjectHelper::ImplWriteObject( + const OUString& rContainerStorageName, + const OUString& rObjName ) +{ + SvInfoObject *pInfo = mpDocPersist->Find( rObjName ); + DBG_ASSERT( pInfo, "OLE object not found" ); + + if( !pInfo ) + return sal_False; + + // Get object type + sal_uInt16 nFlags = ImplGetFlags( pInfo->GetClassName() ); + + // If the objects needs a conversion it has to be loaded and stored + // again later. The same would apply if the save into an old format. + if( (nFlags & EO_FLAG_NEEDS_CONVERSION) != 0 ) + mpDocPersist->GetObject( rObjName ); + + + if( pInfo->GetPersist() ) + { + // The object is loaded either because it is stored within the + // wrong file format or it has been modified + // Create either an UCB or an OLE storage, based on object's type + SvStorageRef xObjStor( ImplGetObjectStorage( + rContainerStorageName, + rObjName, + (nFlags&EO_FLAG_UCB_STORAGE) != 0 ) ); + if( !xObjStor.Is() ) + return sal_False; + + // Save file (again) + xObjStor->SetVersion( mpRootStorage->GetVersion() ); + if( !pInfo->GetPersist()->DoSaveAs( xObjStor ) ) + return sal_False; + + // Commit changes + if( !xObjStor->Commit() ) + return sal_False; + } + else + { + SvStorageRef xCntnrStor( ImplGetContainerStorage( + rContainerStorageName ) ); + if( !xCntnrStor.Is() ) + return sal_False; + + if( !mpDocPersist->GetStorage()->CopyTo( pInfo->GetStorageName(), + xCntnrStor, rObjName ) ) + return sal_False; + } + + return sal_True; +} + +// ----------------------------------------------------------------------------- + +OUString SvXMLEmbeddedObjectHelper::ImplInsertEmbeddedObjectURL( + const OUString& rURLStr ) +{ + OUString sRetURL; + + OUString aContainerStorageName, aObjectStorageName; + if( !ImplGetStorageNames( rURLStr, aContainerStorageName, + aObjectStorageName, + EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) ) + return sRetURL; + + if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode ) + { + SvGlobalName aClassId, *pClassId = 0; + sal_Int32 nPos = aObjectStorageName.lastIndexOf( '!' ); + if( -1 != nPos && aClassId.MakeId( aObjectStorageName.copy( nPos+1 ) ) ) + { + aObjectStorageName = aObjectStorageName.copy( 0, nPos ); + pClassId = &aClassId; + } + ImplReadObject( aContainerStorageName, aObjectStorageName, pClassId ); + sRetURL = OUString( RTL_CONSTASCII_USTRINGPARAM(XML_EMBEDDEDOBJECT_URL_BASE ) ); + sRetURL += aObjectStorageName; + } + else + { + if( mbDirect ) + ImplWriteObject( aContainerStorageName, aObjectStorageName ); + else + maEmbeddedObjectURLs.push_back( rURLStr ); + sRetURL = OUString( RTL_CONSTASCII_USTRINGPARAM("#./") ); + sRetURL += aContainerStorageName; + sRetURL += OUString( '/' ); + sRetURL += aObjectStorageName; + } + + return sRetURL; +} + +// ----------------------------------------------------------------------------- + +void SvXMLEmbeddedObjectHelper::Init( + SvStorage& rRootStorage, + SvPersist& rPersist, + SvXMLEmbeddedObjectHelperMode eCreateMode, + sal_Bool bDirect ) +{ + mpRootStorage = &rRootStorage; + mpDocPersist = &rPersist; + meCreateMode = eCreateMode; + mbDirect = bDirect; +} + +// ----------------------------------------------------------------------------- + +SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create( + SvStorage& rRootStorage, + SvPersist& rDocPersist, + SvXMLEmbeddedObjectHelperMode eCreateMode, + sal_Bool bDirect ) +{ + SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper; + + pThis->acquire(); + pThis->Init( rRootStorage, rDocPersist, eCreateMode, bDirect ); + + return pThis; +} + +// ----------------------------------------------------------------------------- + +void SvXMLEmbeddedObjectHelper::Destroy( + SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper ) +{ + if( pSvXMLEmbeddedObjectHelper ) + { + pSvXMLEmbeddedObjectHelper->Flush(); + pSvXMLEmbeddedObjectHelper->release(); + } +} + +// ----------------------------------------------------------------------------- + +void SvXMLEmbeddedObjectHelper::Flush() +{ + if( ( EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) && !mbDirect ) + { + OUString aContainerStorageName, aObjectStorageName; + URLVector::iterator aIter( maEmbeddedObjectURLs.begin() ); + URLVector::iterator aEnd( maEmbeddedObjectURLs.end() ); + + while( aIter != aEnd ) + { + if( ImplGetStorageNames( *aIter, aContainerStorageName, + aObjectStorageName, sal_True ) ) + ImplWriteObject( aContainerStorageName, aObjectStorageName ); + aIter++; + } + } + + if( EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode && + mxContainerStorage.Is() ) + mxContainerStorage->Commit(); +} + +// XGraphicObjectResolver +OUString SAL_CALL SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL( const OUString& aURL ) + throw(RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + return ImplInsertEmbeddedObjectURL( aURL ); +} |