1*bfd08df8SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*bfd08df8SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*bfd08df8SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*bfd08df8SAndrew Rist  * distributed with this work for additional information
6*bfd08df8SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*bfd08df8SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*bfd08df8SAndrew Rist  * "License"); you may not use this file except in compliance
9*bfd08df8SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*bfd08df8SAndrew Rist  *
11*bfd08df8SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*bfd08df8SAndrew Rist  *
13*bfd08df8SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*bfd08df8SAndrew Rist  * software distributed under the License is distributed on an
15*bfd08df8SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*bfd08df8SAndrew Rist  * KIND, either express or implied.  See the License for the
17*bfd08df8SAndrew Rist  * specific language governing permissions and limitations
18*bfd08df8SAndrew Rist  * under the License.
19*bfd08df8SAndrew Rist  *
20*bfd08df8SAndrew Rist  *************************************************************/
21*bfd08df8SAndrew Rist 
22*bfd08df8SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_embeddedobj.hxx"
26cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
27cdf0e10cSrcweir #include <com/sun/star/frame/XController.hpp>
28cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp>
29cdf0e10cSrcweir #include <com/sun/star/awt/XTopWindow.hpp>
30cdf0e10cSrcweir #include <com/sun/star/embed/XClassifiedObject.hpp>
31cdf0e10cSrcweir #include <com/sun/star/io/XStream.hpp>
32cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp>
33cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
34cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp>
35cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
36cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
37cdf0e10cSrcweir #include <com/sun/star/util/XCloseable.hpp>
38cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBRODCASTER_HPP_
41cdf0e10cSrcweir #include <com/sun/star/document/XEventBroadcaster.hpp>
42cdf0e10cSrcweir #endif
43cdf0e10cSrcweir #include <com/sun/star/document/XEventListener.hpp>
44cdf0e10cSrcweir #include <com/sun/star/document/XTypeDetection.hpp>
45cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
46cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
47cdf0e10cSrcweir #include <comphelper/storagehelper.hxx>
48cdf0e10cSrcweir #include <comphelper/mimeconfighelper.hxx>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include "ownview.hxx"
51cdf0e10cSrcweir 
52cdf0e10cSrcweir 
53cdf0e10cSrcweir using namespace ::com::sun::star;
54cdf0e10cSrcweir using namespace ::comphelper;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
57cdf0e10cSrcweir ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
58cdf0e10cSrcweir sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory );
59cdf0e10cSrcweir uno::Reference< io::XStream > TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw ( uno::Exception );
60cdf0e10cSrcweir 
61cdf0e10cSrcweir //========================================================
62cdf0e10cSrcweir // Dummy interaction handler
63cdf0e10cSrcweir //========================================================
64cdf0e10cSrcweir //--------------------------------------------------------
65cdf0e10cSrcweir class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler >
66cdf0e10cSrcweir {
67cdf0e10cSrcweir public:
DummyHandler_Impl()68cdf0e10cSrcweir 	DummyHandler_Impl() {}
69cdf0e10cSrcweir 	~DummyHandler_Impl();
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest )
72cdf0e10cSrcweir 			throw( uno::RuntimeException );
73cdf0e10cSrcweir };
74cdf0e10cSrcweir 
75cdf0e10cSrcweir //--------------------------------------------------------
~DummyHandler_Impl()76cdf0e10cSrcweir DummyHandler_Impl::~DummyHandler_Impl()
77cdf0e10cSrcweir {
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //--------------------------------------------------------
handle(const uno::Reference<task::XInteractionRequest> &)81cdf0e10cSrcweir void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& )
82cdf0e10cSrcweir 		throw( uno::RuntimeException )
83cdf0e10cSrcweir {
84cdf0e10cSrcweir 	return;
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir //========================================================
88cdf0e10cSrcweir // Object viewer
89cdf0e10cSrcweir //========================================================
90cdf0e10cSrcweir //--------------------------------------------------------
OwnView_Impl(const uno::Reference<lang::XMultiServiceFactory> & xFactory,const uno::Reference<io::XInputStream> & xInputStream)91cdf0e10cSrcweir OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
92cdf0e10cSrcweir 							const uno::Reference< io::XInputStream >& xInputStream )
93cdf0e10cSrcweir : m_xFactory( xFactory )
94cdf0e10cSrcweir , m_bBusy( sal_False )
95cdf0e10cSrcweir , m_bUseNative( sal_False )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	if ( !xFactory.is() || !xInputStream.is() )
98cdf0e10cSrcweir 		throw uno::RuntimeException();
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 	m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory );
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir //--------------------------------------------------------
~OwnView_Impl()104cdf0e10cSrcweir OwnView_Impl::~OwnView_Impl()
105cdf0e10cSrcweir {
106cdf0e10cSrcweir 	try {
107cdf0e10cSrcweir 		KillFile_Impl( m_aTempFileURL, m_xFactory );
108cdf0e10cSrcweir 	} catch( uno::Exception& ) {}
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 	try {
111cdf0e10cSrcweir 		if ( m_aNativeTempURL.getLength() )
112cdf0e10cSrcweir 			KillFile_Impl( m_aNativeTempURL, m_xFactory );
113cdf0e10cSrcweir 	} catch( uno::Exception& ) {}
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir //--------------------------------------------------------
CreateModelFromURL(const::rtl::OUString & aFileURL)117cdf0e10cSrcweir sal_Bool OwnView_Impl::CreateModelFromURL( const ::rtl::OUString& aFileURL )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	if ( aFileURL.getLength() )
122cdf0e10cSrcweir 	{
123cdf0e10cSrcweir 		try {
124cdf0e10cSrcweir 			uno::Reference < frame::XComponentLoader > xDocumentLoader(
125cdf0e10cSrcweir 							m_xFactory->createInstance (
126cdf0e10cSrcweir 										::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ),
127cdf0e10cSrcweir 							uno::UNO_QUERY );
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 			if ( xDocumentLoader.is() )
130cdf0e10cSrcweir 			{
131cdf0e10cSrcweir 				uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.getLength() ? 5 : 4 );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 				aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
134cdf0e10cSrcweir 				aArgs[0].Value <<= aFileURL;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 				aArgs[1].Name = ::rtl::OUString::createFromAscii( "ReadOnly" );
137cdf0e10cSrcweir 				aArgs[1].Value <<= sal_True;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 				aArgs[2].Name = ::rtl::OUString::createFromAscii( "InteractionHandler" );
140cdf0e10cSrcweir 				aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
141cdf0e10cSrcweir 									static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 				aArgs[3].Name = ::rtl::OUString::createFromAscii( "DontEdit" );
144cdf0e10cSrcweir 				aArgs[3].Value <<= sal_True;
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 				if ( m_aFilterName.getLength() )
147cdf0e10cSrcweir 				{
148cdf0e10cSrcweir 					aArgs[4].Name = ::rtl::OUString::createFromAscii( "FilterName" );
149cdf0e10cSrcweir 					aArgs[4].Value <<= m_aFilterName;
150cdf0e10cSrcweir 				}
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 				uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
153cdf0e10cSrcweir 																aFileURL,
154cdf0e10cSrcweir 																::rtl::OUString::createFromAscii( "_blank" ),
155cdf0e10cSrcweir 																0,
156cdf0e10cSrcweir 																aArgs ),
157cdf0e10cSrcweir 															uno::UNO_QUERY );
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 				if ( xModel.is() )
160cdf0e10cSrcweir 				{
161cdf0e10cSrcweir 					uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
162cdf0e10cSrcweir 					if ( xBroadCaster.is() )
163cdf0e10cSrcweir 						xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
164cdf0e10cSrcweir 																static_cast< ::cppu::OWeakObject* >( this ),
165cdf0e10cSrcweir 									 							uno::UNO_QUERY ) );
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 					uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
168cdf0e10cSrcweir 					if ( xCloseable.is() )
169cdf0e10cSrcweir 					{
170cdf0e10cSrcweir 						xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
171cdf0e10cSrcweir 																		static_cast< ::cppu::OWeakObject* >( this ),
172cdf0e10cSrcweir 										  								uno::UNO_QUERY ) );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 						::osl::MutexGuard aGuard( m_aMutex );
175cdf0e10cSrcweir 						m_xModel = xModel;
176cdf0e10cSrcweir 						bResult = sal_True;
177cdf0e10cSrcweir 					}
178cdf0e10cSrcweir 				}
179cdf0e10cSrcweir 			}
180cdf0e10cSrcweir 		}
181cdf0e10cSrcweir 		catch( uno::Exception& )
182cdf0e10cSrcweir 		{
183cdf0e10cSrcweir 		}
184cdf0e10cSrcweir 	}
185cdf0e10cSrcweir 
186cdf0e10cSrcweir 	return bResult;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir //--------------------------------------------------------
CreateModel(sal_Bool bUseNative)190cdf0e10cSrcweir sal_Bool OwnView_Impl::CreateModel( sal_Bool bUseNative )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 	try {
195cdf0e10cSrcweir 		bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL );
196cdf0e10cSrcweir 	}
197cdf0e10cSrcweir 	catch( uno::Exception& )
198cdf0e10cSrcweir 	{
199cdf0e10cSrcweir 	}
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 	return bResult;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir //--------------------------------------------------------
GetFilterNameFromExtentionAndInStream(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & xFactory,const::rtl::OUString & aNameWithExtention,const uno::Reference<io::XInputStream> & xInputStream)205cdf0e10cSrcweir ::rtl::OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
206cdf0e10cSrcweir                                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
207cdf0e10cSrcweir                                                     const ::rtl::OUString& aNameWithExtention,
208cdf0e10cSrcweir                                                     const uno::Reference< io::XInputStream >& xInputStream )
209cdf0e10cSrcweir {
210cdf0e10cSrcweir 	if ( !xInputStream.is() )
211cdf0e10cSrcweir 		throw uno::RuntimeException();
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	uno::Reference< document::XTypeDetection > xTypeDetection(
214cdf0e10cSrcweir 			xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
215cdf0e10cSrcweir 			uno::UNO_QUERY_THROW );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 	::rtl::OUString aTypeName;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir 	if ( aNameWithExtention.getLength() )
220cdf0e10cSrcweir 	{
221cdf0e10cSrcweir 		::rtl::OUString aURLToAnalyze =
222cdf0e10cSrcweir 				( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///" ) ) + aNameWithExtention );
223cdf0e10cSrcweir 		aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
224cdf0e10cSrcweir 	}
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	uno::Sequence< beans::PropertyValue > aArgs( aTypeName.getLength() ? 3 : 2 );
227cdf0e10cSrcweir 	aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
228cdf0e10cSrcweir 	aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
229cdf0e10cSrcweir 	aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
230cdf0e10cSrcweir 	aArgs[1].Value <<= xInputStream;
231cdf0e10cSrcweir 	if ( aTypeName.getLength() )
232cdf0e10cSrcweir 	{
233cdf0e10cSrcweir 		aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TypeName" ) );
234cdf0e10cSrcweir 		aArgs[2].Value <<= aTypeName;
235cdf0e10cSrcweir 	}
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	::rtl::OUString aFilterName;
240cdf0e10cSrcweir 	for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
241cdf0e10cSrcweir 		if ( aArgs[nInd].Name.equalsAscii( "FilterName" ) )
242cdf0e10cSrcweir 			aArgs[nInd].Value >>= aFilterName;
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 	if ( !aFilterName.getLength() && aTypeName.getLength() )
245cdf0e10cSrcweir 	{
246cdf0e10cSrcweir 		// get the default filter name for the type
247cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
248cdf0e10cSrcweir 		uno::Sequence< beans::PropertyValue > aTypes;
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 		if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
251cdf0e10cSrcweir 		{
252cdf0e10cSrcweir 			for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
253cdf0e10cSrcweir 			{
254cdf0e10cSrcweir 				if ( aTypes[nInd].Name.equalsAscii( "PreferredFilter" ) && ( aTypes[nInd].Value >>= aFilterName ) )
255cdf0e10cSrcweir 				{
256cdf0e10cSrcweir 					aTypes[nInd].Value >>= aFilterName;
257cdf0e10cSrcweir 					break;
258cdf0e10cSrcweir 				}
259cdf0e10cSrcweir 			}
260cdf0e10cSrcweir 		}
261cdf0e10cSrcweir 	}
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	return aFilterName;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir //--------------------------------------------------------
ReadContentsAndGenerateTempFile(const uno::Reference<io::XInputStream> & xInStream,sal_Bool bParseHeader)267cdf0e10cSrcweir sal_Bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
268cdf0e10cSrcweir 														sal_Bool bParseHeader )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir 	uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
271cdf0e10cSrcweir 	xSeekable->seek( 0 );
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 	// create m_aNativeTempURL
274cdf0e10cSrcweir 	::rtl::OUString aNativeTempURL;
275cdf0e10cSrcweir 	uno::Reference < beans::XPropertySet > xNativeTempFile(
276cdf0e10cSrcweir 			m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
277cdf0e10cSrcweir 			uno::UNO_QUERY_THROW );
278cdf0e10cSrcweir 	uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
279cdf0e10cSrcweir 	uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
280cdf0e10cSrcweir 	uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
281cdf0e10cSrcweir 	if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
282cdf0e10cSrcweir 		throw uno::RuntimeException();
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	try {
285cdf0e10cSrcweir 		xNativeTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
286cdf0e10cSrcweir 		uno::Any aUrl = xNativeTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
287cdf0e10cSrcweir 		aUrl >>= aNativeTempURL;
288cdf0e10cSrcweir 	}
289cdf0e10cSrcweir 	catch ( uno::Exception& )
290cdf0e10cSrcweir 	{
291cdf0e10cSrcweir 	}
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 	sal_Bool bFailed = sal_False;
294cdf0e10cSrcweir 	::rtl::OUString aFileSuffix;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 	if ( bParseHeader )
297cdf0e10cSrcweir 	{
298cdf0e10cSrcweir 		uno::Sequence< sal_Int8 > aReadSeq( 4 );
299cdf0e10cSrcweir 		// read the complete size of the Object Package
300cdf0e10cSrcweir 		if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
301cdf0e10cSrcweir 			return sal_False;
302cdf0e10cSrcweir /*
303cdf0e10cSrcweir 		sal_uInt32 nLength = (sal_uInt8)aReadSeq[0]
304cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[1] * 0x100
305cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[2] * 0x10000
306cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[3] * 0x1000000;
307cdf0e10cSrcweir */
308cdf0e10cSrcweir 		// read the first header ( have no idea what does this header mean )
309cdf0e10cSrcweir 		if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
310cdf0e10cSrcweir 			return sal_False;
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 		// read file name
313cdf0e10cSrcweir 		// only extension is interesting so only subset of symbols is accepted
314cdf0e10cSrcweir 		do
315cdf0e10cSrcweir 		{
316cdf0e10cSrcweir 			if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
317cdf0e10cSrcweir 				return sal_False;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 			if (
320cdf0e10cSrcweir                 (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
321cdf0e10cSrcweir                 (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
322cdf0e10cSrcweir                 (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
323cdf0e10cSrcweir                 aReadSeq[0] == '.'
324cdf0e10cSrcweir                )
325cdf0e10cSrcweir             {
326cdf0e10cSrcweir 				aFileSuffix += ::rtl::OUString::valueOf( (sal_Unicode) aReadSeq[0] );
327cdf0e10cSrcweir             }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 		} while( aReadSeq[0] );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 		// skip url
332cdf0e10cSrcweir 		do
333cdf0e10cSrcweir 		{
334cdf0e10cSrcweir 			if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
335cdf0e10cSrcweir 				return sal_False;
336cdf0e10cSrcweir 		} while( aReadSeq[0] );
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 		// check the next header
339cdf0e10cSrcweir 		if ( xInStream->readBytes( aReadSeq, 4 ) != 4
340cdf0e10cSrcweir 	  	|| aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
341cdf0e10cSrcweir 			return sal_False;
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 		// get the size of the next entry
344cdf0e10cSrcweir 		if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
345cdf0e10cSrcweir 			return sal_False;
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 		sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
348cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[1] * 0x100
349cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[2] * 0x10000
350cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[3] * 0x1000000;
351cdf0e10cSrcweir 		sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 		xSeekable->seek( nTargetPos );
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 		// get the size of stored data
356cdf0e10cSrcweir 		if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
357cdf0e10cSrcweir 			return sal_False;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 		sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
360cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[1] * 0x100
361cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[2] * 0x10000
362cdf0e10cSrcweir 							+ (sal_uInt8)aReadSeq[3] * 0x1000000;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 		aReadSeq.realloc( 32000 );
365cdf0e10cSrcweir 		sal_uInt32 nRead = 0;
366cdf0e10cSrcweir 		while ( nRead < nDataSize )
367cdf0e10cSrcweir 		{
368cdf0e10cSrcweir 			sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
369cdf0e10cSrcweir 			sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 
372cdf0e10cSrcweir 			if ( !nLocalRead )
373cdf0e10cSrcweir 			{
374cdf0e10cSrcweir 				bFailed = sal_True;
375cdf0e10cSrcweir 				break;
376cdf0e10cSrcweir 			}
377cdf0e10cSrcweir 			else if ( nLocalRead == 32000 )
378cdf0e10cSrcweir 				xNativeOutTemp->writeBytes( aReadSeq );
379cdf0e10cSrcweir 			else
380cdf0e10cSrcweir 			{
381cdf0e10cSrcweir 				uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
382cdf0e10cSrcweir 				aToWrite.realloc( nLocalRead );
383cdf0e10cSrcweir 				xNativeOutTemp->writeBytes( aToWrite );
384cdf0e10cSrcweir 			}
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 			nRead += nLocalRead;
387cdf0e10cSrcweir 		}
388cdf0e10cSrcweir 	}
389cdf0e10cSrcweir 	else
390cdf0e10cSrcweir 	{
391cdf0e10cSrcweir 		uno::Sequence< sal_Int8 > aData( 8 );
392cdf0e10cSrcweir 		if ( xInStream->readBytes( aData, 8 ) == 8
393cdf0e10cSrcweir 		  && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
394cdf0e10cSrcweir 		  && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
395cdf0e10cSrcweir 		{
396cdf0e10cSrcweir 			// the header has to be removed
397cdf0e10cSrcweir 			xSeekable->seek( 40 );
398cdf0e10cSrcweir 		}
399cdf0e10cSrcweir 		else
400cdf0e10cSrcweir 		{
401cdf0e10cSrcweir 			// the usual Ole10Native format
402cdf0e10cSrcweir 			xSeekable->seek( 4 );
403cdf0e10cSrcweir 		}
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 		::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
406cdf0e10cSrcweir 	}
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 	xNativeOutTemp->closeOutput();
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 	// The temporary native file is created, now the filter must be detected
411cdf0e10cSrcweir 	if ( !bFailed )
412cdf0e10cSrcweir 	{
413cdf0e10cSrcweir 		m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
414cdf0e10cSrcweir 		m_aNativeTempURL = aNativeTempURL;
415cdf0e10cSrcweir 	}
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 	return !bFailed;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir //--------------------------------------------------------
CreateNative()421cdf0e10cSrcweir void OwnView_Impl::CreateNative()
422cdf0e10cSrcweir {
423cdf0e10cSrcweir 	if ( m_aNativeTempURL.getLength() )
424cdf0e10cSrcweir 		return;
425cdf0e10cSrcweir 
426cdf0e10cSrcweir 	try
427cdf0e10cSrcweir 	{
428cdf0e10cSrcweir 		uno::Reference < ucb::XSimpleFileAccess > xAccess(
429cdf0e10cSrcweir 				m_xFactory->createInstance (
430cdf0e10cSrcweir 						::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
431cdf0e10cSrcweir 				uno::UNO_QUERY_THROW );
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 		uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
434cdf0e10cSrcweir 		if ( !xInStream.is() )
435cdf0e10cSrcweir 			throw uno::RuntimeException();
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 		uno::Sequence< uno::Any > aArgs( 1 );
438cdf0e10cSrcweir 		aArgs[0] <<= xInStream;
439cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xNameAccess(
440cdf0e10cSrcweir 				m_xFactory->createInstanceWithArguments(
441cdf0e10cSrcweir 						::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
442cdf0e10cSrcweir 						aArgs ),
443cdf0e10cSrcweir 				uno::UNO_QUERY_THROW );
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 		::rtl::OUString aSubStreamName = ::rtl::OUString::createFromAscii( "\1Ole10Native" );
446cdf0e10cSrcweir 		uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
447cdf0e10cSrcweir 		uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 		if ( xNameAccess->hasByName( aSubStreamName ) )
450cdf0e10cSrcweir 		{
451cdf0e10cSrcweir 			sal_uInt8 aClassID[] =
452cdf0e10cSrcweir 				{ 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
453cdf0e10cSrcweir 			uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 );
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 			uno::Reference< io::XStream > xSubStream;
456cdf0e10cSrcweir 			xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
457cdf0e10cSrcweir 			if ( xSubStream.is() )
458cdf0e10cSrcweir 			{
459cdf0e10cSrcweir 				sal_Bool bOk = sal_False;
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 				if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
462cdf0e10cSrcweir 				{
463cdf0e10cSrcweir 					// the storage represents Object Package
464cdf0e10cSrcweir 
465cdf0e10cSrcweir 					bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_True );
466cdf0e10cSrcweir 
467cdf0e10cSrcweir 					if ( !bOk && m_aNativeTempURL.getLength() )
468cdf0e10cSrcweir 					{
469cdf0e10cSrcweir 						KillFile_Impl( m_aNativeTempURL, m_xFactory );
470cdf0e10cSrcweir 						m_aNativeTempURL = ::rtl::OUString();
471cdf0e10cSrcweir 					}
472cdf0e10cSrcweir 				}
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 				if ( !bOk )
475cdf0e10cSrcweir 				{
476cdf0e10cSrcweir 					bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_False );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 					if ( !bOk && m_aNativeTempURL.getLength() )
479cdf0e10cSrcweir 					{
480cdf0e10cSrcweir 						KillFile_Impl( m_aNativeTempURL, m_xFactory );
481cdf0e10cSrcweir 						m_aNativeTempURL = ::rtl::OUString();
482cdf0e10cSrcweir 					}
483cdf0e10cSrcweir 				}
484cdf0e10cSrcweir 			}
485cdf0e10cSrcweir 		}
486cdf0e10cSrcweir 		else
487cdf0e10cSrcweir 		{
488cdf0e10cSrcweir 			// TODO/LATER: No native stream, needs a new solution
489cdf0e10cSrcweir 		}
490cdf0e10cSrcweir 	}
491cdf0e10cSrcweir 	catch( uno::Exception& )
492cdf0e10cSrcweir 	{}
493cdf0e10cSrcweir }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir //--------------------------------------------------------
Open()496cdf0e10cSrcweir sal_Bool OwnView_Impl::Open()
497cdf0e10cSrcweir {
498cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir 	uno::Reference< frame::XModel > xExistingModel;
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 	{
503cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
504cdf0e10cSrcweir 		xExistingModel = m_xModel;
505cdf0e10cSrcweir 		if ( m_bBusy )
506cdf0e10cSrcweir 			return sal_False;
507cdf0e10cSrcweir 
508cdf0e10cSrcweir 		m_bBusy = sal_True;
509cdf0e10cSrcweir 	}
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 	if ( xExistingModel.is() )
512cdf0e10cSrcweir 	{
513cdf0e10cSrcweir 		try {
514cdf0e10cSrcweir 			uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
515cdf0e10cSrcweir 			if ( xController.is() )
516cdf0e10cSrcweir 			{
517cdf0e10cSrcweir 				uno::Reference< frame::XFrame > xFrame = xController->getFrame();
518cdf0e10cSrcweir 				if ( xFrame.is() )
519cdf0e10cSrcweir 				{
520cdf0e10cSrcweir 					xFrame->activate();
521cdf0e10cSrcweir 					uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
522cdf0e10cSrcweir 					if(xTopWindow.is())
523cdf0e10cSrcweir 						xTopWindow->toFront();
524cdf0e10cSrcweir 
525cdf0e10cSrcweir 					bResult = sal_True;
526cdf0e10cSrcweir 				}
527cdf0e10cSrcweir 			}
528cdf0e10cSrcweir 		}
529cdf0e10cSrcweir 		catch( uno::Exception& )
530cdf0e10cSrcweir 		{
531cdf0e10cSrcweir 		}
532cdf0e10cSrcweir 	}
533cdf0e10cSrcweir 	else
534cdf0e10cSrcweir 	{
535cdf0e10cSrcweir 		bResult = CreateModel( m_bUseNative );
536cdf0e10cSrcweir 
537cdf0e10cSrcweir 		if ( !bResult && !m_bUseNative )
538cdf0e10cSrcweir 		{
539cdf0e10cSrcweir 			// the original storage can not be recognized
540cdf0e10cSrcweir 			if ( !m_aNativeTempURL.getLength() )
541cdf0e10cSrcweir 			{
542cdf0e10cSrcweir 				// create a temporary file for the native representation if there is no
543cdf0e10cSrcweir 				CreateNative();
544cdf0e10cSrcweir 			}
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 			if ( m_aNativeTempURL.getLength() )
547cdf0e10cSrcweir 			{
548cdf0e10cSrcweir 				bResult = CreateModel( sal_True );
549cdf0e10cSrcweir 				if ( bResult )
550cdf0e10cSrcweir 					m_bUseNative = sal_True;
551cdf0e10cSrcweir 			}
552cdf0e10cSrcweir 		}
553cdf0e10cSrcweir 	}
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 	m_bBusy = sal_False;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 	return bResult;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir //--------------------------------------------------------
Close()561cdf0e10cSrcweir void OwnView_Impl::Close()
562cdf0e10cSrcweir {
563cdf0e10cSrcweir 	uno::Reference< frame::XModel > xModel;
564cdf0e10cSrcweir 
565cdf0e10cSrcweir 	{
566cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
567cdf0e10cSrcweir 		if ( !m_xModel.is() )
568cdf0e10cSrcweir 			return;
569cdf0e10cSrcweir 		xModel = m_xModel;
570cdf0e10cSrcweir 		m_xModel = uno::Reference< frame::XModel >();
571cdf0e10cSrcweir 
572cdf0e10cSrcweir 		if ( m_bBusy )
573cdf0e10cSrcweir 			return;
574cdf0e10cSrcweir 
575cdf0e10cSrcweir 		m_bBusy = sal_True;
576cdf0e10cSrcweir 	}
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	try {
579cdf0e10cSrcweir 		uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
580cdf0e10cSrcweir 		if ( xBroadCaster.is() )
581cdf0e10cSrcweir 			xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
582cdf0e10cSrcweir 																	static_cast< ::cppu::OWeakObject* >( this ),
583cdf0e10cSrcweir 											 						uno::UNO_QUERY ) );
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 		uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
586cdf0e10cSrcweir 		if ( xCloseable.is() )
587cdf0e10cSrcweir 		{
588cdf0e10cSrcweir 			xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
589cdf0e10cSrcweir 																	static_cast< ::cppu::OWeakObject* >( this ),
590cdf0e10cSrcweir 											 						uno::UNO_QUERY ) );
591cdf0e10cSrcweir 			xCloseable->close( sal_True );
592cdf0e10cSrcweir 		}
593cdf0e10cSrcweir 	}
594cdf0e10cSrcweir 	catch( uno::Exception& )
595cdf0e10cSrcweir 	{}
596cdf0e10cSrcweir 
597cdf0e10cSrcweir 	m_bBusy = sal_False;
598cdf0e10cSrcweir }
599cdf0e10cSrcweir 
600cdf0e10cSrcweir //--------------------------------------------------------
notifyEvent(const document::EventObject & aEvent)601cdf0e10cSrcweir void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
602cdf0e10cSrcweir 		throw ( uno::RuntimeException )
603cdf0e10cSrcweir {
604cdf0e10cSrcweir 
605cdf0e10cSrcweir 	uno::Reference< frame::XModel > xModel;
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 	{
608cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
609cdf0e10cSrcweir 		if ( aEvent.Source == m_xModel && aEvent.EventName.equalsAscii( "OnSaveAsDone" ) )
610cdf0e10cSrcweir 		{
611cdf0e10cSrcweir 			// SaveAs operation took place, so just forget the model and deregister listeners
612cdf0e10cSrcweir 			xModel = m_xModel;
613cdf0e10cSrcweir 			m_xModel = uno::Reference< frame::XModel >();
614cdf0e10cSrcweir 		}
615cdf0e10cSrcweir 	}
616cdf0e10cSrcweir 
617cdf0e10cSrcweir 	if ( xModel.is() )
618cdf0e10cSrcweir 	{
619cdf0e10cSrcweir 		try {
620cdf0e10cSrcweir 			uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
621cdf0e10cSrcweir 			if ( xBroadCaster.is() )
622cdf0e10cSrcweir 				xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
623cdf0e10cSrcweir 																		static_cast< ::cppu::OWeakObject* >( this ),
624cdf0e10cSrcweir 											 							uno::UNO_QUERY ) );
625cdf0e10cSrcweir 
626cdf0e10cSrcweir 			uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
627cdf0e10cSrcweir 			if ( xCloseable.is() )
628cdf0e10cSrcweir 				xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
629cdf0e10cSrcweir 																		static_cast< ::cppu::OWeakObject* >( this ),
630cdf0e10cSrcweir 											 							uno::UNO_QUERY ) );
631cdf0e10cSrcweir 		}
632cdf0e10cSrcweir 		catch( uno::Exception& )
633cdf0e10cSrcweir 		{}
634cdf0e10cSrcweir 	}
635cdf0e10cSrcweir }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir //--------------------------------------------------------
queryClosing(const lang::EventObject &,sal_Bool)638cdf0e10cSrcweir void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
639cdf0e10cSrcweir 		throw ( util::CloseVetoException,
640cdf0e10cSrcweir 				uno::RuntimeException )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir }
643cdf0e10cSrcweir 
644cdf0e10cSrcweir //--------------------------------------------------------
notifyClosing(const lang::EventObject & Source)645cdf0e10cSrcweir void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
646cdf0e10cSrcweir 		throw ( uno::RuntimeException )
647cdf0e10cSrcweir {
648cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
649cdf0e10cSrcweir 	if ( Source.Source == m_xModel )
650cdf0e10cSrcweir 		m_xModel = uno::Reference< frame::XModel >();
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir //--------------------------------------------------------
disposing(const lang::EventObject & Source)654cdf0e10cSrcweir void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
655cdf0e10cSrcweir 		throw (uno::RuntimeException)
656cdf0e10cSrcweir {
657cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
658cdf0e10cSrcweir 	if ( Source.Source == m_xModel )
659cdf0e10cSrcweir 		m_xModel = uno::Reference< frame::XModel >();
660cdf0e10cSrcweir };
661cdf0e10cSrcweir 
662