xref: /AOO41X/main/embeddedobj/source/msole/olecomponent.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_embeddedobj.hxx"
30*cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
31*cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/embed/WrongStateException.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/embed/UnreachableStateException.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/io/XTruncate.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/awt/XRequestCallback.hpp>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <platform.h>
40*cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.h>
41*cdf0e10cSrcweir #include <comphelper/mimeconfighelper.hxx>
42*cdf0e10cSrcweir #include <comphelper/storagehelper.hxx>
43*cdf0e10cSrcweir #include <osl/file.hxx>
44*cdf0e10cSrcweir #include <rtl/ref.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <olecomponent.hxx>
47*cdf0e10cSrcweir #include <olewrapclient.hxx>
48*cdf0e10cSrcweir #include <advisesink.hxx>
49*cdf0e10cSrcweir #include <oleembobj.hxx>
50*cdf0e10cSrcweir #include <mtnotification.hxx>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir using namespace ::com::sun::star;
53*cdf0e10cSrcweir using namespace ::comphelper;
54*cdf0e10cSrcweir #define     MAX_ENUM_ELE     20
55*cdf0e10cSrcweir #define		FORMATS_NUM		 3
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir // ============ class ComSmart =====================
58*cdf0e10cSrcweir namespace {
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir template< class T > class ComSmart
61*cdf0e10cSrcweir {
62*cdf0e10cSrcweir     T* m_pInterface;
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir     void OwnRelease()
65*cdf0e10cSrcweir     {
66*cdf0e10cSrcweir         if ( m_pInterface )
67*cdf0e10cSrcweir         {
68*cdf0e10cSrcweir             T* pInterface = m_pInterface;
69*cdf0e10cSrcweir             m_pInterface = NULL;
70*cdf0e10cSrcweir             pInterface->Release();
71*cdf0e10cSrcweir         }
72*cdf0e10cSrcweir     }
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir public:
75*cdf0e10cSrcweir     ComSmart()
76*cdf0e10cSrcweir     : m_pInterface( NULL )
77*cdf0e10cSrcweir     {}
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir     ComSmart( const ComSmart<T>& rObj )
80*cdf0e10cSrcweir     : m_pInterface( rObj.m_pInterface )
81*cdf0e10cSrcweir     {
82*cdf0e10cSrcweir         if ( m_pInterface != NULL )
83*cdf0e10cSrcweir             m_pInterface->AddRef();
84*cdf0e10cSrcweir     }
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir     ComSmart( T* pInterface )
87*cdf0e10cSrcweir     : m_pInterface( pInterface )
88*cdf0e10cSrcweir     {
89*cdf0e10cSrcweir          if ( m_pInterface != NULL )
90*cdf0e10cSrcweir             m_pInterface->AddRef();
91*cdf0e10cSrcweir     }
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 	~ComSmart()
94*cdf0e10cSrcweir 	{
95*cdf0e10cSrcweir         OwnRelease();
96*cdf0e10cSrcweir 	}
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir     ComSmart& operator=( const ComSmart<T>& rObj )
99*cdf0e10cSrcweir     {
100*cdf0e10cSrcweir         OwnRelease();
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir         m_pInterface = rObj.m_pInterface;
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir         if ( m_pInterface != NULL )
105*cdf0e10cSrcweir             m_pInterface->AddRef();
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir         return *this;
108*cdf0e10cSrcweir     }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir     ComSmart<T>& operator=( T* pInterface )
111*cdf0e10cSrcweir     {
112*cdf0e10cSrcweir         OwnRelease();
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir         m_pInterface = pInterface;
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir         if ( m_pInterface != NULL )
117*cdf0e10cSrcweir             m_pInterface->AddRef();
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir         return *this;
120*cdf0e10cSrcweir     }
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir     operator T*() const
123*cdf0e10cSrcweir     {
124*cdf0e10cSrcweir         return m_pInterface;
125*cdf0e10cSrcweir     }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir     T& operator*() const
128*cdf0e10cSrcweir     {
129*cdf0e10cSrcweir         return *m_pInterface;
130*cdf0e10cSrcweir     }
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir     T** operator&()
133*cdf0e10cSrcweir     {
134*cdf0e10cSrcweir         OwnRelease();
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir         m_pInterface = NULL;
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir         return &m_pInterface;
139*cdf0e10cSrcweir     }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     T* operator->() const
142*cdf0e10cSrcweir     {
143*cdf0e10cSrcweir         return m_pInterface;
144*cdf0e10cSrcweir     }
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir     BOOL operator==( const ComSmart<T>& rObj ) const
147*cdf0e10cSrcweir     {
148*cdf0e10cSrcweir         return ( m_pInterface == rObj.m_pInterface );
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir     BOOL operator!=( const ComSmart<T>& rObj ) const
152*cdf0e10cSrcweir     {
153*cdf0e10cSrcweir         return ( m_pInterface != rObj.m_pInterface );
154*cdf0e10cSrcweir     }
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir     BOOL operator==( const T* pInterface ) const
157*cdf0e10cSrcweir     {
158*cdf0e10cSrcweir         return ( m_pInterface == pInterface );
159*cdf0e10cSrcweir     }
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir     BOOL operator!=( const T* pInterface ) const
162*cdf0e10cSrcweir     {
163*cdf0e10cSrcweir         return ( m_pInterface != pInterface );
164*cdf0e10cSrcweir     }
165*cdf0e10cSrcweir };
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir // ============ class ComSmart =====================
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir sal_Bool ConvertBufferToFormat( void* pBuf,
172*cdf0e10cSrcweir 								sal_uInt32 nBufSize,
173*cdf0e10cSrcweir 								const ::rtl::OUString& aFormatShortName,
174*cdf0e10cSrcweir 								uno::Any& aResult );
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir typedef ::std::vector< FORMATETC* > FormatEtcList;
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir FORMATETC pFormatTemplates[FORMATS_NUM] = {
181*cdf0e10cSrcweir 					{ CF_ENHMETAFILE, NULL, 0, -1, TYMED_ENHMF },
182*cdf0e10cSrcweir 					{ CF_METAFILEPICT, NULL, 0, -1, TYMED_MFPICT },
183*cdf0e10cSrcweir 					{ CF_BITMAP, NULL, 0, -1, TYMED_GDI } };
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir struct OleComponentNative_Impl {
187*cdf0e10cSrcweir 	ComSmart< IUnknown > m_pObj;
188*cdf0e10cSrcweir 	ComSmart< IOleObject > m_pOleObject;
189*cdf0e10cSrcweir 	ComSmart< IViewObject2 > m_pViewObject2;
190*cdf0e10cSrcweir 	ComSmart< IStorage > m_pIStorage;
191*cdf0e10cSrcweir 	FormatEtcList m_aFormatsList;
192*cdf0e10cSrcweir 	uno::Sequence< datatransfer::DataFlavor > m_aSupportedGraphFormats;
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 	OleComponentNative_Impl()
195*cdf0e10cSrcweir 	{
196*cdf0e10cSrcweir 		// TODO: Extend format list
197*cdf0e10cSrcweir 		m_aSupportedGraphFormats.realloc( 5 );
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 		m_aSupportedGraphFormats[0] = datatransfer::DataFlavor(
200*cdf0e10cSrcweir             ::rtl::OUString::createFromAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ),
201*cdf0e10cSrcweir 			::rtl::OUString::createFromAscii( "Windows Enhanced Metafile" ),
202*cdf0e10cSrcweir 			getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 		m_aSupportedGraphFormats[1] = datatransfer::DataFlavor(
205*cdf0e10cSrcweir             ::rtl::OUString::createFromAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ),
206*cdf0e10cSrcweir 			::rtl::OUString::createFromAscii( "Windows Metafile" ),
207*cdf0e10cSrcweir 			getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 		m_aSupportedGraphFormats[2] = datatransfer::DataFlavor(
210*cdf0e10cSrcweir             ::rtl::OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ),
211*cdf0e10cSrcweir 			::rtl::OUString::createFromAscii( "Bitmap" ),
212*cdf0e10cSrcweir 			getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 		m_aSupportedGraphFormats[3] = datatransfer::DataFlavor(
215*cdf0e10cSrcweir 			::rtl::OUString::createFromAscii( "image/png" ),
216*cdf0e10cSrcweir 			::rtl::OUString::createFromAscii( "PNG" ),
217*cdf0e10cSrcweir 			getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 		m_aSupportedGraphFormats[0] = datatransfer::DataFlavor(
220*cdf0e10cSrcweir             ::rtl::OUString::createFromAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ),
221*cdf0e10cSrcweir 			::rtl::OUString::createFromAscii( "GDIMetafile" ),
222*cdf0e10cSrcweir 			getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
223*cdf0e10cSrcweir 	}
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 	void AddSupportedFormat( const FORMATETC& aFormatEtc );
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir 	FORMATETC* GetSupportedFormatForAspect( sal_uInt32 nRequestedAspect );
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 	sal_Bool ConvertDataForFlavor( const STGMEDIUM& aMedium,
230*cdf0e10cSrcweir 									const datatransfer::DataFlavor& aFlavor,
231*cdf0e10cSrcweir 									uno::Any& aResult );
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	sal_Bool GraphicalFlavor( const datatransfer::DataFlavor& aFlavor );
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir 	uno::Sequence< datatransfer::DataFlavor > GetFlavorsForAspects( sal_uInt32 nSupportedAspects );
236*cdf0e10cSrcweir };
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir //----------------------------------------------
239*cdf0e10cSrcweir DWORD GetAspectFromFlavor( const datatransfer::DataFlavor& aFlavor )
240*cdf0e10cSrcweir {
241*cdf0e10cSrcweir 	if ( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( ";Aspect=THUMBNAIL" ) ) != -1 )
242*cdf0e10cSrcweir 		return DVASPECT_THUMBNAIL;
243*cdf0e10cSrcweir 	else if ( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( ";Aspect=ICON" ) ) != -1 )
244*cdf0e10cSrcweir 		return DVASPECT_ICON;
245*cdf0e10cSrcweir 	else if ( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( ";Aspect=DOCPRINT" ) ) != -1 )
246*cdf0e10cSrcweir 		return DVASPECT_DOCPRINT;
247*cdf0e10cSrcweir 	else
248*cdf0e10cSrcweir 		return DVASPECT_CONTENT;
249*cdf0e10cSrcweir }
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir //----------------------------------------------
252*cdf0e10cSrcweir ::rtl::OUString GetFlavorSuffixFromAspect( DWORD nAsp )
253*cdf0e10cSrcweir {
254*cdf0e10cSrcweir 	::rtl::OUString aResult;
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 	if ( nAsp == DVASPECT_THUMBNAIL )
257*cdf0e10cSrcweir 		aResult = ::rtl::OUString::createFromAscii( ";Aspect=THUMBNAIL" );
258*cdf0e10cSrcweir 	else if ( nAsp == DVASPECT_ICON )
259*cdf0e10cSrcweir 		aResult = ::rtl::OUString::createFromAscii( ";Aspect=ICON" );
260*cdf0e10cSrcweir 	else if ( nAsp == DVASPECT_DOCPRINT )
261*cdf0e10cSrcweir 		aResult = ::rtl::OUString::createFromAscii( ";Aspect=DOCPRINT" );
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 	// no suffix for DVASPECT_CONTENT
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 	return aResult;
266*cdf0e10cSrcweir }
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir //----------------------------------------------
269*cdf0e10cSrcweir HRESULT OpenIStorageFromURL_Impl( const ::rtl::OUString& aURL, IStorage** ppIStorage )
270*cdf0e10cSrcweir {
271*cdf0e10cSrcweir 	OSL_ENSURE( ppIStorage, "The pointer must not be empty!" );
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 	::rtl::OUString aFilePath;
274*cdf0e10cSrcweir 	if ( !ppIStorage || ::osl::FileBase::getSystemPathFromFileURL( aURL, aFilePath ) != ::osl::FileBase::E_None )
275*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO: something dangerous happend
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 	return StgOpenStorage( reinterpret_cast<LPCWSTR>(aFilePath.getStr()),
278*cdf0e10cSrcweir 							 NULL,
279*cdf0e10cSrcweir 							 STGM_READWRITE | STGM_TRANSACTED, // | STGM_DELETEONRELEASE,
280*cdf0e10cSrcweir 							 NULL,
281*cdf0e10cSrcweir 							 0,
282*cdf0e10cSrcweir 							 ppIStorage );
283*cdf0e10cSrcweir }
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir //----------------------------------------------
286*cdf0e10cSrcweir sal_Bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
287*cdf0e10cSrcweir 														const datatransfer::DataFlavor& aFlavor,
288*cdf0e10cSrcweir 														uno::Any& aResult )
289*cdf0e10cSrcweir {
290*cdf0e10cSrcweir 	sal_Bool bAnyIsReady = sal_False;
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir 	// try to convert data from Medium format to specified Flavor format
293*cdf0e10cSrcweir 	if ( aFlavor.DataType == getCppuType( ( const uno::Sequence< sal_Int8 >* ) 0 ) )
294*cdf0e10cSrcweir 	{
295*cdf0e10cSrcweir 		// first the GDI-metafile must be generated
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir 		unsigned char* pBuf = NULL;
298*cdf0e10cSrcweir 		sal_uInt32 nBufSize = 0;
299*cdf0e10cSrcweir 		::rtl::OUString aFormat;
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir 		if ( aMedium.tymed == TYMED_MFPICT ) // Win Metafile
302*cdf0e10cSrcweir 		{
303*cdf0e10cSrcweir 			aFormat = ::rtl::OUString::createFromAscii("image/x-wmf");
304*cdf0e10cSrcweir 			METAFILEPICT* pMF = ( METAFILEPICT* )GlobalLock( aMedium.hMetaFilePict );
305*cdf0e10cSrcweir 			if ( pMF )
306*cdf0e10cSrcweir 			{
307*cdf0e10cSrcweir 				nBufSize = GetMetaFileBitsEx( pMF->hMF, 0, NULL ) + 22;
308*cdf0e10cSrcweir 				pBuf = new unsigned char[nBufSize];
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir 				// TODO/LATER: the unit size must be calculated correctly
312*cdf0e10cSrcweir 				*( (long* )pBuf ) = 0x9ac6cdd7L;
313*cdf0e10cSrcweir 				*( (short* )( pBuf+6 )) = ( SHORT ) 0;
314*cdf0e10cSrcweir 				*( (short* )( pBuf+8 )) = ( SHORT ) 0;
315*cdf0e10cSrcweir 				*( (short* )( pBuf+10 )) = ( SHORT ) pMF->xExt;
316*cdf0e10cSrcweir 				*( (short* )( pBuf+12 )) = ( SHORT ) pMF->yExt;
317*cdf0e10cSrcweir 				*( (short* )( pBuf+14 )) = ( USHORT ) 2540;
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir 				if ( nBufSize && nBufSize == GetMetaFileBitsEx( pMF->hMF, nBufSize - 22, pBuf + 22 ) )
321*cdf0e10cSrcweir 				{
322*cdf0e10cSrcweir                     if ( aFlavor.MimeType.matchAsciiL( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", 57 ) )
323*cdf0e10cSrcweir 					{
324*cdf0e10cSrcweir 						aResult <<= uno::Sequence< sal_Int8 >( ( sal_Int8* )pBuf, nBufSize );
325*cdf0e10cSrcweir 						bAnyIsReady = sal_True;
326*cdf0e10cSrcweir 					}
327*cdf0e10cSrcweir 				}
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 				GlobalUnlock( aMedium.hMetaFilePict );
330*cdf0e10cSrcweir 			}
331*cdf0e10cSrcweir 		}
332*cdf0e10cSrcweir 		else if ( aMedium.tymed == TYMED_ENHMF ) // Enh Metafile
333*cdf0e10cSrcweir 		{
334*cdf0e10cSrcweir 			aFormat = ::rtl::OUString::createFromAscii("image/x-emf");
335*cdf0e10cSrcweir 			nBufSize = GetEnhMetaFileBits( aMedium.hEnhMetaFile, 0, NULL );
336*cdf0e10cSrcweir 			pBuf = new unsigned char[nBufSize];
337*cdf0e10cSrcweir 			if ( nBufSize && nBufSize == GetEnhMetaFileBits( aMedium.hEnhMetaFile, nBufSize, pBuf ) )
338*cdf0e10cSrcweir 			{
339*cdf0e10cSrcweir                 if ( aFlavor.MimeType.matchAsciiL( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"", 57 ) )
340*cdf0e10cSrcweir 				{
341*cdf0e10cSrcweir 					aResult <<= uno::Sequence< sal_Int8 >( ( sal_Int8* )pBuf, nBufSize );
342*cdf0e10cSrcweir 					bAnyIsReady = sal_True;
343*cdf0e10cSrcweir 				}
344*cdf0e10cSrcweir 			}
345*cdf0e10cSrcweir 		}
346*cdf0e10cSrcweir 		else if ( aMedium.tymed == TYMED_GDI ) // Bitmap
347*cdf0e10cSrcweir 		{
348*cdf0e10cSrcweir 			aFormat = ::rtl::OUString::createFromAscii("image/x-MS-bmp");
349*cdf0e10cSrcweir 			nBufSize = GetBitmapBits( aMedium.hBitmap, 0, NULL );
350*cdf0e10cSrcweir 			pBuf = new unsigned char[nBufSize];
351*cdf0e10cSrcweir 			if ( nBufSize && nBufSize == sal::static_int_cast< ULONG >( GetBitmapBits( aMedium.hBitmap, nBufSize, pBuf ) ) )
352*cdf0e10cSrcweir 			{
353*cdf0e10cSrcweir                 if ( aFlavor.MimeType.matchAsciiL( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", 54 ) )
354*cdf0e10cSrcweir 				{
355*cdf0e10cSrcweir 					aResult <<= uno::Sequence< sal_Int8 >( ( sal_Int8* )pBuf, nBufSize );
356*cdf0e10cSrcweir 					bAnyIsReady = sal_True;
357*cdf0e10cSrcweir 				}
358*cdf0e10cSrcweir 			}
359*cdf0e10cSrcweir 		}
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir 		if ( pBuf && !bAnyIsReady )
362*cdf0e10cSrcweir 		{
363*cdf0e10cSrcweir 			for ( sal_Int32 nInd = 0; nInd < m_aSupportedGraphFormats.getLength(); nInd++ )
364*cdf0e10cSrcweir  				if ( aFlavor.MimeType.match( m_aSupportedGraphFormats[nInd].MimeType )
365*cdf0e10cSrcweir 				  && aFlavor.DataType == m_aSupportedGraphFormats[nInd].DataType
366*cdf0e10cSrcweir 				  && aFlavor.DataType == getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) )
367*cdf0e10cSrcweir 			{
368*cdf0e10cSrcweir 				bAnyIsReady = ConvertBufferToFormat( ( void* )pBuf, nBufSize, aFormat, aResult );
369*cdf0e10cSrcweir 				break;
370*cdf0e10cSrcweir 			}
371*cdf0e10cSrcweir 		}
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir 		delete[] pBuf;
374*cdf0e10cSrcweir 	}
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 	return bAnyIsReady;
377*cdf0e10cSrcweir }
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir //----------------------------------------------
380*cdf0e10cSrcweir sal_Bool OleComponentNative_Impl::GraphicalFlavor( const datatransfer::DataFlavor& aFlavor )
381*cdf0e10cSrcweir {
382*cdf0e10cSrcweir 	// Actually all the required graphical formats must be supported
383*cdf0e10cSrcweir 	for ( sal_Int32 nInd = 0; nInd < m_aSupportedGraphFormats.getLength(); nInd++ )
384*cdf0e10cSrcweir  		if ( aFlavor.MimeType.match( m_aSupportedGraphFormats[nInd].MimeType )
385*cdf0e10cSrcweir 		  && aFlavor.DataType == m_aSupportedGraphFormats[nInd].DataType )
386*cdf0e10cSrcweir 			return sal_True;
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir 	return sal_False;
389*cdf0e10cSrcweir }
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir //----------------------------------------------
392*cdf0e10cSrcweir sal_Bool GetClassIDFromSequence_Impl( uno::Sequence< sal_Int8 > aSeq, CLSID& aResult )
393*cdf0e10cSrcweir {
394*cdf0e10cSrcweir 	if ( aSeq.getLength() == 16 )
395*cdf0e10cSrcweir 	{
396*cdf0e10cSrcweir 		aResult.Data1 = ( ( ( ( ( ( sal_uInt8 )aSeq[0] << 8 ) + ( sal_uInt8 )aSeq[1] ) << 8 ) + ( sal_uInt8 )aSeq[2] ) << 8 ) + ( sal_uInt8 )aSeq[3];
397*cdf0e10cSrcweir 		aResult.Data2 = ( ( sal_uInt8 )aSeq[4] << 8 ) + ( sal_uInt8 )aSeq[5];
398*cdf0e10cSrcweir 		aResult.Data3 = ( ( sal_uInt8 )aSeq[6] << 8 ) + ( sal_uInt8 )aSeq[7];
399*cdf0e10cSrcweir 		for( int nInd = 0; nInd < 8; nInd++ )
400*cdf0e10cSrcweir 			aResult.Data4[nInd] = ( sal_uInt8 )aSeq[nInd+8];
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir 		return sal_True;
403*cdf0e10cSrcweir 	}
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir 	return sal_False;
406*cdf0e10cSrcweir }
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir //----------------------------------------------
409*cdf0e10cSrcweir ::rtl::OUString WinAccToVcl_Impl( const sal_Unicode* pStr )
410*cdf0e10cSrcweir {
411*cdf0e10cSrcweir 	::rtl::OUString aResult;
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir 	if( pStr )
414*cdf0e10cSrcweir 	{
415*cdf0e10cSrcweir 		while ( *pStr )
416*cdf0e10cSrcweir 		{
417*cdf0e10cSrcweir 			if ( *pStr == '&' )
418*cdf0e10cSrcweir 			{
419*cdf0e10cSrcweir 				aResult += ::rtl::OUString::createFromAscii( "~" );
420*cdf0e10cSrcweir 				while( *( ++pStr ) == '&' );
421*cdf0e10cSrcweir 			}
422*cdf0e10cSrcweir 			else
423*cdf0e10cSrcweir 			{
424*cdf0e10cSrcweir 				aResult += ::rtl::OUString( pStr, 1 );
425*cdf0e10cSrcweir 				pStr++;
426*cdf0e10cSrcweir 			}
427*cdf0e10cSrcweir 		}
428*cdf0e10cSrcweir 	}
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 	return aResult;
431*cdf0e10cSrcweir }
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir //----------------------------------------------
434*cdf0e10cSrcweir OleComponent::OleComponent( const uno::Reference< lang::XMultiServiceFactory >& xFactory, OleEmbeddedObject* pUnoOleObject )
435*cdf0e10cSrcweir : m_pInterfaceContainer( NULL )
436*cdf0e10cSrcweir , m_bDisposed( sal_False )
437*cdf0e10cSrcweir , m_bModified( sal_False )
438*cdf0e10cSrcweir , m_pNativeImpl( new OleComponentNative_Impl() )
439*cdf0e10cSrcweir , m_xFactory( xFactory )
440*cdf0e10cSrcweir , m_pOleWrapClientSite( NULL )
441*cdf0e10cSrcweir , m_pImplAdviseSink( NULL )
442*cdf0e10cSrcweir , m_pUnoOleObject( pUnoOleObject )
443*cdf0e10cSrcweir , m_nOLEMiscFlags( 0 )
444*cdf0e10cSrcweir , m_nAdvConn( 0 )
445*cdf0e10cSrcweir , m_bOleInitialized( sal_False )
446*cdf0e10cSrcweir , m_bWorkaroundActive( sal_False )
447*cdf0e10cSrcweir {
448*cdf0e10cSrcweir 	OSL_ENSURE( m_pUnoOleObject, "No owner object is provided!" );
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir 	HRESULT hr = OleInitialize( NULL );
451*cdf0e10cSrcweir 	OSL_ENSURE( hr == S_OK || hr == S_FALSE, "The ole can not be successfuly initialized\n" );
452*cdf0e10cSrcweir 	if ( hr == S_OK || hr == S_FALSE )
453*cdf0e10cSrcweir 		m_bOleInitialized = sal_True;
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir 	m_pOleWrapClientSite = new OleWrapperClientSite( ( OleComponent* )this );
456*cdf0e10cSrcweir 	m_pOleWrapClientSite->AddRef();
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir 	m_pImplAdviseSink = new OleWrapperAdviseSink( ( OleComponent* )this );
459*cdf0e10cSrcweir 	m_pImplAdviseSink->AddRef();
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir }
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir //----------------------------------------------
464*cdf0e10cSrcweir OleComponent::~OleComponent()
465*cdf0e10cSrcweir {
466*cdf0e10cSrcweir 	OSL_ENSURE( !m_pOleWrapClientSite && !m_pImplAdviseSink && !m_pInterfaceContainer && !m_bOleInitialized,
467*cdf0e10cSrcweir 				"The object was not closed successfully! DISASTER is possible!" );
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir 	if ( m_pOleWrapClientSite || m_pImplAdviseSink || m_pInterfaceContainer || m_bOleInitialized )
470*cdf0e10cSrcweir 	{
471*cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
472*cdf0e10cSrcweir 		m_refCount++;
473*cdf0e10cSrcweir 		try {
474*cdf0e10cSrcweir 			Dispose();
475*cdf0e10cSrcweir 		} catch( uno::Exception& ) {}
476*cdf0e10cSrcweir 	}
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir 	for ( FormatEtcList::iterator aIter = m_pNativeImpl->m_aFormatsList.begin();
479*cdf0e10cSrcweir 		  aIter != m_pNativeImpl->m_aFormatsList.end();
480*cdf0e10cSrcweir 		  aIter++ )
481*cdf0e10cSrcweir 	{
482*cdf0e10cSrcweir 		delete (*aIter);
483*cdf0e10cSrcweir 		(*aIter) = NULL;
484*cdf0e10cSrcweir 	}
485*cdf0e10cSrcweir 	m_pNativeImpl->m_aFormatsList.clear();
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir 	delete m_pNativeImpl;
488*cdf0e10cSrcweir }
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir //----------------------------------------------
491*cdf0e10cSrcweir void OleComponentNative_Impl::AddSupportedFormat( const FORMATETC& aFormatEtc )
492*cdf0e10cSrcweir {
493*cdf0e10cSrcweir 	FORMATETC* pFormatToInsert = new FORMATETC( aFormatEtc );
494*cdf0e10cSrcweir 	m_aFormatsList.push_back( pFormatToInsert );
495*cdf0e10cSrcweir }
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir //----------------------------------------------
498*cdf0e10cSrcweir FORMATETC* OleComponentNative_Impl::GetSupportedFormatForAspect( sal_uInt32 nRequestedAspect )
499*cdf0e10cSrcweir {
500*cdf0e10cSrcweir 	for ( FormatEtcList::iterator aIter = m_aFormatsList.begin();
501*cdf0e10cSrcweir 		  aIter != m_aFormatsList.end();
502*cdf0e10cSrcweir 		  aIter++ )
503*cdf0e10cSrcweir 		if ( (*aIter) && (*aIter)->dwAspect == nRequestedAspect )
504*cdf0e10cSrcweir 			return (*aIter);
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir 	return NULL;
507*cdf0e10cSrcweir }
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir //----------------------------------------------
510*cdf0e10cSrcweir void OleComponent::Dispose()
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir 	// the mutex must be locked before this method is called
513*cdf0e10cSrcweir 	if ( m_bDisposed )
514*cdf0e10cSrcweir 		return;
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir 	CloseObject();
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir 	if ( m_pOleWrapClientSite )
519*cdf0e10cSrcweir 	{
520*cdf0e10cSrcweir 		m_pOleWrapClientSite->disconnectOleComponent();
521*cdf0e10cSrcweir 		m_pOleWrapClientSite->Release();
522*cdf0e10cSrcweir 		m_pOleWrapClientSite = NULL;
523*cdf0e10cSrcweir 	}
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir 	if ( m_pImplAdviseSink )
526*cdf0e10cSrcweir 	{
527*cdf0e10cSrcweir 		m_pImplAdviseSink->disconnectOleComponent();
528*cdf0e10cSrcweir 		m_pImplAdviseSink->Release();
529*cdf0e10cSrcweir 		m_pImplAdviseSink = NULL;
530*cdf0e10cSrcweir 	}
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir 	if ( m_pInterfaceContainer )
533*cdf0e10cSrcweir 	{
534*cdf0e10cSrcweir 		lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >( this ) );
535*cdf0e10cSrcweir 		m_pInterfaceContainer->disposeAndClear( aEvent );
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir 		delete m_pInterfaceContainer;
538*cdf0e10cSrcweir 		m_pInterfaceContainer = NULL;
539*cdf0e10cSrcweir 	}
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir 	if ( m_bOleInitialized )
542*cdf0e10cSrcweir 	{
543*cdf0e10cSrcweir 		// since the disposing can happen not only from main thread but also from a clipboard
544*cdf0e10cSrcweir 		// the deinitialization might lead to a disaster, SO7 does not deinitialize OLE at all
545*cdf0e10cSrcweir 		// so currently the same approach is selected as workaround
546*cdf0e10cSrcweir 		// OleUninitialize();
547*cdf0e10cSrcweir 		m_bOleInitialized = sal_False;
548*cdf0e10cSrcweir 	}
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir 	m_bDisposed = sal_True;
551*cdf0e10cSrcweir }
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir //----------------------------------------------
554*cdf0e10cSrcweir void OleComponent::disconnectEmbeddedObject()
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir 	// must not be called from destructor of UNO OLE object!!!
557*cdf0e10cSrcweir 	osl::MutexGuard aGuard( m_aMutex );
558*cdf0e10cSrcweir 	m_pUnoOleObject = NULL;
559*cdf0e10cSrcweir }
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir //----------------------------------------------
562*cdf0e10cSrcweir void OleComponent::CreateNewIStorage_Impl()
563*cdf0e10cSrcweir {
564*cdf0e10cSrcweir 	// TODO: in future a global memory could be used instead of file.
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir 	// write the stream to the temporary file
567*cdf0e10cSrcweir 	::rtl::OUString aTempURL;
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir 	OSL_ENSURE( m_pUnoOleObject, "Unexpected object absence!" );
570*cdf0e10cSrcweir 	if ( m_pUnoOleObject )
571*cdf0e10cSrcweir 		aTempURL = m_pUnoOleObject->CreateTempURLEmpty_Impl();
572*cdf0e10cSrcweir 	else
573*cdf0e10cSrcweir 		aTempURL = GetNewTempFileURL_Impl( m_xFactory );
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 	if ( !aTempURL.getLength() )
576*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir 	// open an IStorage based on the temporary file
579*cdf0e10cSrcweir 	::rtl::OUString aTempFilePath;
580*cdf0e10cSrcweir 	if ( ::osl::FileBase::getSystemPathFromFileURL( aTempURL, aTempFilePath ) != ::osl::FileBase::E_None )
581*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO: something dangerous happend
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir 	HRESULT hr = StgCreateDocfile( reinterpret_cast<LPCWSTR>(aTempFilePath.getStr()), STGM_CREATE | STGM_READWRITE | STGM_TRANSACTED | STGM_DELETEONRELEASE, 0, &m_pNativeImpl->m_pIStorage );
584*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pIStorage )
585*cdf0e10cSrcweir 		throw io::IOException(); // TODO: transport error code?
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir //----------------------------------------------
589*cdf0e10cSrcweir uno::Sequence< datatransfer::DataFlavor > OleComponentNative_Impl::GetFlavorsForAspects( sal_uInt32 nSupportedAspects )
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir 	uno::Sequence< datatransfer::DataFlavor > aResult;
592*cdf0e10cSrcweir 	for ( sal_uInt32 nAsp = 1; nAsp <= 8; nAsp *= 2 )
593*cdf0e10cSrcweir 		if ( ( nSupportedAspects & nAsp ) == nAsp )
594*cdf0e10cSrcweir 		{
595*cdf0e10cSrcweir 			::rtl::OUString aAspectSuffix = GetFlavorSuffixFromAspect( nAsp );
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir 			sal_Int32 nLength = aResult.getLength();
598*cdf0e10cSrcweir 			aResult.realloc( nLength + m_aSupportedGraphFormats.getLength() );
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 			for ( sal_Int32 nInd = 0; nInd < m_aSupportedGraphFormats.getLength(); nInd++ )
601*cdf0e10cSrcweir 			{
602*cdf0e10cSrcweir 				aResult[nLength + nInd].MimeType = m_aSupportedGraphFormats[nInd].MimeType + aAspectSuffix;
603*cdf0e10cSrcweir 				aResult[nLength + nInd].HumanPresentableName = m_aSupportedGraphFormats[nInd].HumanPresentableName;
604*cdf0e10cSrcweir 				aResult[nLength + nInd].DataType = m_aSupportedGraphFormats[nInd].DataType;
605*cdf0e10cSrcweir 			}
606*cdf0e10cSrcweir 		}
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir 	return aResult;
609*cdf0e10cSrcweir }
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir //----------------------------------------------
612*cdf0e10cSrcweir void OleComponent::RetrieveObjectDataFlavors_Impl()
613*cdf0e10cSrcweir {
614*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
615*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir 	if ( !m_aDataFlavors.getLength() )
618*cdf0e10cSrcweir 	{
619*cdf0e10cSrcweir 		ComSmart< IDataObject > pDataObject;
620*cdf0e10cSrcweir 		HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, (void**)&pDataObject );
621*cdf0e10cSrcweir 		if ( SUCCEEDED( hr ) && pDataObject )
622*cdf0e10cSrcweir 		{
623*cdf0e10cSrcweir 			ComSmart< IEnumFORMATETC > pFormatEnum;
624*cdf0e10cSrcweir 			hr = pDataObject->EnumFormatEtc( DATADIR_GET, &pFormatEnum );
625*cdf0e10cSrcweir 			if ( SUCCEEDED( hr ) && pFormatEnum )
626*cdf0e10cSrcweir 			{
627*cdf0e10cSrcweir 				FORMATETC pElem[ MAX_ENUM_ELE ];
628*cdf0e10cSrcweir 				ULONG nNum = 0;
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir 				// if it is possible to retrieve at least one supported graphical format for an aspect
631*cdf0e10cSrcweir 				// this format can be converted to other supported formats
632*cdf0e10cSrcweir 				sal_uInt32 nSupportedAspects = 0;
633*cdf0e10cSrcweir 				do
634*cdf0e10cSrcweir 				{
635*cdf0e10cSrcweir 					HRESULT hr = pFormatEnum->Next( MAX_ENUM_ELE, pElem, &nNum );
636*cdf0e10cSrcweir 					if( hr == S_OK || hr == S_FALSE )
637*cdf0e10cSrcweir 					{
638*cdf0e10cSrcweir 						for( sal_uInt32 nInd = 0; nInd < FORMATS_NUM; nInd++ )
639*cdf0e10cSrcweir 							{
640*cdf0e10cSrcweir 							if ( pElem[nInd].cfFormat == pFormatTemplates[nInd].cfFormat
641*cdf0e10cSrcweir 					  		&& pElem[nInd].tymed == pFormatTemplates[nInd].tymed )
642*cdf0e10cSrcweir 								nSupportedAspects |= pElem[nInd].dwAspect;
643*cdf0e10cSrcweir 						}
644*cdf0e10cSrcweir 					}
645*cdf0e10cSrcweir 					else
646*cdf0e10cSrcweir 						break;
647*cdf0e10cSrcweir 				}
648*cdf0e10cSrcweir 				while( nNum == MAX_ENUM_ELE );
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir 				m_aDataFlavors = m_pNativeImpl->GetFlavorsForAspects( nSupportedAspects );
651*cdf0e10cSrcweir 			}
652*cdf0e10cSrcweir 		}
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir 		if ( !m_aDataFlavors.getLength() )
655*cdf0e10cSrcweir 		{
656*cdf0e10cSrcweir 			// TODO:
657*cdf0e10cSrcweir 			// for any reason the object could not provide this information
658*cdf0e10cSrcweir 			// try to get access to the cached representation
659*cdf0e10cSrcweir 		}
660*cdf0e10cSrcweir 	}
661*cdf0e10cSrcweir }
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir //----------------------------------------------
664*cdf0e10cSrcweir sal_Bool OleComponent::InitializeObject_Impl()
665*cdf0e10cSrcweir // There will be no static objects!
666*cdf0e10cSrcweir {
667*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pObj )
668*cdf0e10cSrcweir 		return sal_False;
669*cdf0e10cSrcweir 
670*cdf0e10cSrcweir 	// the linked object will be detected here
671*cdf0e10cSrcweir 	ComSmart< IOleLink > pOleLink;
672*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IOleLink, (void**)&pOleLink );
673*cdf0e10cSrcweir 	OSL_ENSURE( m_pUnoOleObject, "Unexpected object absence!" );
674*cdf0e10cSrcweir 	if ( m_pUnoOleObject )
675*cdf0e10cSrcweir 		m_pUnoOleObject->SetObjectIsLink_Impl( sal_Bool( pOleLink != NULL ) );
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 	hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IViewObject2, (void**)&m_pNativeImpl->m_pViewObject2 );
679*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pViewObject2 )
680*cdf0e10cSrcweir 		return sal_False;
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir 	// not realy needed for now, since object is updated on saving
683*cdf0e10cSrcweir 	// m_pNativeImpl->m_pViewObject2->SetAdvise( DVASPECT_CONTENT, 0, m_pImplAdviseSink );
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir 	// remove all the caches
686*cdf0e10cSrcweir 	IOleCache* pIOleCache = NULL;
687*cdf0e10cSrcweir 	if ( SUCCEEDED( m_pNativeImpl->m_pObj->QueryInterface( IID_IOleCache, (void**)&pIOleCache ) ) && pIOleCache )
688*cdf0e10cSrcweir 	{
689*cdf0e10cSrcweir 		IEnumSTATDATA* pEnumSD = NULL;
690*cdf0e10cSrcweir 		HRESULT hr = pIOleCache->EnumCache( &pEnumSD );
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir 		if ( SUCCEEDED( hr ) && pEnumSD )
693*cdf0e10cSrcweir 		{
694*cdf0e10cSrcweir 			pEnumSD->Reset();
695*cdf0e10cSrcweir 			STATDATA aSD;
696*cdf0e10cSrcweir 			DWORD nNum;
697*cdf0e10cSrcweir 			while( SUCCEEDED( pEnumSD->Next( 1, &aSD, &nNum ) ) && nNum == 1 )
698*cdf0e10cSrcweir 				hr = pIOleCache->Uncache( aSD.dwConnection );
699*cdf0e10cSrcweir 		}
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir 		// No IDataObject implementation, caching must be used instead
702*cdf0e10cSrcweir 		DWORD nConn;
703*cdf0e10cSrcweir 		FORMATETC aFormat = { 0, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT };
704*cdf0e10cSrcweir 		hr = pIOleCache->Cache( &aFormat, ADVFCACHE_ONSAVE, &nConn );
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir 		pIOleCache->Release();
707*cdf0e10cSrcweir 		pIOleCache = NULL;
708*cdf0e10cSrcweir 	}
709*cdf0e10cSrcweir 
710*cdf0e10cSrcweir 	hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IOleObject, (void**)&m_pNativeImpl->m_pOleObject );
711*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pOleObject )
712*cdf0e10cSrcweir 		return sal_False; // Static objects are not supported, they should be inserted as graphics
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir 	m_pNativeImpl->m_pOleObject->GetMiscStatus( DVASPECT_CONTENT, ( DWORD* )&m_nOLEMiscFlags );
715*cdf0e10cSrcweir 	// TODO: use other misc flags also
716*cdf0e10cSrcweir 	// the object should have drawable aspect even in case it supports only iconic representation
717*cdf0e10cSrcweir 	// if ( m_nOLEMiscFlags & OLEMISC_ONLYICONIC )
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir 	m_pNativeImpl->m_pOleObject->SetClientSite( m_pOleWrapClientSite );
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir 	// the only need in this registration is workaround for close notification
722*cdf0e10cSrcweir 	m_pNativeImpl->m_pOleObject->Advise( m_pImplAdviseSink, ( DWORD* )&m_nAdvConn );
723*cdf0e10cSrcweir     m_pNativeImpl->m_pViewObject2->SetAdvise( DVASPECT_CONTENT, 0, m_pImplAdviseSink );
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir 	OleSetContainedObject( m_pNativeImpl->m_pOleObject, TRUE );
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir 	return sal_True;
728*cdf0e10cSrcweir }
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir //----------------------------------------------
731*cdf0e10cSrcweir void OleComponent::LoadEmbeddedObject( const ::rtl::OUString& aTempURL )
732*cdf0e10cSrcweir {
733*cdf0e10cSrcweir 	if ( !aTempURL.getLength() )
734*cdf0e10cSrcweir 		throw lang::IllegalArgumentException(); // TODO
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pIStorage )
737*cdf0e10cSrcweir 		throw io::IOException(); // TODO the object is already initialized or wrong initialization is done
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir 	// open an IStorage based on the temporary file
740*cdf0e10cSrcweir 	HRESULT hr = OpenIStorageFromURL_Impl( aTempURL, &m_pNativeImpl->m_pIStorage );
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pIStorage )
743*cdf0e10cSrcweir 		throw io::IOException(); // TODO: transport error code?
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir 	hr = OleLoad( m_pNativeImpl->m_pIStorage, IID_IUnknown, NULL, (void**)&m_pNativeImpl->m_pObj );
746*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
747*cdf0e10cSrcweir 	{
748*cdf0e10cSrcweir 		// STATSTG aStat;
749*cdf0e10cSrcweir 		// m_pNativeImpl->m_pIStorage->Stat( &aStat, STATFLAG_NONAME );
750*cdf0e10cSrcweir 		throw uno::RuntimeException();
751*cdf0e10cSrcweir 	}
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir 	if ( !InitializeObject_Impl() )
754*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
755*cdf0e10cSrcweir }
756*cdf0e10cSrcweir 
757*cdf0e10cSrcweir //----------------------------------------------
758*cdf0e10cSrcweir void OleComponent::CreateObjectFromClipboard()
759*cdf0e10cSrcweir {
760*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pIStorage )
761*cdf0e10cSrcweir 		throw io::IOException(); // TODO:the object is already initialized
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir 	CreateNewIStorage_Impl();
764*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pIStorage )
765*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir 	IDataObject * pDO = NULL;
768*cdf0e10cSrcweir 	HRESULT hr = OleGetClipboard( &pDO );
769*cdf0e10cSrcweir 	if( SUCCEEDED( hr ) && pDO )
770*cdf0e10cSrcweir 	{
771*cdf0e10cSrcweir 		hr = OleQueryCreateFromData( pDO );
772*cdf0e10cSrcweir 		if( S_OK == GetScode( hr ) )
773*cdf0e10cSrcweir 		{
774*cdf0e10cSrcweir 			hr = OleCreateFromData( pDO,
775*cdf0e10cSrcweir 									IID_IUnknown,
776*cdf0e10cSrcweir 									OLERENDER_DRAW, // OLERENDER_FORMAT
777*cdf0e10cSrcweir 									NULL, 			// &aFormat,
778*cdf0e10cSrcweir 									NULL,
779*cdf0e10cSrcweir 									m_pNativeImpl->m_pIStorage,
780*cdf0e10cSrcweir 									(void**)&m_pNativeImpl->m_pObj );
781*cdf0e10cSrcweir 		}
782*cdf0e10cSrcweir 		else
783*cdf0e10cSrcweir 		{
784*cdf0e10cSrcweir 			// Static objects are not supported
785*cdf0e10cSrcweir 			pDO->Release();
786*cdf0e10cSrcweir 		}
787*cdf0e10cSrcweir 	}
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
790*cdf0e10cSrcweir 		throw uno::RuntimeException();
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir 	if ( !InitializeObject_Impl() )
793*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
794*cdf0e10cSrcweir }
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir //----------------------------------------------
797*cdf0e10cSrcweir void OleComponent::CreateNewEmbeddedObject( const uno::Sequence< sal_Int8 >& aSeqCLSID )
798*cdf0e10cSrcweir {
799*cdf0e10cSrcweir 	CLSID aClsID;
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir 	if ( !GetClassIDFromSequence_Impl( aSeqCLSID, aClsID ) )
802*cdf0e10cSrcweir 		throw lang::IllegalArgumentException(); // TODO
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pIStorage )
805*cdf0e10cSrcweir 		throw io::IOException(); // TODO:the object is already initialized
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir 	CreateNewIStorage_Impl();
808*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pIStorage )
809*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir 	// FORMATETC aFormat = { CF_METAFILEPICT, NULL, nAspect, -1, TYMED_MFPICT }; // for OLE..._DRAW should be NULL
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir 	HRESULT hr = OleCreate( aClsID,
814*cdf0e10cSrcweir 							IID_IUnknown,
815*cdf0e10cSrcweir 							OLERENDER_DRAW, // OLERENDER_FORMAT
816*cdf0e10cSrcweir 							NULL, 			// &aFormat,
817*cdf0e10cSrcweir 							NULL,
818*cdf0e10cSrcweir 							m_pNativeImpl->m_pIStorage,
819*cdf0e10cSrcweir 							(void**)&m_pNativeImpl->m_pObj );
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
822*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir 	if ( !InitializeObject_Impl() )
825*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir 	// TODO: getExtent???
828*cdf0e10cSrcweir }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir //----------------------------------------------
831*cdf0e10cSrcweir void OleComponent::CreateObjectFromData( const uno::Reference< datatransfer::XTransferable >& )
832*cdf0e10cSrcweir // Static objects are not supported, they should be inserted as graphics
833*cdf0e10cSrcweir {
834*cdf0e10cSrcweir 	// TODO: May be this call is useless since there are no static objects
835*cdf0e10cSrcweir 	//		 and nonstatic objects will be created based on OLEstorage ( stream ).
836*cdf0e10cSrcweir 	//		 ???
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 	// OleQueryCreateFromData...
839*cdf0e10cSrcweir }
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir //----------------------------------------------
842*cdf0e10cSrcweir void OleComponent::CreateObjectFromFile( const ::rtl::OUString& aFileURL )
843*cdf0e10cSrcweir {
844*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pIStorage )
845*cdf0e10cSrcweir 		throw io::IOException(); // TODO:the object is already initialized
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir 	CreateNewIStorage_Impl();
848*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pIStorage )
849*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO:
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir 	::rtl::OUString aFilePath;
852*cdf0e10cSrcweir 	if ( ::osl::FileBase::getSystemPathFromFileURL( aFileURL, aFilePath ) != ::osl::FileBase::E_None )
853*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO: something dangerous happend
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir 	HRESULT hr = OleCreateFromFile( CLSID_NULL,
856*cdf0e10cSrcweir 									reinterpret_cast<LPCWSTR>(aFilePath.getStr()),
857*cdf0e10cSrcweir 									IID_IUnknown,
858*cdf0e10cSrcweir 									OLERENDER_DRAW, // OLERENDER_FORMAT
859*cdf0e10cSrcweir 									NULL,
860*cdf0e10cSrcweir 									NULL,
861*cdf0e10cSrcweir 									m_pNativeImpl->m_pIStorage,
862*cdf0e10cSrcweir 									(void**)&m_pNativeImpl->m_pObj );
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
865*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir 	if ( !InitializeObject_Impl() )
868*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
869*cdf0e10cSrcweir }
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir //----------------------------------------------
872*cdf0e10cSrcweir void OleComponent::CreateLinkFromFile( const ::rtl::OUString& aFileURL )
873*cdf0e10cSrcweir {
874*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pIStorage )
875*cdf0e10cSrcweir 		throw io::IOException(); // TODO:the object is already initialized
876*cdf0e10cSrcweir 
877*cdf0e10cSrcweir 	CreateNewIStorage_Impl();
878*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pIStorage )
879*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO:
880*cdf0e10cSrcweir 
881*cdf0e10cSrcweir 	::rtl::OUString aFilePath;
882*cdf0e10cSrcweir 	if ( ::osl::FileBase::getSystemPathFromFileURL( aFileURL, aFilePath ) != ::osl::FileBase::E_None )
883*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO: something dangerous happend
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir 	HRESULT hr = OleCreateLinkToFile( reinterpret_cast<LPCWSTR>(aFilePath.getStr()),
886*cdf0e10cSrcweir 										IID_IUnknown,
887*cdf0e10cSrcweir 										OLERENDER_DRAW, // OLERENDER_FORMAT
888*cdf0e10cSrcweir 										NULL,
889*cdf0e10cSrcweir 										NULL,
890*cdf0e10cSrcweir 										m_pNativeImpl->m_pIStorage,
891*cdf0e10cSrcweir 										(void**)&m_pNativeImpl->m_pObj );
892*cdf0e10cSrcweir 
893*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
894*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir 	if ( !InitializeObject_Impl() )
897*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
898*cdf0e10cSrcweir }
899*cdf0e10cSrcweir 
900*cdf0e10cSrcweir //----------------------------------------------
901*cdf0e10cSrcweir void OleComponent::InitEmbeddedCopyOfLink( OleComponent* pOleLinkComponent )
902*cdf0e10cSrcweir {
903*cdf0e10cSrcweir 	if ( !pOleLinkComponent || !pOleLinkComponent->m_pNativeImpl->m_pObj )
904*cdf0e10cSrcweir 		throw lang::IllegalArgumentException(); // TODO
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pIStorage )
907*cdf0e10cSrcweir 		throw io::IOException(); // TODO:the object is already initialized
908*cdf0e10cSrcweir 
909*cdf0e10cSrcweir 	ComSmart< IDataObject > pDataObject;
910*cdf0e10cSrcweir 	HRESULT hr = pOleLinkComponent->m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, (void**)&pDataObject );
911*cdf0e10cSrcweir 	if ( SUCCEEDED( hr ) && pDataObject && SUCCEEDED( OleQueryCreateFromData( pDataObject ) ) )
912*cdf0e10cSrcweir 	{
913*cdf0e10cSrcweir 		// the object must be already disconnected from the temporary URL
914*cdf0e10cSrcweir 		CreateNewIStorage_Impl();
915*cdf0e10cSrcweir 		if ( !m_pNativeImpl->m_pIStorage )
916*cdf0e10cSrcweir 			throw uno::RuntimeException(); // TODO:
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir 		hr = OleCreateFromData( pDataObject,
919*cdf0e10cSrcweir 								IID_IUnknown,
920*cdf0e10cSrcweir 								OLERENDER_DRAW,
921*cdf0e10cSrcweir 								NULL,
922*cdf0e10cSrcweir 								NULL,
923*cdf0e10cSrcweir 								m_pNativeImpl->m_pIStorage,
924*cdf0e10cSrcweir 								(void**)&m_pNativeImpl->m_pObj );
925*cdf0e10cSrcweir 	}
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pObj )
928*cdf0e10cSrcweir 	{
929*cdf0e10cSrcweir 		ComSmart< IOleLink > pOleLink;
930*cdf0e10cSrcweir 		hr = pOleLinkComponent->m_pNativeImpl->m_pObj->QueryInterface( IID_IOleLink, (void**)&pOleLink );
931*cdf0e10cSrcweir 		if ( FAILED( hr ) || !pOleLink )
932*cdf0e10cSrcweir 			throw io::IOException(); // TODO: the object doesn't support IOleLink
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir 		ComSmart< IMoniker > pMoniker;
935*cdf0e10cSrcweir 		hr = pOleLink->GetSourceMoniker( &pMoniker );
936*cdf0e10cSrcweir 		if ( FAILED( hr ) || !pMoniker )
937*cdf0e10cSrcweir 			throw io::IOException(); // TODO: can not retrieve moniker
938*cdf0e10cSrcweir 
939*cdf0e10cSrcweir 		// In case of file moniker life is easy : )
940*cdf0e10cSrcweir 		DWORD aMonType = 0;
941*cdf0e10cSrcweir 		hr = pMoniker->IsSystemMoniker( &aMonType );
942*cdf0e10cSrcweir 		if ( SUCCEEDED( hr ) && aMonType == MKSYS_FILEMONIKER )
943*cdf0e10cSrcweir 		{
944*cdf0e10cSrcweir 			ComSmart< IMalloc > pMalloc;
945*cdf0e10cSrcweir 			CoGetMalloc( 1, &pMalloc ); // if fails there will be a memory leak
946*cdf0e10cSrcweir 			OSL_ENSURE( pMalloc, "CoGetMalloc() failed!" );
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir 			LPOLESTR pOleStr = NULL;
949*cdf0e10cSrcweir 			hr = pOleLink->GetSourceDisplayName( &pOleStr );
950*cdf0e10cSrcweir 			if ( SUCCEEDED( hr ) && pOleStr )
951*cdf0e10cSrcweir 			{
952*cdf0e10cSrcweir 				::rtl::OUString aFilePath( ( sal_Unicode* )pOleStr );
953*cdf0e10cSrcweir 				if ( pMalloc )
954*cdf0e10cSrcweir 					pMalloc->Free( ( void* )pOleStr );
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir 				hr = OleCreateFromFile( CLSID_NULL,
957*cdf0e10cSrcweir 										reinterpret_cast<LPCWSTR>(aFilePath.getStr()),
958*cdf0e10cSrcweir 										IID_IUnknown,
959*cdf0e10cSrcweir 										OLERENDER_DRAW, // OLERENDER_FORMAT
960*cdf0e10cSrcweir 										NULL,
961*cdf0e10cSrcweir 										NULL,
962*cdf0e10cSrcweir 										m_pNativeImpl->m_pIStorage,
963*cdf0e10cSrcweir 										(void**)&m_pNativeImpl->m_pObj );
964*cdf0e10cSrcweir 			}
965*cdf0e10cSrcweir 		}
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir 		// in case of other moniker types the only way is to get storage
968*cdf0e10cSrcweir 		if ( !m_pNativeImpl->m_pObj )
969*cdf0e10cSrcweir 		{
970*cdf0e10cSrcweir 			ComSmart< IBindCtx > pBindCtx;
971*cdf0e10cSrcweir 			hr = CreateBindCtx( 0, ( LPBC FAR* )&pBindCtx );
972*cdf0e10cSrcweir 			if ( SUCCEEDED( hr ) && pBindCtx )
973*cdf0e10cSrcweir 			{
974*cdf0e10cSrcweir 				ComSmart< IStorage > pObjectStorage;
975*cdf0e10cSrcweir 				hr = pMoniker->BindToStorage( pBindCtx, NULL, IID_IStorage, (void**)&pObjectStorage );
976*cdf0e10cSrcweir 				if ( SUCCEEDED( hr ) && pObjectStorage )
977*cdf0e10cSrcweir 				{
978*cdf0e10cSrcweir 					hr = pObjectStorage->CopyTo( 0, NULL, NULL, m_pNativeImpl->m_pIStorage );
979*cdf0e10cSrcweir 					if ( SUCCEEDED( hr ) )
980*cdf0e10cSrcweir 						hr = OleLoad( m_pNativeImpl->m_pIStorage, IID_IUnknown, NULL, (void**)&m_pNativeImpl->m_pObj );
981*cdf0e10cSrcweir 				}
982*cdf0e10cSrcweir 			}
983*cdf0e10cSrcweir 		}
984*cdf0e10cSrcweir 	}
985*cdf0e10cSrcweir 
986*cdf0e10cSrcweir 	// If object could not be created the only way is to use graphical representation
987*cdf0e10cSrcweir 	if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
988*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
989*cdf0e10cSrcweir 
990*cdf0e10cSrcweir 	if ( !InitializeObject_Impl() )
991*cdf0e10cSrcweir 		throw uno::RuntimeException(); // TODO
992*cdf0e10cSrcweir }
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir //----------------------------------------------
995*cdf0e10cSrcweir void OleComponent::RunObject()
996*cdf0e10cSrcweir {
997*cdf0e10cSrcweir 	OSL_ENSURE( m_pNativeImpl->m_pOleObject, "The pointer can not be set to NULL here!\n" );
998*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
999*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir 	if ( !OleIsRunning( m_pNativeImpl->m_pOleObject ) )
1002*cdf0e10cSrcweir 	{
1003*cdf0e10cSrcweir 		HRESULT hr = S_OK;
1004*cdf0e10cSrcweir 		try
1005*cdf0e10cSrcweir 		{
1006*cdf0e10cSrcweir 			hr = OleRun( m_pNativeImpl->m_pObj );
1007*cdf0e10cSrcweir 		}
1008*cdf0e10cSrcweir 		catch( ... )
1009*cdf0e10cSrcweir 		{
1010*cdf0e10cSrcweir 			int i = 0;
1011*cdf0e10cSrcweir 			i++;
1012*cdf0e10cSrcweir 		}
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir 		if ( FAILED( hr ) )
1015*cdf0e10cSrcweir 		{
1016*cdf0e10cSrcweir 			if ( hr == REGDB_E_CLASSNOTREG )
1017*cdf0e10cSrcweir 				throw embed::UnreachableStateException(); // the object server is not installed
1018*cdf0e10cSrcweir 			else
1019*cdf0e10cSrcweir 				throw io::IOException();
1020*cdf0e10cSrcweir 		}
1021*cdf0e10cSrcweir 	}
1022*cdf0e10cSrcweir }
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir //----------------------------------------------
1025*cdf0e10cSrcweir awt::Size OleComponent::CalculateWithFactor( const awt::Size& aSize,
1026*cdf0e10cSrcweir 											const awt::Size& aMultiplier,
1027*cdf0e10cSrcweir 											const awt::Size& aDivisor )
1028*cdf0e10cSrcweir {
1029*cdf0e10cSrcweir 	awt::Size aResult;
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir 	sal_Int64 nWidth = (sal_Int64)aSize.Width * (sal_Int64)aMultiplier.Width / (sal_Int64)aDivisor.Width;
1032*cdf0e10cSrcweir 	sal_Int64 nHeight = (sal_Int64)aSize.Height * (sal_Int64)aMultiplier.Height / (sal_Int64)aDivisor.Height;
1033*cdf0e10cSrcweir 	OSL_ENSURE( nWidth < SAL_MAX_INT32 && nWidth > SAL_MIN_INT32
1034*cdf0e10cSrcweir 			 && nHeight < SAL_MAX_INT32 && nHeight > SAL_MIN_INT32,
1035*cdf0e10cSrcweir 			 "Unacceptable result size!" );
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir 	aResult.Width = (sal_Int32)nWidth;
1038*cdf0e10cSrcweir 	aResult.Height = (sal_Int32)nHeight;
1039*cdf0e10cSrcweir 
1040*cdf0e10cSrcweir 	return aResult;
1041*cdf0e10cSrcweir }
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir //----------------------------------------------
1044*cdf0e10cSrcweir void OleComponent::CloseObject()
1045*cdf0e10cSrcweir {
1046*cdf0e10cSrcweir 	if ( m_pNativeImpl->m_pOleObject && OleIsRunning( m_pNativeImpl->m_pOleObject ) )
1047*cdf0e10cSrcweir 		m_pNativeImpl->m_pOleObject->Close( OLECLOSE_NOSAVE ); // must be saved before
1048*cdf0e10cSrcweir }
1049*cdf0e10cSrcweir 
1050*cdf0e10cSrcweir //----------------------------------------------
1051*cdf0e10cSrcweir uno::Sequence< embed::VerbDescriptor > OleComponent::GetVerbList()
1052*cdf0e10cSrcweir {
1053*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1054*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir 	if( !m_aVerbList.getLength() )
1057*cdf0e10cSrcweir 	{
1058*cdf0e10cSrcweir 		ComSmart< IEnumOLEVERB > pEnum;
1059*cdf0e10cSrcweir 		if( SUCCEEDED( m_pNativeImpl->m_pOleObject->EnumVerbs( &pEnum ) ) )
1060*cdf0e10cSrcweir 		{
1061*cdf0e10cSrcweir 			OLEVERB     szEle[ MAX_ENUM_ELE ];
1062*cdf0e10cSrcweir 			ULONG       nNum = 0;
1063*cdf0e10cSrcweir 			sal_Int32	nSeqSize = 0;
1064*cdf0e10cSrcweir 
1065*cdf0e10cSrcweir 			do
1066*cdf0e10cSrcweir 			{
1067*cdf0e10cSrcweir 				HRESULT hr = pEnum->Next( MAX_ENUM_ELE, szEle, &nNum );
1068*cdf0e10cSrcweir 				if( hr == S_OK || hr == S_FALSE )
1069*cdf0e10cSrcweir 				{
1070*cdf0e10cSrcweir 					m_aVerbList.realloc( nSeqSize += nNum );
1071*cdf0e10cSrcweir 					for( sal_uInt32 nInd = 0; nInd < nNum; nInd++ )
1072*cdf0e10cSrcweir 					{
1073*cdf0e10cSrcweir 						m_aVerbList[nSeqSize-nNum+nInd].VerbID = szEle[ nInd ].lVerb;
1074*cdf0e10cSrcweir 						m_aVerbList[nSeqSize-nNum+nInd].VerbName = WinAccToVcl_Impl( reinterpret_cast<const sal_Unicode*>(szEle[ nInd ].lpszVerbName) );
1075*cdf0e10cSrcweir 						m_aVerbList[nSeqSize-nNum+nInd].VerbFlags = szEle[ nInd ].fuFlags;
1076*cdf0e10cSrcweir 						m_aVerbList[nSeqSize-nNum+nInd].VerbAttributes = szEle[ nInd ].grfAttribs;
1077*cdf0e10cSrcweir 					}
1078*cdf0e10cSrcweir 				}
1079*cdf0e10cSrcweir 				else
1080*cdf0e10cSrcweir 					break;
1081*cdf0e10cSrcweir 			}
1082*cdf0e10cSrcweir 			while( nNum == MAX_ENUM_ELE );
1083*cdf0e10cSrcweir 		}
1084*cdf0e10cSrcweir 	}
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir 	return m_aVerbList;
1087*cdf0e10cSrcweir }
1088*cdf0e10cSrcweir 
1089*cdf0e10cSrcweir //----------------------------------------------
1090*cdf0e10cSrcweir void OleComponent::ExecuteVerb( sal_Int32 nVerbID )
1091*cdf0e10cSrcweir {
1092*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1093*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO
1094*cdf0e10cSrcweir 
1095*cdf0e10cSrcweir 	HRESULT hr = OleRun( m_pNativeImpl->m_pOleObject );
1096*cdf0e10cSrcweir 	if ( FAILED( hr ) )
1097*cdf0e10cSrcweir 		throw io::IOException(); // TODO: a specific exception that transport error code can be thrown here
1098*cdf0e10cSrcweir 
1099*cdf0e10cSrcweir 	// TODO: probably extents should be set here and stored in aRect
1100*cdf0e10cSrcweir 	// TODO: probably the parent window also should be set
1101*cdf0e10cSrcweir 	hr = m_pNativeImpl->m_pOleObject->DoVerb( nVerbID, NULL, m_pOleWrapClientSite, 0, NULL, NULL );
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir 	if ( FAILED( hr ) )
1104*cdf0e10cSrcweir 		throw io::IOException(); // TODO
1105*cdf0e10cSrcweir 
1106*cdf0e10cSrcweir 	// TODO/LATER: the real names should be used here
1107*cdf0e10cSrcweir 	m_pNativeImpl->m_pOleObject->SetHostNames( L"app name", L"untitled" );
1108*cdf0e10cSrcweir }
1109*cdf0e10cSrcweir 
1110*cdf0e10cSrcweir //----------------------------------------------
1111*cdf0e10cSrcweir void OleComponent::SetHostName( const ::rtl::OUString&,
1112*cdf0e10cSrcweir 								const ::rtl::OUString& )
1113*cdf0e10cSrcweir {
1114*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1115*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir 	// TODO: use aContName and aEmbDocName in m_pNativeImpl->m_pOleObject->SetHostNames()
1118*cdf0e10cSrcweir }
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir //----------------------------------------------
1121*cdf0e10cSrcweir void OleComponent::SetExtent( const awt::Size& aVisAreaSize, sal_Int64 nAspect )
1122*cdf0e10cSrcweir {
1123*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1124*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1125*cdf0e10cSrcweir 
1126*cdf0e10cSrcweir 	DWORD nMSAspect = ( DWORD )nAspect; // first 32 bits are for MS aspects
1127*cdf0e10cSrcweir 
1128*cdf0e10cSrcweir 	SIZEL aSize = { aVisAreaSize.Width, aVisAreaSize.Height };
1129*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pOleObject->SetExtent( nMSAspect, &aSize );
1130*cdf0e10cSrcweir 
1131*cdf0e10cSrcweir 	if ( FAILED( hr ) )
1132*cdf0e10cSrcweir 	{
1133*cdf0e10cSrcweir 		// TODO/LATER: is it correct? In future user code probably should be ready for the exception.
1134*cdf0e10cSrcweir 		// if the object is running but not activated, RPC_E_SERVER_DIED error code is returned by OLE package
1135*cdf0e10cSrcweir 		// in this case just do nothing
1136*cdf0e10cSrcweir 		// Also Visio returns E_FAIL on resize if it is in running state
1137*cdf0e10cSrcweir 		// if ( hr != RPC_E_SERVER_DIED )
1138*cdf0e10cSrcweir 		throw io::IOException(); // TODO
1139*cdf0e10cSrcweir 	}
1140*cdf0e10cSrcweir }
1141*cdf0e10cSrcweir 
1142*cdf0e10cSrcweir //----------------------------------------------
1143*cdf0e10cSrcweir awt::Size OleComponent::GetExtent( sal_Int64 nAspect )
1144*cdf0e10cSrcweir {
1145*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1146*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1147*cdf0e10cSrcweir 
1148*cdf0e10cSrcweir 	DWORD nMSAspect = ( DWORD )nAspect; // first 32 bits are for MS aspects
1149*cdf0e10cSrcweir 	awt::Size aSize;
1150*cdf0e10cSrcweir 	sal_Bool bGotSize = sal_False;
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir 	if ( nMSAspect == DVASPECT_CONTENT )
1153*cdf0e10cSrcweir 	{
1154*cdf0e10cSrcweir 		// Try to get the size from the replacement image first
1155*cdf0e10cSrcweir 		ComSmart< IDataObject > pDataObject;
1156*cdf0e10cSrcweir 		HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, (void**)&pDataObject );
1157*cdf0e10cSrcweir 		if ( SUCCEEDED( hr ) || pDataObject )
1158*cdf0e10cSrcweir 		{
1159*cdf0e10cSrcweir 			STGMEDIUM aMedium;
1160*cdf0e10cSrcweir 			FORMATETC aFormat = pFormatTemplates[1]; // use windows metafile format
1161*cdf0e10cSrcweir 			aFormat.dwAspect = nMSAspect;
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir 			hr = pDataObject->GetData( &aFormat, &aMedium );
1164*cdf0e10cSrcweir 			if ( SUCCEEDED( hr ) && aMedium.tymed == TYMED_MFPICT ) // Win Metafile
1165*cdf0e10cSrcweir 			{
1166*cdf0e10cSrcweir 				METAFILEPICT* pMF = ( METAFILEPICT* )GlobalLock( aMedium.hMetaFilePict );
1167*cdf0e10cSrcweir 				if ( pMF )
1168*cdf0e10cSrcweir 				{
1169*cdf0e10cSrcweir 					// the object uses 0.01 mm as unit, so the metafile size should be converted to object unit
1170*cdf0e10cSrcweir 					sal_Int64 nMult = 1;
1171*cdf0e10cSrcweir 					sal_Int64 nDiv = 1;
1172*cdf0e10cSrcweir 					switch( pMF->mm )
1173*cdf0e10cSrcweir 					{
1174*cdf0e10cSrcweir 						case MM_HIENGLISH:
1175*cdf0e10cSrcweir 							nMult = 254;
1176*cdf0e10cSrcweir 							nDiv = 100;
1177*cdf0e10cSrcweir 							break;
1178*cdf0e10cSrcweir 
1179*cdf0e10cSrcweir 						case MM_LOENGLISH:
1180*cdf0e10cSrcweir 							nMult = 254;
1181*cdf0e10cSrcweir 							nDiv = 10;
1182*cdf0e10cSrcweir 							break;
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir 						case MM_LOMETRIC:
1185*cdf0e10cSrcweir 							nMult = 10;
1186*cdf0e10cSrcweir 							break;
1187*cdf0e10cSrcweir 
1188*cdf0e10cSrcweir 						case MM_TWIPS:
1189*cdf0e10cSrcweir 							nMult = 254;
1190*cdf0e10cSrcweir 							nDiv = 144;
1191*cdf0e10cSrcweir 							break;
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir 						case MM_ISOTROPIC:
1194*cdf0e10cSrcweir 						case MM_ANISOTROPIC:
1195*cdf0e10cSrcweir 						case MM_HIMETRIC:
1196*cdf0e10cSrcweir 							// do nothing
1197*cdf0e10cSrcweir 							break;
1198*cdf0e10cSrcweir 					}
1199*cdf0e10cSrcweir 
1200*cdf0e10cSrcweir 					sal_Int64 nX = ( (sal_Int64)abs( pMF->xExt ) ) * nMult / nDiv;
1201*cdf0e10cSrcweir 					sal_Int64 nY = ( (sal_Int64)abs( pMF->yExt ) ) * nMult / nDiv;
1202*cdf0e10cSrcweir 					if (  nX < SAL_MAX_INT32 && nY < SAL_MAX_INT32 )
1203*cdf0e10cSrcweir 					{
1204*cdf0e10cSrcweir 						aSize.Width = ( sal_Int32 )nX;
1205*cdf0e10cSrcweir 						aSize.Height = ( sal_Int32 )nY;
1206*cdf0e10cSrcweir 						bGotSize = sal_True;
1207*cdf0e10cSrcweir 					}
1208*cdf0e10cSrcweir 					else
1209*cdf0e10cSrcweir 						OSL_ENSURE( sal_False, "Unexpected size is provided!" );
1210*cdf0e10cSrcweir 				}
1211*cdf0e10cSrcweir 			}
1212*cdf0e10cSrcweir 		}
1213*cdf0e10cSrcweir 	}
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir 	if ( !bGotSize )
1216*cdf0e10cSrcweir 		throw lang::IllegalArgumentException();
1217*cdf0e10cSrcweir 
1218*cdf0e10cSrcweir 	return aSize;
1219*cdf0e10cSrcweir }
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir //----------------------------------------------
1222*cdf0e10cSrcweir awt::Size OleComponent::GetCachedExtent( sal_Int64 nAspect )
1223*cdf0e10cSrcweir {
1224*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1225*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir 	DWORD nMSAspect = ( DWORD )nAspect; // first 32 bits are for MS aspects
1228*cdf0e10cSrcweir 	SIZEL aSize;
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pViewObject2->GetExtent( nMSAspect, -1, NULL, &aSize );
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir 	if ( FAILED( hr ) )
1233*cdf0e10cSrcweir 	{
1234*cdf0e10cSrcweir 		// TODO/LATER: is it correct?
1235*cdf0e10cSrcweir 		// if there is no appropriate cache for the aspect, OLE_E_BLANK error code is returned
1236*cdf0e10cSrcweir 		// if ( hr == OLE_E_BLANK )
1237*cdf0e10cSrcweir 		//	throw lang::IllegalArgumentException();
1238*cdf0e10cSrcweir 		//else
1239*cdf0e10cSrcweir 		//	throw io::IOException(); // TODO
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir 		throw lang::IllegalArgumentException();
1242*cdf0e10cSrcweir 	}
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir 	return awt::Size( aSize.cx, aSize.cy );
1245*cdf0e10cSrcweir }
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir //----------------------------------------------
1248*cdf0e10cSrcweir awt::Size OleComponent::GetReccomendedExtent( sal_Int64 nAspect )
1249*cdf0e10cSrcweir {
1250*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1251*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1252*cdf0e10cSrcweir 
1253*cdf0e10cSrcweir 	DWORD nMSAspect = ( DWORD )nAspect; // first 32 bits are for MS aspects
1254*cdf0e10cSrcweir 	SIZEL aSize;
1255*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pOleObject->GetExtent( nMSAspect, &aSize );
1256*cdf0e10cSrcweir 	if ( FAILED( hr ) )
1257*cdf0e10cSrcweir 		throw lang::IllegalArgumentException();
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir 	return awt::Size( aSize.cx, aSize.cy );
1260*cdf0e10cSrcweir }
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir //----------------------------------------------
1263*cdf0e10cSrcweir sal_Int64 OleComponent::GetMiscStatus( sal_Int64 nAspect )
1264*cdf0e10cSrcweir {
1265*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1266*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir 	sal_uInt32 nResult;
1269*cdf0e10cSrcweir 	m_pNativeImpl->m_pOleObject->GetMiscStatus( ( DWORD )nAspect, ( DWORD* )&nResult );
1270*cdf0e10cSrcweir 	return ( sal_Int64 )nResult; // first 32 bits are for MS flags
1271*cdf0e10cSrcweir }
1272*cdf0e10cSrcweir 
1273*cdf0e10cSrcweir //----------------------------------------------
1274*cdf0e10cSrcweir uno::Sequence< sal_Int8 > OleComponent::GetCLSID()
1275*cdf0e10cSrcweir {
1276*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1277*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1278*cdf0e10cSrcweir 
1279*cdf0e10cSrcweir 	GUID aCLSID;
1280*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pOleObject->GetUserClassID( &aCLSID );
1281*cdf0e10cSrcweir 	if ( FAILED( hr ) )
1282*cdf0e10cSrcweir 		throw io::IOException(); // TODO:
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir 	return  MimeConfigurationHelper::GetSequenceClassID( aCLSID.Data1, aCLSID.Data2, aCLSID.Data3,
1285*cdf0e10cSrcweir 								aCLSID.Data4[0], aCLSID.Data4[1],
1286*cdf0e10cSrcweir 								aCLSID.Data4[2], aCLSID.Data4[3],
1287*cdf0e10cSrcweir 								aCLSID.Data4[4], aCLSID.Data4[5],
1288*cdf0e10cSrcweir 								aCLSID.Data4[6], aCLSID.Data4[7] );
1289*cdf0e10cSrcweir }
1290*cdf0e10cSrcweir 
1291*cdf0e10cSrcweir //----------------------------------------------
1292*cdf0e10cSrcweir sal_Bool OleComponent::IsDirty()
1293*cdf0e10cSrcweir {
1294*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1295*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir 	if ( IsWorkaroundActive() )
1298*cdf0e10cSrcweir 		return sal_True;
1299*cdf0e10cSrcweir 
1300*cdf0e10cSrcweir 	ComSmart< IPersistStorage > pPersistStorage;
1301*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IPersistStorage, (void**)&pPersistStorage );
1302*cdf0e10cSrcweir 	if ( FAILED( hr ) || !pPersistStorage )
1303*cdf0e10cSrcweir 		throw io::IOException(); // TODO
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir 	hr = pPersistStorage->IsDirty();
1306*cdf0e10cSrcweir 	return ( hr != S_FALSE );
1307*cdf0e10cSrcweir }
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir //----------------------------------------------
1310*cdf0e10cSrcweir void OleComponent::StoreOwnTmpIfNecessary()
1311*cdf0e10cSrcweir {
1312*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1313*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1314*cdf0e10cSrcweir 
1315*cdf0e10cSrcweir 	ComSmart< IPersistStorage > pPersistStorage;
1316*cdf0e10cSrcweir 	HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IPersistStorage, (void**)&pPersistStorage );
1317*cdf0e10cSrcweir 	if ( FAILED( hr ) || !pPersistStorage )
1318*cdf0e10cSrcweir 		throw io::IOException(); // TODO
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir 	if ( m_bWorkaroundActive || pPersistStorage->IsDirty() != S_FALSE )
1321*cdf0e10cSrcweir 	{
1322*cdf0e10cSrcweir 		hr = OleSave( pPersistStorage, m_pNativeImpl->m_pIStorage, TRUE );
1323*cdf0e10cSrcweir 		if ( FAILED( hr ) )
1324*cdf0e10cSrcweir 		{
1325*cdf0e10cSrcweir 			// Till now was required only for AcrobatReader7.0.8
1326*cdf0e10cSrcweir 			GUID aCLSID;
1327*cdf0e10cSrcweir 			hr = m_pNativeImpl->m_pOleObject->GetUserClassID( &aCLSID );
1328*cdf0e10cSrcweir 			if ( FAILED( hr ) )
1329*cdf0e10cSrcweir 				throw io::IOException(); // TODO
1330*cdf0e10cSrcweir 
1331*cdf0e10cSrcweir 			hr = WriteClassStg( m_pNativeImpl->m_pIStorage, aCLSID );
1332*cdf0e10cSrcweir 			if ( FAILED( hr ) )
1333*cdf0e10cSrcweir 				throw io::IOException(); // TODO
1334*cdf0e10cSrcweir 
1335*cdf0e10cSrcweir 			// the result of the following call is not checked because some objects, for example AcrobatReader7.0.8
1336*cdf0e10cSrcweir 			// return error even in case the saving was done correctly
1337*cdf0e10cSrcweir 			hr = pPersistStorage->Save( m_pNativeImpl->m_pIStorage, TRUE );
1338*cdf0e10cSrcweir 
1339*cdf0e10cSrcweir 			// another workaround for AcrobatReader7.0.8 object, this object might think that it is not changed
1340*cdf0e10cSrcweir 			// when it has been created from file, although it must be saved
1341*cdf0e10cSrcweir 			m_bWorkaroundActive = sal_True;
1342*cdf0e10cSrcweir 		}
1343*cdf0e10cSrcweir 
1344*cdf0e10cSrcweir 		hr = m_pNativeImpl->m_pIStorage->Commit( STGC_DEFAULT );
1345*cdf0e10cSrcweir 		if ( FAILED( hr ) )
1346*cdf0e10cSrcweir 			throw io::IOException(); // TODO
1347*cdf0e10cSrcweir 
1348*cdf0e10cSrcweir 		hr = pPersistStorage->SaveCompleted( NULL );
1349*cdf0e10cSrcweir 		if ( FAILED( hr ) && hr != E_UNEXPECTED )
1350*cdf0e10cSrcweir 			throw io::IOException(); // TODO
1351*cdf0e10cSrcweir 
1352*cdf0e10cSrcweir 		// STATSTG aStat;
1353*cdf0e10cSrcweir 		// m_pNativeImpl->m_pIStorage->Stat( &aStat, STATFLAG_NONAME );
1354*cdf0e10cSrcweir 	}
1355*cdf0e10cSrcweir }
1356*cdf0e10cSrcweir 
1357*cdf0e10cSrcweir //----------------------------------------------
1358*cdf0e10cSrcweir sal_Bool OleComponent::SaveObject_Impl()
1359*cdf0e10cSrcweir {
1360*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
1361*cdf0e10cSrcweir 	OleEmbeddedObject* pLockObject = NULL;
1362*cdf0e10cSrcweir 
1363*cdf0e10cSrcweir 	{
1364*cdf0e10cSrcweir 		osl::MutexGuard aGuard( m_aMutex );
1365*cdf0e10cSrcweir 		if ( m_pUnoOleObject )
1366*cdf0e10cSrcweir 		{
1367*cdf0e10cSrcweir 			pLockObject = m_pUnoOleObject;
1368*cdf0e10cSrcweir 			pLockObject->acquire();
1369*cdf0e10cSrcweir 		}
1370*cdf0e10cSrcweir 	}
1371*cdf0e10cSrcweir 
1372*cdf0e10cSrcweir 	if ( pLockObject )
1373*cdf0e10cSrcweir 	{
1374*cdf0e10cSrcweir 		bResult = pLockObject->SaveObject_Impl();
1375*cdf0e10cSrcweir 		pLockObject->release();
1376*cdf0e10cSrcweir 	}
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir 	return bResult;
1379*cdf0e10cSrcweir }
1380*cdf0e10cSrcweir 
1381*cdf0e10cSrcweir //----------------------------------------------
1382*cdf0e10cSrcweir sal_Bool OleComponent::OnShowWindow_Impl( bool bShow )
1383*cdf0e10cSrcweir {
1384*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
1385*cdf0e10cSrcweir 	OleEmbeddedObject* pLockObject = NULL;
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir 	{
1388*cdf0e10cSrcweir 		osl::MutexGuard aGuard( m_aMutex );
1389*cdf0e10cSrcweir 
1390*cdf0e10cSrcweir 		if ( m_pUnoOleObject )
1391*cdf0e10cSrcweir 		{
1392*cdf0e10cSrcweir 			pLockObject = m_pUnoOleObject;
1393*cdf0e10cSrcweir 			pLockObject->acquire();
1394*cdf0e10cSrcweir 		}
1395*cdf0e10cSrcweir 	}
1396*cdf0e10cSrcweir 
1397*cdf0e10cSrcweir 	if ( pLockObject )
1398*cdf0e10cSrcweir 	{
1399*cdf0e10cSrcweir 		bResult = pLockObject->OnShowWindow_Impl( bShow );
1400*cdf0e10cSrcweir 		pLockObject->release();
1401*cdf0e10cSrcweir 	}
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir 	return bResult;
1404*cdf0e10cSrcweir }
1405*cdf0e10cSrcweir 
1406*cdf0e10cSrcweir //----------------------------------------------
1407*cdf0e10cSrcweir void OleComponent::OnViewChange_Impl( sal_uInt32 dwAspect )
1408*cdf0e10cSrcweir {
1409*cdf0e10cSrcweir 	// TODO: check if it is enough or may be saving notifications are required for Visio2000
1410*cdf0e10cSrcweir 	::rtl::Reference< OleEmbeddedObject > xLockObject;
1411*cdf0e10cSrcweir 
1412*cdf0e10cSrcweir 	{
1413*cdf0e10cSrcweir 		osl::MutexGuard aGuard( m_aMutex );
1414*cdf0e10cSrcweir 		if ( m_pUnoOleObject )
1415*cdf0e10cSrcweir 			xLockObject = m_pUnoOleObject;
1416*cdf0e10cSrcweir 	}
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir 	if ( xLockObject.is() )
1419*cdf0e10cSrcweir 	{
1420*cdf0e10cSrcweir 		uno::Reference < awt::XRequestCallback > xRequestCallback(
1421*cdf0e10cSrcweir 			m_xFactory->createInstance(
1422*cdf0e10cSrcweir 			 ::rtl::OUString::createFromAscii("com.sun.star.awt.AsyncCallback") ),
1423*cdf0e10cSrcweir 			 uno::UNO_QUERY );
1424*cdf0e10cSrcweir 		xRequestCallback->addCallback( new MainThreadNotificationRequest( xLockObject, OLECOMP_ONVIEWCHANGE, dwAspect ), uno::Any() );
1425*cdf0e10cSrcweir 	}
1426*cdf0e10cSrcweir }
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir //----------------------------------------------
1429*cdf0e10cSrcweir void OleComponent::OnClose_Impl()
1430*cdf0e10cSrcweir {
1431*cdf0e10cSrcweir 	::rtl::Reference< OleEmbeddedObject > xLockObject;
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir 	{
1434*cdf0e10cSrcweir 		osl::MutexGuard aGuard( m_aMutex );
1435*cdf0e10cSrcweir 		if ( m_pUnoOleObject )
1436*cdf0e10cSrcweir 			xLockObject = m_pUnoOleObject;
1437*cdf0e10cSrcweir 	}
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir 	if ( xLockObject.is() )
1440*cdf0e10cSrcweir 	{
1441*cdf0e10cSrcweir 		uno::Reference < awt::XRequestCallback > xRequestCallback(
1442*cdf0e10cSrcweir 			m_xFactory->createInstance(
1443*cdf0e10cSrcweir 			 ::rtl::OUString::createFromAscii("com.sun.star.awt.AsyncCallback") ),
1444*cdf0e10cSrcweir 			 uno::UNO_QUERY );
1445*cdf0e10cSrcweir 		xRequestCallback->addCallback( new MainThreadNotificationRequest( xLockObject, OLECOMP_ONCLOSE ), uno::Any() );
1446*cdf0e10cSrcweir 	}
1447*cdf0e10cSrcweir }
1448*cdf0e10cSrcweir 
1449*cdf0e10cSrcweir // XCloseable
1450*cdf0e10cSrcweir //----------------------------------------------
1451*cdf0e10cSrcweir void SAL_CALL OleComponent::close( sal_Bool bDeliverOwnership )
1452*cdf0e10cSrcweir 	throw ( util::CloseVetoException,
1453*cdf0e10cSrcweir 			uno::RuntimeException )
1454*cdf0e10cSrcweir {
1455*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1456*cdf0e10cSrcweir 	if ( m_bDisposed )
1457*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1458*cdf0e10cSrcweir 
1459*cdf0e10cSrcweir     uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
1460*cdf0e10cSrcweir     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
1461*cdf0e10cSrcweir 
1462*cdf0e10cSrcweir 	if ( m_pInterfaceContainer )
1463*cdf0e10cSrcweir 	{
1464*cdf0e10cSrcweir     	::cppu::OInterfaceContainerHelper* pContainer =
1465*cdf0e10cSrcweir 			m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >* ) NULL ) );
1466*cdf0e10cSrcweir     	if ( pContainer != NULL )
1467*cdf0e10cSrcweir 		{
1468*cdf0e10cSrcweir         	::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1469*cdf0e10cSrcweir         	while ( pIterator.hasMoreElements() )
1470*cdf0e10cSrcweir         	{
1471*cdf0e10cSrcweir             	try
1472*cdf0e10cSrcweir             	{
1473*cdf0e10cSrcweir                 	( (util::XCloseListener* )pIterator.next() )->queryClosing( aSource, bDeliverOwnership );
1474*cdf0e10cSrcweir             	}
1475*cdf0e10cSrcweir             	catch( uno::RuntimeException& )
1476*cdf0e10cSrcweir             	{
1477*cdf0e10cSrcweir                 	pIterator.remove();
1478*cdf0e10cSrcweir             	}
1479*cdf0e10cSrcweir         	}
1480*cdf0e10cSrcweir 		}
1481*cdf0e10cSrcweir 
1482*cdf0e10cSrcweir     	pContainer = m_pInterfaceContainer->getContainer(
1483*cdf0e10cSrcweir 									::getCppuType( ( const uno::Reference< util::XCloseListener >* ) NULL ) );
1484*cdf0e10cSrcweir     	if ( pContainer != NULL )
1485*cdf0e10cSrcweir 		{
1486*cdf0e10cSrcweir         	::cppu::OInterfaceIteratorHelper pCloseIterator( *pContainer );
1487*cdf0e10cSrcweir         	while ( pCloseIterator.hasMoreElements() )
1488*cdf0e10cSrcweir         	{
1489*cdf0e10cSrcweir             	try
1490*cdf0e10cSrcweir             	{
1491*cdf0e10cSrcweir                 	( (util::XCloseListener* )pCloseIterator.next() )->notifyClosing( aSource );
1492*cdf0e10cSrcweir             	}
1493*cdf0e10cSrcweir             	catch( uno::RuntimeException& )
1494*cdf0e10cSrcweir             	{
1495*cdf0e10cSrcweir                 	pCloseIterator.remove();
1496*cdf0e10cSrcweir             	}
1497*cdf0e10cSrcweir         	}
1498*cdf0e10cSrcweir 		}
1499*cdf0e10cSrcweir 	}
1500*cdf0e10cSrcweir 
1501*cdf0e10cSrcweir 	Dispose();
1502*cdf0e10cSrcweir }
1503*cdf0e10cSrcweir 
1504*cdf0e10cSrcweir //----------------------------------------------
1505*cdf0e10cSrcweir void SAL_CALL OleComponent::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
1506*cdf0e10cSrcweir 	throw ( uno::RuntimeException )
1507*cdf0e10cSrcweir {
1508*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1509*cdf0e10cSrcweir 	if ( m_bDisposed )
1510*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1511*cdf0e10cSrcweir 
1512*cdf0e10cSrcweir 	if ( !m_pInterfaceContainer )
1513*cdf0e10cSrcweir 		m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
1514*cdf0e10cSrcweir 
1515*cdf0e10cSrcweir 	m_pInterfaceContainer->addInterface( ::getCppuType( ( const uno::Reference< util::XCloseListener >* )0 ), xListener );
1516*cdf0e10cSrcweir }
1517*cdf0e10cSrcweir 
1518*cdf0e10cSrcweir //----------------------------------------------
1519*cdf0e10cSrcweir void SAL_CALL OleComponent::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
1520*cdf0e10cSrcweir 	throw ( uno::RuntimeException )
1521*cdf0e10cSrcweir {
1522*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1523*cdf0e10cSrcweir 	if ( m_bDisposed )
1524*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1525*cdf0e10cSrcweir 
1526*cdf0e10cSrcweir 	if ( m_pInterfaceContainer )
1527*cdf0e10cSrcweir 		m_pInterfaceContainer->removeInterface( ::getCppuType( ( const uno::Reference< util::XCloseListener >* )0 ),
1528*cdf0e10cSrcweir 												xListener );
1529*cdf0e10cSrcweir }
1530*cdf0e10cSrcweir 
1531*cdf0e10cSrcweir // XTransferable
1532*cdf0e10cSrcweir //----------------------------------------------
1533*cdf0e10cSrcweir uno::Any SAL_CALL OleComponent::getTransferData( const datatransfer::DataFlavor& aFlavor )
1534*cdf0e10cSrcweir 	throw ( datatransfer::UnsupportedFlavorException,
1535*cdf0e10cSrcweir 			io::IOException,
1536*cdf0e10cSrcweir 			uno::RuntimeException )
1537*cdf0e10cSrcweir {
1538*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1539*cdf0e10cSrcweir 	if ( m_bDisposed )
1540*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1541*cdf0e10cSrcweir 
1542*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1543*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1544*cdf0e10cSrcweir 
1545*cdf0e10cSrcweir 	uno::Any aResult;
1546*cdf0e10cSrcweir 	sal_Bool bSupportedFlavor = sal_False;
1547*cdf0e10cSrcweir 
1548*cdf0e10cSrcweir 	if ( m_pNativeImpl->GraphicalFlavor( aFlavor ) )
1549*cdf0e10cSrcweir 	{
1550*cdf0e10cSrcweir 		DWORD nRequestedAspect = GetAspectFromFlavor( aFlavor );
1551*cdf0e10cSrcweir 		// if own icon is set and icon aspect is requested the own icon can be returned directly
1552*cdf0e10cSrcweir 
1553*cdf0e10cSrcweir 		ComSmart< IDataObject > pDataObject;
1554*cdf0e10cSrcweir 		HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, (void**)&pDataObject );
1555*cdf0e10cSrcweir 		if ( FAILED( hr ) || !pDataObject )
1556*cdf0e10cSrcweir 			throw io::IOException(); // TODO: transport error code
1557*cdf0e10cSrcweir 
1558*cdf0e10cSrcweir 		// The following optimization does not make much sence currently just because
1559*cdf0e10cSrcweir 		// only one aspect is supported, and only three formats for the aspect are supported
1560*cdf0e10cSrcweir 		// and moreover it is not guarantied that the once returned format will be supported further
1561*cdf0e10cSrcweir 		// example - i52106
1562*cdf0e10cSrcweir 		// TODO/LATER: bring the optimization back when other aspects are supported
1563*cdf0e10cSrcweir 
1564*cdf0e10cSrcweir 		// FORMATETC* pFormatEtc = m_pNativeImpl->GetSupportedFormatForAspect( nRequestedAspect );
1565*cdf0e10cSrcweir 		// if ( pFormatEtc )
1566*cdf0e10cSrcweir 		// {
1567*cdf0e10cSrcweir 		// 	STGMEDIUM aMedium;
1568*cdf0e10cSrcweir 		// 	hr = pDataObject->GetData( pFormatEtc, &aMedium );
1569*cdf0e10cSrcweir 		// 	if ( SUCCEEDED( hr ) )
1570*cdf0e10cSrcweir 		// 		bSupportedFlavor = m_pNativeImpl->ConvertDataForFlavor( aMedium, aFlavor, aResult );
1571*cdf0e10cSrcweir 		// }
1572*cdf0e10cSrcweir 		// else
1573*cdf0e10cSrcweir 		{
1574*cdf0e10cSrcweir 			// the supported format of the application is still not found, find one
1575*cdf0e10cSrcweir 			for ( sal_Int32 nInd = 0; nInd < FORMATS_NUM; nInd++ )
1576*cdf0e10cSrcweir 			{
1577*cdf0e10cSrcweir 				STGMEDIUM aMedium;
1578*cdf0e10cSrcweir 				FORMATETC aFormat = pFormatTemplates[nInd];
1579*cdf0e10cSrcweir 				aFormat.dwAspect = nRequestedAspect;
1580*cdf0e10cSrcweir 
1581*cdf0e10cSrcweir 				hr = pDataObject->GetData( &aFormat, &aMedium );
1582*cdf0e10cSrcweir 				if ( SUCCEEDED( hr ) )
1583*cdf0e10cSrcweir                 {
1584*cdf0e10cSrcweir                     bSupportedFlavor = m_pNativeImpl->ConvertDataForFlavor( aMedium, aFlavor, aResult );
1585*cdf0e10cSrcweir                     if ( bSupportedFlavor )
1586*cdf0e10cSrcweir                     {
1587*cdf0e10cSrcweir                         // TODO/LATER: bring the optimization back when other aspects are supported
1588*cdf0e10cSrcweir                         // m_pNativeImpl->AddSupportedFormat( aFormat );
1589*cdf0e10cSrcweir                         break;
1590*cdf0e10cSrcweir                     }
1591*cdf0e10cSrcweir 				}
1592*cdf0e10cSrcweir 			}
1593*cdf0e10cSrcweir 		}
1594*cdf0e10cSrcweir 
1595*cdf0e10cSrcweir 		// If the replacement could not be retrieved, the cached representaion should be used
1596*cdf0e10cSrcweir 		// currently it is not necessary to retrieve it here, so it is implemented in the object itself
1597*cdf0e10cSrcweir 	}
1598*cdf0e10cSrcweir 	// TODO: Investigate if there is already the format name
1599*cdf0e10cSrcweir 	// 		 and whether this format is really required
1600*cdf0e10cSrcweir 	else if ( aFlavor.DataType == getCppuType( ( const uno::Reference< io::XInputStream >* ) 0 )
1601*cdf0e10cSrcweir 			&& aFlavor.MimeType.equalsAscii( "application/x-openoffice-contentstream" ) )
1602*cdf0e10cSrcweir 	{
1603*cdf0e10cSrcweir 		// allow to retrieve stream-representation of the object persistence
1604*cdf0e10cSrcweir 		bSupportedFlavor = sal_True;
1605*cdf0e10cSrcweir 		uno::Reference < io::XStream > xTempFileStream(
1606*cdf0e10cSrcweir 			m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1607*cdf0e10cSrcweir 			uno::UNO_QUERY );
1608*cdf0e10cSrcweir 
1609*cdf0e10cSrcweir 		if ( !xTempFileStream.is() )
1610*cdf0e10cSrcweir 			throw uno::RuntimeException(); // TODO
1611*cdf0e10cSrcweir 
1612*cdf0e10cSrcweir 		uno::Reference< io::XOutputStream > xTempOutStream = xTempFileStream->getOutputStream();
1613*cdf0e10cSrcweir 		uno::Reference< io::XInputStream > xTempInStream = xTempFileStream->getInputStream();
1614*cdf0e10cSrcweir 		if ( xTempOutStream.is() && xTempInStream.is() )
1615*cdf0e10cSrcweir 		{
1616*cdf0e10cSrcweir 			OSL_ENSURE( m_pUnoOleObject, "Unexpected object absence!" );
1617*cdf0e10cSrcweir 			if ( !m_pUnoOleObject )
1618*cdf0e10cSrcweir 			throw uno::RuntimeException();
1619*cdf0e10cSrcweir 
1620*cdf0e10cSrcweir 			m_pUnoOleObject->StoreObjectToStream( xTempOutStream );
1621*cdf0e10cSrcweir 
1622*cdf0e10cSrcweir 			xTempOutStream->closeOutput();
1623*cdf0e10cSrcweir 			xTempOutStream = uno::Reference< io::XOutputStream >();
1624*cdf0e10cSrcweir 		}
1625*cdf0e10cSrcweir 		else
1626*cdf0e10cSrcweir 			throw io::IOException(); // TODO:
1627*cdf0e10cSrcweir 
1628*cdf0e10cSrcweir 		aResult <<= xTempInStream;
1629*cdf0e10cSrcweir 	}
1630*cdf0e10cSrcweir 
1631*cdf0e10cSrcweir 	if ( !bSupportedFlavor )
1632*cdf0e10cSrcweir 		throw datatransfer::UnsupportedFlavorException();
1633*cdf0e10cSrcweir 
1634*cdf0e10cSrcweir 	return aResult;
1635*cdf0e10cSrcweir }
1636*cdf0e10cSrcweir 
1637*cdf0e10cSrcweir //----------------------------------------------
1638*cdf0e10cSrcweir uno::Sequence< datatransfer::DataFlavor > SAL_CALL OleComponent::getTransferDataFlavors()
1639*cdf0e10cSrcweir 	throw ( uno::RuntimeException )
1640*cdf0e10cSrcweir {
1641*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1642*cdf0e10cSrcweir 	if ( m_bDisposed )
1643*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1644*cdf0e10cSrcweir 
1645*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1646*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1647*cdf0e10cSrcweir 
1648*cdf0e10cSrcweir 	RetrieveObjectDataFlavors_Impl();
1649*cdf0e10cSrcweir 
1650*cdf0e10cSrcweir 	return m_aDataFlavors;
1651*cdf0e10cSrcweir }
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir //----------------------------------------------
1654*cdf0e10cSrcweir sal_Bool SAL_CALL OleComponent::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
1655*cdf0e10cSrcweir 	throw ( uno::RuntimeException )
1656*cdf0e10cSrcweir {
1657*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1658*cdf0e10cSrcweir 	if ( m_bDisposed )
1659*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1660*cdf0e10cSrcweir 
1661*cdf0e10cSrcweir 	if ( !m_pNativeImpl->m_pOleObject )
1662*cdf0e10cSrcweir 		throw embed::WrongStateException(); // TODO: the object is in wrong state
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir 	if ( !m_aDataFlavors.getLength() )
1665*cdf0e10cSrcweir 	{
1666*cdf0e10cSrcweir 		RetrieveObjectDataFlavors_Impl();
1667*cdf0e10cSrcweir 	}
1668*cdf0e10cSrcweir 
1669*cdf0e10cSrcweir 	for ( sal_Int32 nInd = 0; nInd < m_aDataFlavors.getLength(); nInd++ )
1670*cdf0e10cSrcweir 		if ( m_aDataFlavors[nInd].MimeType.equals( aFlavor.MimeType ) && m_aDataFlavors[nInd].DataType == aFlavor.DataType )
1671*cdf0e10cSrcweir 			return sal_True;
1672*cdf0e10cSrcweir 
1673*cdf0e10cSrcweir 	return sal_False;
1674*cdf0e10cSrcweir }
1675*cdf0e10cSrcweir 
1676*cdf0e10cSrcweir void SAL_CALL OleComponent::dispose() throw (::com::sun::star::uno::RuntimeException)
1677*cdf0e10cSrcweir {
1678*cdf0e10cSrcweir     try
1679*cdf0e10cSrcweir     {
1680*cdf0e10cSrcweir         close( sal_True );
1681*cdf0e10cSrcweir     }
1682*cdf0e10cSrcweir     catch ( uno::Exception& )
1683*cdf0e10cSrcweir     {
1684*cdf0e10cSrcweir     }
1685*cdf0e10cSrcweir }
1686*cdf0e10cSrcweir 
1687*cdf0e10cSrcweir void SAL_CALL OleComponent::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
1688*cdf0e10cSrcweir 	throw ( uno::RuntimeException )
1689*cdf0e10cSrcweir {
1690*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1691*cdf0e10cSrcweir 	if ( m_bDisposed )
1692*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1693*cdf0e10cSrcweir 
1694*cdf0e10cSrcweir 	if ( !m_pInterfaceContainer )
1695*cdf0e10cSrcweir 		m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
1696*cdf0e10cSrcweir 
1697*cdf0e10cSrcweir     m_pInterfaceContainer->addInterface( ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
1698*cdf0e10cSrcweir }
1699*cdf0e10cSrcweir 
1700*cdf0e10cSrcweir //----------------------------------------------
1701*cdf0e10cSrcweir void SAL_CALL OleComponent::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
1702*cdf0e10cSrcweir 	throw ( uno::RuntimeException )
1703*cdf0e10cSrcweir {
1704*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1705*cdf0e10cSrcweir 	if ( m_bDisposed )
1706*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1707*cdf0e10cSrcweir 
1708*cdf0e10cSrcweir 	if ( m_pInterfaceContainer )
1709*cdf0e10cSrcweir         m_pInterfaceContainer->removeInterface( ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ),
1710*cdf0e10cSrcweir 												xListener );
1711*cdf0e10cSrcweir }
1712*cdf0e10cSrcweir 
1713*cdf0e10cSrcweir sal_Int64 SAL_CALL OleComponent::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException)
1714*cdf0e10cSrcweir {
1715*cdf0e10cSrcweir     try
1716*cdf0e10cSrcweir     {
1717*cdf0e10cSrcweir         uno::Sequence < sal_Int8 > aCLSID = GetCLSID();
1718*cdf0e10cSrcweir         if ( MimeConfigurationHelper::ClassIDsEqual( aIdentifier, aCLSID ) )
1719*cdf0e10cSrcweir             return (sal_Int64) (IUnknown*) m_pNativeImpl->m_pObj;
1720*cdf0e10cSrcweir 
1721*cdf0e10cSrcweir         // compatibility hack for old versions: CLSID was used in wrong order (SvGlobalName order)
1722*cdf0e10cSrcweir         sal_Int32 nLength = aIdentifier.getLength();
1723*cdf0e10cSrcweir         if ( nLength == 16 )
1724*cdf0e10cSrcweir         {
1725*cdf0e10cSrcweir             for ( sal_Int32 n=8; n<16; n++ )
1726*cdf0e10cSrcweir                 if ( aIdentifier[n] != aCLSID[n] )
1727*cdf0e10cSrcweir                     return 0;
1728*cdf0e10cSrcweir             if ( aIdentifier[7] == aCLSID[6] &&
1729*cdf0e10cSrcweir                  aIdentifier[6] == aCLSID[7] &&
1730*cdf0e10cSrcweir                  aIdentifier[5] == aCLSID[4] &&
1731*cdf0e10cSrcweir                  aIdentifier[4] == aCLSID[5] &&
1732*cdf0e10cSrcweir                  aIdentifier[3] == aCLSID[0] &&
1733*cdf0e10cSrcweir                  aIdentifier[2] == aCLSID[1] &&
1734*cdf0e10cSrcweir                  aIdentifier[1] == aCLSID[2] &&
1735*cdf0e10cSrcweir                  aIdentifier[0] == aCLSID[3] )
1736*cdf0e10cSrcweir                 return (sal_Int64) (IUnknown*) m_pNativeImpl->m_pObj;
1737*cdf0e10cSrcweir         }
1738*cdf0e10cSrcweir 	}
1739*cdf0e10cSrcweir     catch ( uno::Exception& )
1740*cdf0e10cSrcweir     {
1741*cdf0e10cSrcweir     }
1742*cdf0e10cSrcweir 
1743*cdf0e10cSrcweir     return 0;
1744*cdf0e10cSrcweir }
1745*cdf0e10cSrcweir 
1746*cdf0e10cSrcweir sal_Bool SAL_CALL OleComponent::isModified() throw (::com::sun::star::uno::RuntimeException)
1747*cdf0e10cSrcweir {
1748*cdf0e10cSrcweir     return m_bModified;
1749*cdf0e10cSrcweir }
1750*cdf0e10cSrcweir 
1751*cdf0e10cSrcweir void SAL_CALL OleComponent::setModified( sal_Bool bModified )
1752*cdf0e10cSrcweir         throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
1753*cdf0e10cSrcweir {
1754*cdf0e10cSrcweir     m_bModified = bModified;
1755*cdf0e10cSrcweir 
1756*cdf0e10cSrcweir     if ( bModified && m_pInterfaceContainer )
1757*cdf0e10cSrcweir 	{
1758*cdf0e10cSrcweir     	::cppu::OInterfaceContainerHelper* pContainer =
1759*cdf0e10cSrcweir             m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XModifyListener >* ) NULL ) );
1760*cdf0e10cSrcweir     	if ( pContainer != NULL )
1761*cdf0e10cSrcweir 		{
1762*cdf0e10cSrcweir             ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1763*cdf0e10cSrcweir             while ( pIterator.hasMoreElements() )
1764*cdf0e10cSrcweir         	{
1765*cdf0e10cSrcweir             	try
1766*cdf0e10cSrcweir             	{
1767*cdf0e10cSrcweir                     lang::EventObject aEvent( (util::XModifiable*) this );
1768*cdf0e10cSrcweir                     ((util::XModifyListener*)pIterator.next())->modified( aEvent );
1769*cdf0e10cSrcweir             	}
1770*cdf0e10cSrcweir             	catch( uno::RuntimeException& )
1771*cdf0e10cSrcweir             	{
1772*cdf0e10cSrcweir                     pIterator.remove();
1773*cdf0e10cSrcweir             	}
1774*cdf0e10cSrcweir         	}
1775*cdf0e10cSrcweir 		}
1776*cdf0e10cSrcweir 	}
1777*cdf0e10cSrcweir }
1778*cdf0e10cSrcweir 
1779*cdf0e10cSrcweir void SAL_CALL OleComponent::addModifyListener( const com::sun::star::uno::Reference < com::sun::star::util::XModifyListener >& xListener ) throw(::com::sun::star::uno::RuntimeException)
1780*cdf0e10cSrcweir {
1781*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1782*cdf0e10cSrcweir 	if ( m_bDisposed )
1783*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1784*cdf0e10cSrcweir 
1785*cdf0e10cSrcweir 	if ( !m_pInterfaceContainer )
1786*cdf0e10cSrcweir 		m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
1787*cdf0e10cSrcweir 
1788*cdf0e10cSrcweir     m_pInterfaceContainer->addInterface( ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), xListener );
1789*cdf0e10cSrcweir }
1790*cdf0e10cSrcweir 
1791*cdf0e10cSrcweir void SAL_CALL OleComponent::removeModifyListener( const com::sun::star::uno::Reference < com::sun::star::util::XModifyListener >& xListener) throw(::com::sun::star::uno::RuntimeException)
1792*cdf0e10cSrcweir {
1793*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1794*cdf0e10cSrcweir 	if ( m_bDisposed )
1795*cdf0e10cSrcweir 		throw lang::DisposedException(); // TODO
1796*cdf0e10cSrcweir 
1797*cdf0e10cSrcweir 	if ( m_pInterfaceContainer )
1798*cdf0e10cSrcweir         m_pInterfaceContainer->removeInterface( ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ),
1799*cdf0e10cSrcweir 												xListener );
1800*cdf0e10cSrcweir }
1801*cdf0e10cSrcweir 
1802