xref: /AOO41X/main/embeddedobj/source/msole/ownview.cxx (revision bfd08df8d53be340829eb05b5154718deb4e1b3d)
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
10cdf0e10cSrcweir  *
11*bfd08df8SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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