1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ed_ipersiststr.cxx,v $
10 * $Revision: 1.27.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #if defined(_MSC_VER) && (_MSC_VER > 1310)
31 #pragma warning(disable : 4917 4555)
34 #include "embeddoc.hxx"
35 #include <com/sun/star/uno/Any.h>
36 #include <com/sun/star/uno/Exception.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/lang/XComponent.hpp>
39 #include <com/sun/star/io/XInputStream.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/io/XSeekable.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
43 #include <com/sun/star/frame/XLoadable.hpp>
44 #include <com/sun/star/util/XModifiable.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
46 #include <com/sun/star/frame/XComponentLoader.hpp>
47 #include <com/sun/star/util/XUrlTransformer.hpp>
50 #include <osl/mutex.hxx>
51 #include <osl/diagnose.h>
55 #define EXT_STREAM_LENGTH 16
57 using namespace ::com::sun::star
;
59 extern ::rtl::OUString
getStorageTypeFromGUID_Impl( GUID
* guid
);
60 extern ::rtl::OUString
getServiceNameFromGUID_Impl( GUID
* );
61 extern ::rtl::OUString
getFilterNameFromGUID_Impl( GUID
* );
62 // extern CLIPFORMAT getClipFormatFromGUID_Impl( GUID* );
63 ::rtl::OUString
getTestFileURLFromGUID_Impl( GUID
* guid
);
65 const ::rtl::OUString
aOfficeEmbedStreamName( RTL_CONSTASCII_USTRINGPARAM ( "package_stream" ) );
66 const ::rtl::OUString
aExtentStreamName( RTL_CONSTASCII_USTRINGPARAM ( "properties_stream" ) );
68 uno::Reference
< io::XInputStream
> createTempXInStreamFromIStream(
69 uno::Reference
< lang::XMultiServiceFactory
> xFactory
,
72 uno::Reference
< io::XInputStream
> xResult
;
77 const ::rtl::OUString
aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
78 uno::Reference
< io::XOutputStream
> xTempOut
= uno::Reference
< io::XOutputStream
> (
79 xFactory
->createInstance ( aServiceName
),
83 ULARGE_INTEGER nNewPos
;
84 LARGE_INTEGER aZero
= { 0L, 0L };
85 HRESULT hr
= pStream
->Seek( aZero
, STREAM_SEEK_SET
, &nNewPos
);
86 if ( FAILED( hr
) ) return xResult
;
89 hr
= pStream
->Stat( &aStat
, STATFLAG_NONAME
);
90 if ( FAILED( hr
) ) return xResult
;
92 sal_uInt32 nSize
= (sal_uInt32
)aStat
.cbSize
.QuadPart
;
93 sal_uInt32 nCopied
= 0;
94 uno::Sequence
< sal_Int8
> aBuffer( nConstBufferSize
);
100 pStream
->Read( (void*)aBuffer
.getArray(), nConstBufferSize
, &nRead
);
102 if ( nRead
< nConstBufferSize
)
103 aBuffer
.realloc( nRead
);
105 xTempOut
->writeBytes( aBuffer
);
107 } while( nRead
== nConstBufferSize
);
109 if ( nCopied
== nSize
)
111 uno::Reference
< io::XSeekable
> xTempSeek ( xTempOut
, uno::UNO_QUERY
);
112 if ( xTempSeek
.is() )
114 xTempSeek
->seek ( 0 );
115 xResult
= uno::Reference
< io::XInputStream
>( xTempOut
, uno::UNO_QUERY
);
119 catch( uno::Exception
& )
127 HRESULT
copyXTempOutToIStream( uno::Reference
< io::XOutputStream
> xTempOut
, IStream
* pStream
)
129 if ( !xTempOut
.is() || !pStream
)
132 uno::Reference
< io::XSeekable
> xTempSeek ( xTempOut
, uno::UNO_QUERY
);
133 if ( !xTempSeek
.is() )
136 xTempSeek
->seek ( 0 );
138 uno::Reference
< io::XInputStream
> xTempIn ( xTempOut
, uno::UNO_QUERY
);
139 if ( !xTempSeek
.is() )
142 // Seek to zero and truncate the stream
143 ULARGE_INTEGER nNewPos
;
144 LARGE_INTEGER aZero
= { 0L, 0L };
145 HRESULT hr
= pStream
->Seek( aZero
, STREAM_SEEK_SET
, &nNewPos
);
146 if ( FAILED( hr
) ) return E_FAIL
;
147 ULARGE_INTEGER aUZero
= { 0L, 0L };
148 hr
= pStream
->SetSize( aUZero
);
149 if ( FAILED( hr
) ) return E_FAIL
;
151 uno::Sequence
< sal_Int8
> aBuffer( nConstBufferSize
);
152 sal_uInt32 nReadBytes
= 0;
157 nReadBytes
= xTempIn
->readBytes( aBuffer
, nConstBufferSize
);
159 catch( uno::Exception
& )
164 sal_uInt32 nWritten
= 0;
165 HRESULT hr
= pStream
->Write( (void*)aBuffer
.getArray(), nReadBytes
, &nWritten
);
166 if ( !SUCCEEDED( hr
) || nWritten
!= nReadBytes
)
169 } while( nReadBytes
== nConstBufferSize
);
175 //===============================================================================
176 // EmbedDocument_Impl
177 //===============================================================================
179 EmbedDocument_Impl::EmbedDocument_Impl( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
, const GUID
* guid
)
181 , m_xFactory( xFactory
)
183 , m_bIsDirty( sal_False
)
185 , m_bIsInVerbHandling( sal_False
)
186 //, m_bLoadedFromFile( sal_False )
188 m_xOwnAccess
= new EmbeddedDocumentInstanceAccess_Impl( this );
189 m_pDocHolder
= new DocumentHolder( xFactory
, m_xOwnAccess
);
190 m_pDocHolder
->acquire();
193 EmbedDocument_Impl::~EmbedDocument_Impl()
195 m_pDocHolder
->FreeOffice();
197 if ( m_pDocHolder
->HasFrame() && m_pDocHolder
->IsLink() )
199 // a link with frame should be only disconnected, not closed
200 m_pDocHolder
->DisconnectFrameDocument( sal_True
);
204 m_pDocHolder
->CloseDocument();
205 m_pDocHolder
->CloseFrame();
208 m_pDocHolder
->release();
211 uno::Sequence
< beans::PropertyValue
> EmbedDocument_Impl::fillArgsForLoading_Impl( uno::Reference
< io::XInputStream
> xStream
, DWORD
/*nStreamMode*/, LPCOLESTR pFilePath
)
213 uno::Sequence
< beans::PropertyValue
> aArgs( 3 );
215 sal_Int32 nInd
= 0; // must not be bigger than the preset size
216 aArgs
[nInd
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "FilterName" ) );
217 aArgs
[nInd
++].Value
<<= getFilterNameFromGUID_Impl( &m_guid
);
221 aArgs
[nInd
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "InputStream" ) );
222 aArgs
[nInd
++].Value
<<= xStream
;
223 aArgs
[nInd
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "URL" ) );
224 aArgs
[nInd
++].Value
<<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "private:stream" ) );
228 aArgs
[nInd
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "URL" ) );
230 rtl::OUString sDocUrl
;
233 ::rtl::OUString
aServiceName( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.util.URLTransformer" ) );
234 uno::Reference
< util::XURLTransformer
> aTransformer( m_xFactory
->createInstance( aServiceName
),
236 if ( aTransformer
.is() )
240 aURL
.Complete
= ::rtl::OUString( reinterpret_cast<const sal_Unicode
*>(pFilePath
) );
242 if ( aTransformer
->parseSmart( aURL
, ::rtl::OUString() ) )
243 sDocUrl
= aURL
.Complete
;
247 aArgs
[nInd
++].Value
<<= sDocUrl
;
250 aArgs
.realloc( nInd
);
252 // aArgs[].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ReadOnly" ) );
253 // aArgs[].Value <<= sal_False; //( ( nStreamMode & ( STGM_READWRITE | STGM_WRITE ) ) ? sal_True : sal_False );
258 uno::Sequence
< beans::PropertyValue
> EmbedDocument_Impl::fillArgsForStoring_Impl( uno::Reference
< io::XOutputStream
> xStream
)
260 uno::Sequence
< beans::PropertyValue
> aArgs( xStream
.is() ? 2 : 1 );
262 aArgs
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "FilterName" ) );
263 aArgs
[0].Value
<<= getFilterNameFromGUID_Impl( &m_guid
);
267 aArgs
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "OutputStream" ) );
268 aArgs
[1].Value
<<= xStream
;
274 HRESULT
EmbedDocument_Impl::SaveTo_Impl( IStorage
* pStg
)
276 if ( !pStg
|| pStg
== m_pMasterStorage
)
279 // for saveto operation the master storage
280 // should not enter NoScribble mode
281 CComPtr
< IStream
> pOrigOwn
= m_pOwnStream
;
282 CComPtr
< IStream
> pOrigExt
= m_pExtStream
;
283 HRESULT hr
= Save( pStg
, sal_False
);
284 pStg
->Commit( STGC_ONLYIFCURRENT
);
285 m_pOwnStream
= pOrigOwn
;
286 m_pExtStream
= pOrigExt
;
291 //-------------------------------------------------------------------------------
294 STDMETHODIMP
EmbedDocument_Impl::QueryInterface( REFIID riid
, void FAR
* FAR
* ppv
)
296 if(IsEqualIID(riid
, IID_IUnknown
))
299 *ppv
= (IUnknown
*) (IPersistStorage
*) this;
302 else if (IsEqualIID(riid
, IID_IPersist
))
305 *ppv
= (IPersist
*) (IPersistStorage
*) this;
308 else if (IsEqualIID(riid
, IID_IExternalConnection
))
311 *ppv
= (IExternalConnection
*) this;
314 else if (IsEqualIID(riid
, IID_IPersistStorage
))
317 *ppv
= (IPersistStorage
*) this;
320 else if (IsEqualIID(riid
, IID_IDataObject
))
323 *ppv
= (IDataObject
*) this;
326 else if (IsEqualIID(riid
, IID_IOleObject
))
329 *ppv
= (IOleObject
*) this;
332 else if (IsEqualIID(riid
, IID_IOleWindow
))
335 *ppv
= (IOleWindow
*) this;
338 else if (IsEqualIID(riid
, IID_IOleInPlaceObject
))
341 *ppv
= (IOleInPlaceObject
*) this;
344 else if (IsEqualIID(riid
, IID_IPersistFile
))
347 *ppv
= (IPersistFile
*) this;
350 else if (IsEqualIID(riid
, IID_IDispatch
))
353 *ppv
= (IDispatch
*) this;
358 return ResultFromScode(E_NOINTERFACE
);
361 STDMETHODIMP_(ULONG
) EmbedDocument_Impl::AddRef()
363 return osl_incrementInterlockedCount( &m_refCount
);
366 STDMETHODIMP_(ULONG
) EmbedDocument_Impl::Release()
368 // if there is a time when the last reference is destructed, that means that only internal pointers are alive
369 // after the following call either the refcount is increased or the pointers are empty
370 if ( m_refCount
== 1 )
371 m_xOwnAccess
->ClearEmbedDocument();
373 sal_Int32 nCount
= osl_decrementInterlockedCount( &m_refCount
);
379 //-------------------------------------------------------------------------------
382 STDMETHODIMP
EmbedDocument_Impl::GetClassID( CLSID
* pClassId
)
384 *pClassId
= *&m_guid
;
388 //-------------------------------------------------------------------------------
391 STDMETHODIMP
EmbedDocument_Impl::IsDirty()
393 // the link modified state is controlled by the document
394 if ( m_bIsDirty
&& !m_aFileName
.getLength() )
397 uno::Reference
< util::XModifiable
> xMod( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
399 return xMod
->isModified() ? S_OK
: S_FALSE
;
403 STDMETHODIMP
EmbedDocument_Impl::InitNew( IStorage
*pStg
)
405 HRESULT hr
= CO_E_ALREADYINITIALIZED
;
407 if ( !m_pDocHolder
->GetDocument().is() )
411 hr
= pStg
->Stat( &aStat
, STATFLAG_NONAME
);
412 if ( FAILED( hr
) ) return E_FAIL
;
414 DWORD nStreamMode
= aStat
.grfMode
;
417 if ( m_xFactory
.is() && pStg
)
419 uno::Reference
< frame::XModel
> aDocument(
420 m_xFactory
->createInstance( getServiceNameFromGUID_Impl( &m_guid
) ),
422 if ( aDocument
.is() )
424 m_pDocHolder
->SetDocument( aDocument
);
426 uno::Reference
< frame::XLoadable
> xLoadable( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
431 xLoadable
->initNew();
432 // xLoadable->load( fillArgsForLoading_Impl( uno::Reference< io::XInputStream >(), nStreamMode ) );
435 catch( uno::Exception
& )
442 ::rtl::OUString aCurType
= getStorageTypeFromGUID_Impl( &m_guid
); // ???
443 CLIPFORMAT cf
= (CLIPFORMAT
)RegisterClipboardFormatA( "Embedded Object" );
444 hr
= WriteFmtUserTypeStg( pStg
,
446 reinterpret_cast<LPWSTR
>(( sal_Unicode
* )aCurType
.getStr()) );
450 hr
= pStg
->CreateStream( reinterpret_cast<LPCWSTR
>(aOfficeEmbedStreamName
.getStr()),
451 STGM_CREATE
| ( nStreamMode
& 0x73 ),
456 if ( hr
== S_OK
&& m_pOwnStream
)
458 hr
= pStg
->CreateStream( reinterpret_cast<LPCWSTR
>(aExtentStreamName
.getStr()),
459 STGM_CREATE
| ( nStreamMode
& 0x73 ),
464 if ( hr
== S_OK
&& m_pExtStream
)
467 m_pMasterStorage
= pStg
;
468 m_bIsDirty
= sal_True
;
481 m_pDocHolder
->CloseDocument();
489 STDMETHODIMP
EmbedDocument_Impl::Load( IStorage
*pStg
)
491 if ( m_pDocHolder
->GetDocument().is() )
492 return CO_E_ALREADYINITIALIZED
;
494 if ( !m_xFactory
.is() || !pStg
)
500 hr
= pStg
->Stat( &aStat
, STATFLAG_NONAME
);
501 if ( FAILED( hr
) ) return E_FAIL
;
503 DWORD nStreamMode
= aStat
.grfMode
;
504 hr
= pStg
->OpenStream( reinterpret_cast<LPCWSTR
>(aOfficeEmbedStreamName
.getStr()),
509 if ( !m_pOwnStream
) hr
= E_FAIL
;
511 if ( SUCCEEDED( hr
) )
513 hr
= pStg
->OpenStream( reinterpret_cast<LPCWSTR
>(aExtentStreamName
.getStr()),
518 if ( !m_pExtStream
) hr
= E_FAIL
;
523 if ( SUCCEEDED( hr
) )
525 ULARGE_INTEGER nNewPos
;
526 LARGE_INTEGER aZero
= { 0L, 0L };
527 hr
= m_pExtStream
->Seek( aZero
, STREAM_SEEK_SET
, &nNewPos
);
528 if ( SUCCEEDED( hr
) )
531 sal_Int8 aInf
[EXT_STREAM_LENGTH
];
532 hr
= m_pExtStream
->Read( (void*)aInf
, EXT_STREAM_LENGTH
, &nRead
);
533 if ( nRead
!= EXT_STREAM_LENGTH
) hr
= E_FAIL
;
535 if ( SUCCEEDED( hr
) )
537 // aRectToSet.left = *((sal_Int32*)aInf);
538 // aRectToSet.top = *((sal_Int32*)&aInf[4]);
539 // aRectToSet.right = *((sal_Int32*)&aInf[8]);
540 // aRectToSet.bottom = *((sal_Int32*)&aInf[12]);
541 aSizeToSet
.cx
= *((sal_Int32
*)&aInf
[8]) - *((sal_Int32
*)aInf
);
542 aSizeToSet
.cy
= *((sal_Int32
*)&aInf
[12]) - *((sal_Int32
*)&aInf
[4]);
547 if ( SUCCEEDED( hr
) )
551 uno::Reference
< io::XInputStream
> xTempIn
= createTempXInStreamFromIStream( m_xFactory
, m_pOwnStream
);
554 uno::Reference
< frame::XModel
> aDocument(
555 m_xFactory
->createInstance( getServiceNameFromGUID_Impl( &m_guid
) ),
557 if ( aDocument
.is() )
559 m_pDocHolder
->SetDocument( aDocument
);
561 uno::Reference
< frame::XLoadable
> xLoadable( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
566 xLoadable
->load( fillArgsForLoading_Impl( xTempIn
, nStreamMode
) );
567 m_pMasterStorage
= pStg
;
568 hr
= m_pDocHolder
->SetExtent( &aSizeToSet
);
569 // hr = m_pDocHolder->SetVisArea( &aRectToSet );
571 catch( uno::Exception
& )
577 m_pDocHolder
->CloseDocument();
584 m_pOwnStream
= CComPtr
< IStream
>();
585 m_pExtStream
= CComPtr
< IStream
>();
586 hr
= pStg
->DestroyElement( reinterpret_cast<LPCWSTR
>(aOfficeEmbedStreamName
.getStr()) );
587 hr
= pStg
->DestroyElement( reinterpret_cast<LPCWSTR
>(aExtentStreamName
.getStr()) );
589 OSL_ENSURE( SUCCEEDED( hr
), "Can not destroy created stream!\n" );
597 STDMETHODIMP
EmbedDocument_Impl::Save( IStorage
*pStgSave
, BOOL fSameAsLoad
)
599 if ( !m_pDocHolder
->GetDocument().is() || !m_xFactory
.is() || !pStgSave
|| !m_pOwnStream
|| !m_pExtStream
)
602 CComPtr
< IStream
> pTargetStream
;
603 CComPtr
< IStream
> pNewExtStream
;
605 if ( !fSameAsLoad
&& pStgSave
!= m_pMasterStorage
)
607 OSL_ENSURE( m_pMasterStorage
, "How could the document be initialized without storage!??\n" );
608 HRESULT hr
= m_pMasterStorage
->CopyTo( NULL
, NULL
, NULL
, pStgSave
);
609 if ( FAILED( hr
) ) return E_FAIL
;
612 hr
= pStgSave
->Stat( &aStat
, STATFLAG_NONAME
);
613 if ( FAILED( hr
) ) return E_FAIL
;
615 DWORD nStreamMode
= aStat
.grfMode
;
616 hr
= pStgSave
->CreateStream( reinterpret_cast<LPCWSTR
>(aOfficeEmbedStreamName
.getStr()),
617 STGM_CREATE
| ( nStreamMode
& 0x73 ),
621 if ( FAILED( hr
) || !pTargetStream
) return E_FAIL
;
623 hr
= pStgSave
->CreateStream( reinterpret_cast<LPCWSTR
>(aExtentStreamName
.getStr()),
624 STGM_CREATE
| ( nStreamMode
& 0x73 ),
628 if ( FAILED( hr
) || !pNewExtStream
) return E_FAIL
;
632 pTargetStream
= m_pOwnStream
;
633 pNewExtStream
= m_pExtStream
;
638 const ::rtl::OUString
aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
639 uno::Reference
< io::XOutputStream
> xTempOut
= uno::Reference
< io::XOutputStream
> (
640 m_xFactory
->createInstance ( aServiceName
),
645 uno::Reference
< frame::XStorable
> xStorable( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
650 xStorable
->storeToURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "private:stream" ) ),
651 fillArgsForStoring_Impl( xTempOut
) );
652 hr
= copyXTempOutToIStream( xTempOut
, pTargetStream
);
653 if ( SUCCEEDED( hr
) )
655 // no need to truncate the stream, the size of the stream is always the same
656 ULARGE_INTEGER nNewPos
;
657 LARGE_INTEGER aZero
= { 0L, 0L };
658 hr
= pNewExtStream
->Seek( aZero
, STREAM_SEEK_SET
, &nNewPos
);
659 if ( SUCCEEDED( hr
) )
662 hr
= m_pDocHolder
->GetExtent( &aSize
);
664 if ( SUCCEEDED( hr
) )
667 sal_Int8 aInf
[EXT_STREAM_LENGTH
];
668 *((sal_Int32
*)aInf
) = 0;
669 *((sal_Int32
*)&aInf
[4]) = 0;
670 *((sal_Int32
*)&aInf
[8]) = aSize
.cx
;
671 *((sal_Int32
*)&aInf
[12]) = aSize
.cy
;
673 hr
= pNewExtStream
->Write( (void*)aInf
, EXT_STREAM_LENGTH
, &nWritten
);
674 if ( nWritten
!= EXT_STREAM_LENGTH
) hr
= E_FAIL
;
676 if ( SUCCEEDED( hr
) )
678 m_pOwnStream
= CComPtr
< IStream
>();
679 m_pExtStream
= CComPtr
< IStream
>();
680 if ( fSameAsLoad
|| pStgSave
== m_pMasterStorage
)
682 uno::Reference
< util::XModifiable
> xMod( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
684 xMod
->setModified( sal_False
);
685 m_bIsDirty
= sal_False
;
692 catch( uno::Exception
& )
701 STDMETHODIMP
EmbedDocument_Impl::SaveCompleted( IStorage
*pStgNew
)
703 // m_pOwnStream == NULL && m_pMasterStorage != NULL means the object is in NoScribble mode
704 // m_pOwnStream == NULL && m_pMasterStorage == NULL means the object is in HandsOff mode
706 if ( m_pOwnStream
|| m_pExtStream
)
709 if ( !m_pMasterStorage
&& !pStgNew
)
713 m_pMasterStorage
= pStgNew
;
716 HRESULT hr
= m_pMasterStorage
->Stat( &aStat
, STATFLAG_NONAME
);
717 if ( FAILED( hr
) ) return E_OUTOFMEMORY
;
719 DWORD nStreamMode
= aStat
.grfMode
;
720 hr
= m_pMasterStorage
->OpenStream( reinterpret_cast<LPCWSTR
>(aOfficeEmbedStreamName
.getStr()),
725 if ( FAILED( hr
) || !m_pOwnStream
) return E_OUTOFMEMORY
;
727 hr
= m_pMasterStorage
->OpenStream( reinterpret_cast<LPCWSTR
>(aExtentStreamName
.getStr()),
732 if ( FAILED( hr
) || !m_pExtStream
) return E_OUTOFMEMORY
;
734 sal_Bool bModified
= sal_False
;
735 uno::Reference
< util::XModifiable
> xMod( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
737 bModified
= xMod
->isModified();
739 for ( AdviseSinkHashMapIterator iAdvise
= m_aAdviseHashMap
.begin(); iAdvise
!= m_aAdviseHashMap
.end(); iAdvise
++ )
741 if ( iAdvise
->second
)
742 iAdvise
->second
->OnSave();
746 bModified
= xMod
->isModified();
751 STDMETHODIMP
EmbedDocument_Impl::HandsOffStorage()
753 m_pMasterStorage
= CComPtr
< IStorage
>();
754 m_pOwnStream
= CComPtr
< IStream
>();
755 m_pExtStream
= CComPtr
< IStream
>();
760 //-------------------------------------------------------------------------------
763 STDMETHODIMP
EmbedDocument_Impl::Load( LPCOLESTR pszFileName
, DWORD
/*dwMode*/ )
765 if ( m_pDocHolder
->GetDocument().is() )
766 return CO_E_ALREADYINITIALIZED
;
768 if ( !m_xFactory
.is() )
771 DWORD nStreamMode
= STGM_CREATE
| STGM_READWRITE
| STGM_DELETEONRELEASE
| STGM_SHARE_EXCLUSIVE
;
772 HRESULT hr
= StgCreateDocfile( NULL
,
777 if ( FAILED( hr
) || !m_pMasterStorage
) return E_FAIL
;
779 ::rtl::OUString aCurType
= getServiceNameFromGUID_Impl( &m_guid
); // ???
780 CLIPFORMAT cf
= (CLIPFORMAT
)RegisterClipboardFormatA( "Embedded Object" );
781 hr
= WriteFmtUserTypeStg( m_pMasterStorage
,
783 reinterpret_cast<LPWSTR
>(( sal_Unicode
* )aCurType
.getStr()) );
784 if ( FAILED( hr
) ) return E_FAIL
;
786 hr
= m_pMasterStorage
->SetClass( m_guid
);
787 if ( FAILED( hr
) ) return E_FAIL
;
789 hr
= m_pMasterStorage
->CreateStream( reinterpret_cast<LPCWSTR
>(aOfficeEmbedStreamName
.getStr()),
790 STGM_CREATE
| ( nStreamMode
& 0x73 ),
794 if ( FAILED( hr
) || !m_pOwnStream
) return E_FAIL
;
796 hr
= m_pMasterStorage
->CreateStream( reinterpret_cast<LPCWSTR
>(aExtentStreamName
.getStr()),
797 STGM_CREATE
| ( nStreamMode
& 0x73 ),
801 if ( FAILED( hr
) || !m_pExtStream
) return E_FAIL
;
804 uno::Reference
< frame::XModel
> aDocument(
805 m_xFactory
->createInstance( getServiceNameFromGUID_Impl( &m_guid
) ),
807 if ( aDocument
.is() )
809 m_pDocHolder
->SetDocument( aDocument
, sal_True
);
811 uno::Reference
< frame::XLoadable
> xLoadable( m_pDocHolder
->GetDocument(), uno::UNO_QUERY
);
816 xLoadable
->load( fillArgsForLoading_Impl( uno::Reference
< io::XInputStream
>(),
821 m_aFileName
= ::rtl::OUString( reinterpret_cast<const sal_Unicode
*>(pszFileName
) );
823 catch( uno::Exception
& )
830 ::rtl::OUString aCurType
= getServiceNameFromGUID_Impl( &m_guid
); // ???
831 CLIPFORMAT cf
= (CLIPFORMAT
)RegisterClipboardFormatA( "Embedded Object" );
832 hr
= WriteFmtUserTypeStg( m_pMasterStorage
,
834 reinterpret_cast<LPWSTR
>(( sal_Unicode
* )aCurType
.getStr()) );
836 if ( SUCCEEDED( hr
) )
838 // no need to truncate the stream, the size of the stream is always the same
839 ULARGE_INTEGER nNewPos
;
840 LARGE_INTEGER aZero
= { 0L, 0L };
841 hr
= m_pExtStream
->Seek( aZero
, STREAM_SEEK_SET
, &nNewPos
);
842 if ( SUCCEEDED( hr
) )
845 hr
= m_pDocHolder
->GetExtent( &aSize
);
847 if ( SUCCEEDED( hr
) )
850 sal_Int8 aInf
[EXT_STREAM_LENGTH
];
851 *((sal_Int32
*)aInf
) = 0;
852 *((sal_Int32
*)&aInf
[4]) = 0;
853 *((sal_Int32
*)&aInf
[8]) = aSize
.cx
;
854 *((sal_Int32
*)&aInf
[12]) = aSize
.cy
;
856 hr
= m_pExtStream
->Write( (void*)aInf
, EXT_STREAM_LENGTH
, &nWritten
);
857 if ( nWritten
!= EXT_STREAM_LENGTH
) hr
= E_FAIL
;
862 if ( SUCCEEDED( hr
) )
863 m_bIsDirty
= sal_True
;
870 m_pDocHolder
->CloseDocument();
873 m_pMasterStorage
= NULL
;
880 STDMETHODIMP
EmbedDocument_Impl::Save( LPCOLESTR pszFileName
, BOOL fRemember
)
882 if ( !m_pDocHolder
->GetDocument().is() || !m_xFactory
.is() )
887 // TODO/LATER: currently there is no hands off state implemented
890 uno::Reference
< frame::XStorable
> xStorable( m_pDocHolder
->GetDocument(), uno::UNO_QUERY_THROW
);
897 aURL
.Complete
= ::rtl::OUString( reinterpret_cast<const sal_Unicode
*>( pszFileName
) );
899 ::rtl::OUString
aServiceName( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.util.URLTransformer" ) );
900 uno::Reference
< util::XURLTransformer
> aTransformer( m_xFactory
->createInstance( aServiceName
),
901 uno::UNO_QUERY_THROW
);
903 if ( aTransformer
->parseSmart( aURL
, ::rtl::OUString() ) && aURL
.Complete
.getLength() )
907 xStorable
->storeAsURL( aURL
.Complete
, fillArgsForStoring_Impl( uno::Reference
< io::XOutputStream
>() ) );
908 m_aFileName
= aURL
.Complete
;
911 xStorable
->storeToURL( aURL
.Complete
, fillArgsForStoring_Impl( uno::Reference
< io::XOutputStream
>() ) );
917 catch( uno::Exception
& )
924 STDMETHODIMP
EmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName
)
926 // the different file name would mean error here
927 m_aFileName
= ::rtl::OUString( reinterpret_cast<const sal_Unicode
*>(pszFileName
) );
931 STDMETHODIMP
EmbedDocument_Impl::GetCurFile( LPOLESTR
*ppszFileName
)
933 CComPtr
<IMalloc
> pMalloc
;
935 HRESULT hr
= CoGetMalloc( 1, &pMalloc
);
936 if ( FAILED( hr
) || !pMalloc
) return E_FAIL
;
938 *ppszFileName
= (LPOLESTR
)( pMalloc
->Alloc( sizeof( sal_Unicode
) * ( m_aFileName
.getLength() + 1 ) ) );
939 wcsncpy( *ppszFileName
, reinterpret_cast<LPCWSTR
>(m_aFileName
.getStr()), m_aFileName
.getLength() + 1 );
941 return m_aFileName
.getLength() ? S_OK
: S_FALSE
;
944 // ===============================================
946 LockedEmbedDocument_Impl
EmbeddedDocumentInstanceAccess_Impl::GetEmbedDocument()
948 ::osl::MutexGuard
aGuard( m_aMutex
);
949 return LockedEmbedDocument_Impl( m_pEmbedDocument
);
952 void EmbeddedDocumentInstanceAccess_Impl::ClearEmbedDocument()
954 ::osl::MutexGuard
aGuard( m_aMutex
);
955 m_pEmbedDocument
= NULL
;
958 // ===============================================
960 LockedEmbedDocument_Impl::LockedEmbedDocument_Impl()
961 : m_pEmbedDocument( NULL
)
964 LockedEmbedDocument_Impl::LockedEmbedDocument_Impl( EmbedDocument_Impl
* pEmbedDocument
)
965 : m_pEmbedDocument( pEmbedDocument
)
967 if ( m_pEmbedDocument
)
968 m_pEmbedDocument
->AddRef();
971 LockedEmbedDocument_Impl::LockedEmbedDocument_Impl( const LockedEmbedDocument_Impl
& aDocLock
)
972 : m_pEmbedDocument( aDocLock
.m_pEmbedDocument
)
974 if ( m_pEmbedDocument
)
975 m_pEmbedDocument
->AddRef();
978 LockedEmbedDocument_Impl
& LockedEmbedDocument_Impl::operator=( const LockedEmbedDocument_Impl
& aDocLock
)
980 if ( m_pEmbedDocument
)
981 m_pEmbedDocument
->Release();
983 m_pEmbedDocument
= aDocLock
.m_pEmbedDocument
;
984 if ( m_pEmbedDocument
)
985 m_pEmbedDocument
->AddRef();
990 LockedEmbedDocument_Impl::~LockedEmbedDocument_Impl()
992 if ( m_pEmbedDocument
)
993 m_pEmbedDocument
->Release();
996 void LockedEmbedDocument_Impl::ExecuteMethod( sal_Int16 nId
)
998 if ( m_pEmbedDocument
)
1000 if ( nId
== OLESERV_SAVEOBJECT
)
1001 m_pEmbedDocument
->SaveObject();
1002 else if ( nId
== OLESERV_CLOSE
)
1003 m_pEmbedDocument
->Close( 0 );
1004 else if ( nId
== OLESERV_NOTIFY
)
1005 m_pEmbedDocument
->notify();
1006 else if ( nId
== OLESERV_NOTIFYCLOSING
)
1007 m_pEmbedDocument
->OLENotifyClosing();
1008 else if ( nId
== OLESERV_SHOWOBJECT
)
1009 m_pEmbedDocument
->ShowObject();
1010 else if ( nId
== OLESERV_DEACTIVATE
)
1011 m_pEmbedDocument
->Deactivate();
1015 // Fix strange warnings about some
1016 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
1017 // warning C4505: 'xxx' : unreferenced local function has been removed
1018 #if defined(_MSC_VER)
1019 #pragma warning(disable: 4505)