xref: /aoo4110/main/sc/source/ui/unoobj/scdetect.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_sc.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include "scdetect.hxx"
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski #include <framework/interaction.hxx>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyValue.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/frame/XFrame.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/frame/XModel.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XWindow.hpp>
35*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XUnoTunnel.hpp>
36*b1cdbd2cSJim Jagielski #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
37*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
38*b1cdbd2cSJim Jagielski #endif
39*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyValue.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/container/XNameAccess.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/io/XInputStream.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/task/XInteractionHandler.hpp>
43*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
44*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/CommandAbortedException.hpp>
45*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveAppException.hpp>
46*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/XContent.hpp>
47*b1cdbd2cSJim Jagielski #include <com/sun/star/packages/zip/ZipIOException.hpp>
48*b1cdbd2cSJim Jagielski 
49*b1cdbd2cSJim Jagielski 
50*b1cdbd2cSJim Jagielski #include <framework/interaction.hxx>
51*b1cdbd2cSJim Jagielski 
52*b1cdbd2cSJim Jagielski #ifndef _TOOLKIT_UNOHLP_HXX
53*b1cdbd2cSJim Jagielski #include <toolkit/helper/vclunohelper.hxx>
54*b1cdbd2cSJim Jagielski #endif
55*b1cdbd2cSJim Jagielski #include <ucbhelper/simpleinteractionrequest.hxx>
56*b1cdbd2cSJim Jagielski 
57*b1cdbd2cSJim Jagielski #include <svtools/parhtml.hxx>
58*b1cdbd2cSJim Jagielski #include <rtl/ustring.h>
59*b1cdbd2cSJim Jagielski #include <rtl/logfile.hxx>
60*b1cdbd2cSJim Jagielski #include <svl/itemset.hxx>
61*b1cdbd2cSJim Jagielski #include <vcl/window.hxx>
62*b1cdbd2cSJim Jagielski #include <svl/eitem.hxx>
63*b1cdbd2cSJim Jagielski #include <svl/stritem.hxx>
64*b1cdbd2cSJim Jagielski #include <tools/urlobj.hxx>
65*b1cdbd2cSJim Jagielski #include <vos/mutex.hxx>
66*b1cdbd2cSJim Jagielski #include <svtools/sfxecode.hxx>
67*b1cdbd2cSJim Jagielski #include <svtools/ehdl.hxx>
68*b1cdbd2cSJim Jagielski #include <sot/storinfo.hxx>
69*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
70*b1cdbd2cSJim Jagielski #include <sfx2/sfxsids.hrc>
71*b1cdbd2cSJim Jagielski #include <sfx2/request.hxx>
72*b1cdbd2cSJim Jagielski #include <sfx2/docfile.hxx>
73*b1cdbd2cSJim Jagielski #include <sfx2/docfilt.hxx>
74*b1cdbd2cSJim Jagielski #include <sfx2/fcontnr.hxx>
75*b1cdbd2cSJim Jagielski #include <sfx2/app.hxx>
76*b1cdbd2cSJim Jagielski #include <sfx2/brokenpackageint.hxx>
77*b1cdbd2cSJim Jagielski #include <sot/storage.hxx>
78*b1cdbd2cSJim Jagielski 
79*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
80*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno;
81*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::io;
82*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::frame;
83*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::task;
84*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::beans;
85*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::lang;
86*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::ucb;
87*b1cdbd2cSJim Jagielski using ::rtl::OUString;
88*b1cdbd2cSJim Jagielski 
ScFilterDetect(const REFERENCE<::com::sun::star::lang::XMultiServiceFactory> &)89*b1cdbd2cSJim Jagielski ScFilterDetect::ScFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& /* xFactory */ )
90*b1cdbd2cSJim Jagielski {
91*b1cdbd2cSJim Jagielski }
92*b1cdbd2cSJim Jagielski 
~ScFilterDetect()93*b1cdbd2cSJim Jagielski ScFilterDetect::~ScFilterDetect()
94*b1cdbd2cSJim Jagielski {
95*b1cdbd2cSJim Jagielski }
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc50[]		= "StarCalc 5.0";
98*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc50Temp[]	= "StarCalc 5.0 Vorlage/Template";
99*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc40[]		= "StarCalc 4.0";
100*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc40Temp[]	= "StarCalc 4.0 Vorlage/Template";
101*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc30[]		= "StarCalc 3.0";
102*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc30Temp[]	= "StarCalc 3.0 Vorlage/Template";
103*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSc10[]		= "StarCalc 1.0";
104*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterXML[]		= "StarOffice XML (Calc)";
105*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterAscii[]		= "Text - txt - csv (StarCalc)";
106*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterLotus[]		= "Lotus";
107*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterQPro6[]		= "Quattro Pro 6.0";
108*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterExcel4[]	= "MS Excel 4.0";
109*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterEx4Temp[]	= "MS Excel 4.0 Vorlage/Template";
110*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterExcel5[]	= "MS Excel 5.0/95";
111*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterEx5Temp[]	= "MS Excel 5.0/95 Vorlage/Template";
112*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterExcel95[]	= "MS Excel 95";
113*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterEx95Temp[]	= "MS Excel 95 Vorlage/Template";
114*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterExcel97[]	= "MS Excel 97";
115*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterEx97Temp[]	= "MS Excel 97 Vorlage/Template";
116*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterExcelXML[]  = "MS Excel 2003 XML";
117*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterDBase[]		= "dBase";
118*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterDif[]		= "DIF";
119*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterSylk[]		= "SYLK";
120*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterHtml[]		= "HTML (StarCalc)";
121*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterHtmlWeb[]	= "calc_HTML_WebQuery";
122*b1cdbd2cSJim Jagielski static const sal_Char __FAR_DATA pFilterRtf[]		= "Rich Text Format (StarCalc)";
123*b1cdbd2cSJim Jagielski 
124*b1cdbd2cSJim Jagielski 
lcl_MayBeAscii(SvStream & rStream)125*b1cdbd2cSJim Jagielski static sal_Bool lcl_MayBeAscii( SvStream& rStream )
126*b1cdbd2cSJim Jagielski {
127*b1cdbd2cSJim Jagielski     // ASCII/CSV is considered possible if there are no null bytes, or a Byte
128*b1cdbd2cSJim Jagielski     // Order Mark is present, or if, for Unicode UCS2/UTF-16, all null bytes
129*b1cdbd2cSJim Jagielski     // are on either even or uneven byte positions.
130*b1cdbd2cSJim Jagielski 
131*b1cdbd2cSJim Jagielski 	rStream.Seek(STREAM_SEEK_TO_BEGIN);
132*b1cdbd2cSJim Jagielski 
133*b1cdbd2cSJim Jagielski     const size_t nBufSize = 2048;
134*b1cdbd2cSJim Jagielski 	sal_uInt16 aBuffer[ nBufSize ];
135*b1cdbd2cSJim Jagielski     sal_uInt8* pByte = reinterpret_cast<sal_uInt8*>(aBuffer);
136*b1cdbd2cSJim Jagielski 	sal_uLong nBytesRead = rStream.Read( pByte, nBufSize*2);
137*b1cdbd2cSJim Jagielski 
138*b1cdbd2cSJim Jagielski 	if ( nBytesRead >= 2 && (aBuffer[0] == 0xfffe || aBuffer[0] == 0xfeff) )
139*b1cdbd2cSJim Jagielski 	{
140*b1cdbd2cSJim Jagielski         // Unicode BOM file may contain null bytes.
141*b1cdbd2cSJim Jagielski 		return sal_True;
142*b1cdbd2cSJim Jagielski 	}
143*b1cdbd2cSJim Jagielski 
144*b1cdbd2cSJim Jagielski 	const sal_uInt16* p = aBuffer;
145*b1cdbd2cSJim Jagielski     sal_uInt16 nMask = 0xffff;
146*b1cdbd2cSJim Jagielski     nBytesRead /= 2;
147*b1cdbd2cSJim Jagielski 	while( nBytesRead-- && nMask )
148*b1cdbd2cSJim Jagielski     {
149*b1cdbd2cSJim Jagielski         sal_uInt16 nVal = *p++ & nMask;
150*b1cdbd2cSJim Jagielski         if (!(nVal & 0x00ff))
151*b1cdbd2cSJim Jagielski             nMask &= 0xff00;
152*b1cdbd2cSJim Jagielski         if (!(nVal & 0xff00))
153*b1cdbd2cSJim Jagielski             nMask &= 0x00ff;
154*b1cdbd2cSJim Jagielski     }
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski 	return nMask != 0;
157*b1cdbd2cSJim Jagielski }
158*b1cdbd2cSJim Jagielski 
lcl_DetectExcelXML(SvStream & rStream,SfxFilterMatcher & rMatcher)159*b1cdbd2cSJim Jagielski static const SfxFilter* lcl_DetectExcelXML( SvStream& rStream, SfxFilterMatcher& rMatcher )
160*b1cdbd2cSJim Jagielski {
161*b1cdbd2cSJim Jagielski     const SfxFilter* pFound = NULL;
162*b1cdbd2cSJim Jagielski     rStream.Seek(STREAM_SEEK_TO_BEGIN);
163*b1cdbd2cSJim Jagielski 
164*b1cdbd2cSJim Jagielski     const size_t nBufSize = 4000;
165*b1cdbd2cSJim Jagielski     sal_uInt8 aBuffer[ nBufSize ];
166*b1cdbd2cSJim Jagielski     sal_uLong nBytesRead = rStream.Read( aBuffer, nBufSize );
167*b1cdbd2cSJim Jagielski     sal_uLong nXMLStart = 0;
168*b1cdbd2cSJim Jagielski 
169*b1cdbd2cSJim Jagielski     // Skip UTF-8 BOM if present.
170*b1cdbd2cSJim Jagielski     // No need to handle UTF-16 etc (also rejected in XMLFilterDetect).
171*b1cdbd2cSJim Jagielski     if ( nBytesRead >= 3 && aBuffer[0] == 0xEF && aBuffer[1] == 0xBB && aBuffer[2] == 0xBF )
172*b1cdbd2cSJim Jagielski         nXMLStart = 3;
173*b1cdbd2cSJim Jagielski 
174*b1cdbd2cSJim Jagielski     if ( nBytesRead >= nXMLStart + 5 && rtl_compareMemory( aBuffer+nXMLStart, "<?xml", 5 ) == 0 )
175*b1cdbd2cSJim Jagielski     {
176*b1cdbd2cSJim Jagielski         // Be consistent with XMLFilterDetect service: Check for presence of "Workbook" in XML file.
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski         rtl::OString aTryStr( "Workbook" );
179*b1cdbd2cSJim Jagielski         rtl::OString aFileString(reinterpret_cast<const sal_Char*>(aBuffer), nBytesRead);
180*b1cdbd2cSJim Jagielski 
181*b1cdbd2cSJim Jagielski         if (aFileString.indexOf(aTryStr) >= 0)
182*b1cdbd2cSJim Jagielski             pFound = rMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterExcelXML) );
183*b1cdbd2cSJim Jagielski     }
184*b1cdbd2cSJim Jagielski 
185*b1cdbd2cSJim Jagielski     return pFound;
186*b1cdbd2cSJim Jagielski }
187*b1cdbd2cSJim Jagielski 
lcl_MayBeDBase(SvStream & rStream)188*b1cdbd2cSJim Jagielski static sal_Bool lcl_MayBeDBase( SvStream& rStream )
189*b1cdbd2cSJim Jagielski {
190*b1cdbd2cSJim Jagielski     // Look for dbf marker, see connectivity/source/inc/dbase/DTable.hxx
191*b1cdbd2cSJim Jagielski     // DBFType for values.
192*b1cdbd2cSJim Jagielski     const sal_uInt8 nValidMarks[] = {
193*b1cdbd2cSJim Jagielski         0x03, 0x04, 0x05, 0x30, 0x43, 0xB3, 0x83, 0x8b, 0x8e, 0xf5 };
194*b1cdbd2cSJim Jagielski     sal_uInt8 nMark;
195*b1cdbd2cSJim Jagielski     rStream.Seek(STREAM_SEEK_TO_BEGIN);
196*b1cdbd2cSJim Jagielski     rStream >> nMark;
197*b1cdbd2cSJim Jagielski     bool bValidMark = false;
198*b1cdbd2cSJim Jagielski     for (size_t i=0; i < sizeof(nValidMarks)/sizeof(nValidMarks[0]) && !bValidMark; ++i)
199*b1cdbd2cSJim Jagielski     {
200*b1cdbd2cSJim Jagielski         if (nValidMarks[i] == nMark)
201*b1cdbd2cSJim Jagielski             bValidMark = true;
202*b1cdbd2cSJim Jagielski     }
203*b1cdbd2cSJim Jagielski     if ( !bValidMark )
204*b1cdbd2cSJim Jagielski         return sal_False;
205*b1cdbd2cSJim Jagielski 
206*b1cdbd2cSJim Jagielski     const size_t nHeaderBlockSize = 32;
207*b1cdbd2cSJim Jagielski     // Empty dbf is >= 32*2+1 bytes in size.
208*b1cdbd2cSJim Jagielski     const size_t nEmptyDbf = nHeaderBlockSize * 2 + 1;
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski 	rStream.Seek(STREAM_SEEK_TO_END);
211*b1cdbd2cSJim Jagielski 	sal_uLong nSize = rStream.Tell();
212*b1cdbd2cSJim Jagielski 	if ( nSize < nEmptyDbf )
213*b1cdbd2cSJim Jagielski 		return sal_False;
214*b1cdbd2cSJim Jagielski 
215*b1cdbd2cSJim Jagielski 	// length of header starts at 8
216*b1cdbd2cSJim Jagielski 	rStream.Seek(8);
217*b1cdbd2cSJim Jagielski 	sal_uInt16 nHeaderLen;
218*b1cdbd2cSJim Jagielski 	rStream >> nHeaderLen;
219*b1cdbd2cSJim Jagielski 
220*b1cdbd2cSJim Jagielski 	if ( nHeaderLen < nEmptyDbf || nSize < nHeaderLen )
221*b1cdbd2cSJim Jagielski 		return sal_False;
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski     // Last byte of header must be 0x0d, this is how it's specified.
224*b1cdbd2cSJim Jagielski     // #i9581#,#i26407# but some applications don't follow the specification
225*b1cdbd2cSJim Jagielski     // and pad the header with one byte 0x00 to reach an
226*b1cdbd2cSJim Jagielski     // even boundary. Some (#i88577# ) even pad more or pad using a 0x1a ^Z
227*b1cdbd2cSJim Jagielski     // control character (#i8857#). This results in:
228*b1cdbd2cSJim Jagielski     // Last byte of header must be 0x0d on 32 bytes boundary.
229*b1cdbd2cSJim Jagielski 	sal_uInt16 nBlocks = (nHeaderLen - 1) / nHeaderBlockSize;
230*b1cdbd2cSJim Jagielski 	sal_uInt8 nEndFlag = 0;
231*b1cdbd2cSJim Jagielski 	while ( nBlocks > 1 && nEndFlag != 0x0d ) {
232*b1cdbd2cSJim Jagielski 		rStream.Seek( nBlocks-- * nHeaderBlockSize );
233*b1cdbd2cSJim Jagielski 		rStream >> nEndFlag;
234*b1cdbd2cSJim Jagielski 	}
235*b1cdbd2cSJim Jagielski 
236*b1cdbd2cSJim Jagielski 	return ( 0x0d == nEndFlag );
237*b1cdbd2cSJim Jagielski }
238*b1cdbd2cSJim Jagielski 
239*b1cdbd2cSJim Jagielski #if 0
240*b1cdbd2cSJim Jagielski static sal_Bool lcl_IsAnyXMLFilter( const SfxFilter* pFilter )
241*b1cdbd2cSJim Jagielski {
242*b1cdbd2cSJim Jagielski 	if ( !pFilter )
243*b1cdbd2cSJim Jagielski 		return sal_False;
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski 	//	sal_True for XML file or template
246*b1cdbd2cSJim Jagielski 	//	(template filter has no internal name -> allow configuration key names)
247*b1cdbd2cSJim Jagielski 
248*b1cdbd2cSJim Jagielski 	String aName(pFilter->GetFilterName());
249*b1cdbd2cSJim Jagielski 	return aName.EqualsAscii(pFilterXML) ||
250*b1cdbd2cSJim Jagielski 		   aName.EqualsAscii("calc_StarOffice_XML_Calc") ||
251*b1cdbd2cSJim Jagielski 		   aName.EqualsAscii("calc_StarOffice_XML_Calc_Template");
252*b1cdbd2cSJim Jagielski }
253*b1cdbd2cSJim Jagielski #endif
254*b1cdbd2cSJim Jagielski 
detect(::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & lDescriptor)255*b1cdbd2cSJim Jagielski ::rtl::OUString SAL_CALL ScFilterDetect::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
256*b1cdbd2cSJim Jagielski {
257*b1cdbd2cSJim Jagielski     REFERENCE< XInputStream > xStream;
258*b1cdbd2cSJim Jagielski     REFERENCE< XContent > xContent;
259*b1cdbd2cSJim Jagielski     REFERENCE< XInteractionHandler > xInteraction;
260*b1cdbd2cSJim Jagielski     String aURL;
261*b1cdbd2cSJim Jagielski 	::rtl::OUString sTemp;
262*b1cdbd2cSJim Jagielski     String aTypeName;            // a name describing the type (from MediaDescriptor, usually from flat detection)
263*b1cdbd2cSJim Jagielski     String aPreselectedFilterName;      // a name describing the filter to use (from MediaDescriptor, usually from UI action)
264*b1cdbd2cSJim Jagielski 
265*b1cdbd2cSJim Jagielski 	::rtl::OUString aDocumentTitle; // interesting only if set in this method
266*b1cdbd2cSJim Jagielski 
267*b1cdbd2cSJim Jagielski 	// opening as template is done when a parameter tells to do so and a template filter can be detected
268*b1cdbd2cSJim Jagielski     // (otherwise no valid filter would be found) or if the detected filter is a template filter and
269*b1cdbd2cSJim Jagielski 	// there is no parameter that forbids to open as template
270*b1cdbd2cSJim Jagielski 	sal_Bool bOpenAsTemplate = sal_False;
271*b1cdbd2cSJim Jagielski     sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
272*b1cdbd2cSJim Jagielski 
273*b1cdbd2cSJim Jagielski 	sal_Bool bRepairPackage = sal_False;
274*b1cdbd2cSJim Jagielski 	sal_Bool bRepairAllowed = sal_False;
275*b1cdbd2cSJim Jagielski 
276*b1cdbd2cSJim Jagielski 	// now some parameters that can already be in the array, but may be overwritten or new inserted here
277*b1cdbd2cSJim Jagielski 	// remember their indices in the case new values must be added to the array
278*b1cdbd2cSJim Jagielski 	sal_Int32 nPropertyCount = lDescriptor.getLength();
279*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfFilterName = -1;
280*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfInputStream = -1;
281*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfContent = -1;
282*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfReadOnlyFlag = -1;
283*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfTemplateFlag = -1;
284*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfDocumentTitle = -1;
285*b1cdbd2cSJim Jagielski     bool bFakeXLS = false;
286*b1cdbd2cSJim Jagielski 
287*b1cdbd2cSJim Jagielski     for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
288*b1cdbd2cSJim Jagielski 	{
289*b1cdbd2cSJim Jagielski         // extract properties
290*b1cdbd2cSJim Jagielski         if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
291*b1cdbd2cSJim Jagielski 		{
292*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
293*b1cdbd2cSJim Jagielski 			aURL = sTemp;
294*b1cdbd2cSJim Jagielski 		}
295*b1cdbd2cSJim Jagielski         else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
296*b1cdbd2cSJim Jagielski 		{
297*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
298*b1cdbd2cSJim Jagielski 			aURL = sTemp;
299*b1cdbd2cSJim Jagielski 		}
300*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
301*b1cdbd2cSJim Jagielski 		{
302*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
303*b1cdbd2cSJim Jagielski             aTypeName = sTemp;
304*b1cdbd2cSJim Jagielski 		}
305*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
306*b1cdbd2cSJim Jagielski 		{
307*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
308*b1cdbd2cSJim Jagielski             aPreselectedFilterName = sTemp;
309*b1cdbd2cSJim Jagielski 
310*b1cdbd2cSJim Jagielski             // if the preselected filter name is not correct, it must be erased after detection
311*b1cdbd2cSJim Jagielski             // remember index of property to get access to it later
312*b1cdbd2cSJim Jagielski             nIndexOfFilterName = nProperty;
313*b1cdbd2cSJim Jagielski 		}
314*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
315*b1cdbd2cSJim Jagielski             nIndexOfInputStream = nProperty;
316*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
317*b1cdbd2cSJim Jagielski             nIndexOfReadOnlyFlag = nProperty;
318*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
319*b1cdbd2cSJim Jagielski             nIndexOfContent = nProperty;
320*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
321*b1cdbd2cSJim Jagielski 		{
322*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= bOpenAsTemplate;
323*b1cdbd2cSJim Jagielski             nIndexOfTemplateFlag = nProperty;
324*b1cdbd2cSJim Jagielski 		}
325*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
326*b1cdbd2cSJim Jagielski             lDescriptor[nProperty].Value >>= xInteraction;
327*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) )
328*b1cdbd2cSJim Jagielski             lDescriptor[nProperty].Value >>= bRepairPackage;
329*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
330*b1cdbd2cSJim Jagielski             nIndexOfDocumentTitle = nProperty;
331*b1cdbd2cSJim Jagielski 	}
332*b1cdbd2cSJim Jagielski 
333*b1cdbd2cSJim Jagielski     // can't check the type for external filters, so set the "dont" flag accordingly
334*b1cdbd2cSJim Jagielski     ::vos::OGuard aGuard( Application::GetSolarMutex() );
335*b1cdbd2cSJim Jagielski     //SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED;
336*b1cdbd2cSJim Jagielski 
337*b1cdbd2cSJim Jagielski     SfxAllItemSet *pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
338*b1cdbd2cSJim Jagielski     TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
339*b1cdbd2cSJim Jagielski     SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
340*b1cdbd2cSJim Jagielski 
341*b1cdbd2cSJim Jagielski     bWasReadOnly = pItem && pItem->GetValue();
342*b1cdbd2cSJim Jagielski 
343*b1cdbd2cSJim Jagielski 	const SfxFilter* pFilter = 0;
344*b1cdbd2cSJim Jagielski 	String aPrefix = String::CreateFromAscii( "private:factory/" );
345*b1cdbd2cSJim Jagielski 	if( aURL.Match( aPrefix ) == aPrefix.Len() )
346*b1cdbd2cSJim Jagielski 	{
347*b1cdbd2cSJim Jagielski 		String aPattern( aPrefix );
348*b1cdbd2cSJim Jagielski 		aPattern += String::CreateFromAscii("scalc");
349*b1cdbd2cSJim Jagielski 		if ( aURL.Match( aPattern ) >= aPattern.Len() )
350*b1cdbd2cSJim Jagielski 			pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
351*b1cdbd2cSJim Jagielski 	}
352*b1cdbd2cSJim Jagielski 	else
353*b1cdbd2cSJim Jagielski 	{
354*b1cdbd2cSJim Jagielski 		// container for Calc filters
355*b1cdbd2cSJim Jagielski 		SfxFilterMatcher aMatcher( String::CreateFromAscii("scalc") );
356*b1cdbd2cSJim Jagielski 		if ( aPreselectedFilterName.Len() )
357*b1cdbd2cSJim Jagielski 			pFilter = SfxFilter::GetFilterByName( aPreselectedFilterName );
358*b1cdbd2cSJim Jagielski 		else if( aTypeName.Len() )
359*b1cdbd2cSJim Jagielski 			pFilter = aMatcher.GetFilter4EA( aTypeName );
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski 	    // ctor of SfxMedium uses owner transition of ItemSet
362*b1cdbd2cSJim Jagielski 	    SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, sal_False, NULL, pSet );
363*b1cdbd2cSJim Jagielski 	    aMedium.UseInteractionHandler( sal_True );
364*b1cdbd2cSJim Jagielski 
365*b1cdbd2cSJim Jagielski 	    sal_Bool bIsStorage = aMedium.IsStorage();
366*b1cdbd2cSJim Jagielski 	    if ( aMedium.GetErrorCode() == ERRCODE_NONE )
367*b1cdbd2cSJim Jagielski 	    {
368*b1cdbd2cSJim Jagielski 	        // remember input stream and content and put them into the descriptor later
369*b1cdbd2cSJim Jagielski 			// should be done here since later the medium can switch to a version
370*b1cdbd2cSJim Jagielski 	        xStream.set(aMedium.GetInputStream());
371*b1cdbd2cSJim Jagielski 			xContent.set(aMedium.GetContent());
372*b1cdbd2cSJim Jagielski         	bReadOnly = aMedium.IsReadOnly();
373*b1cdbd2cSJim Jagielski 
374*b1cdbd2cSJim Jagielski 	        // maybe that IsStorage() already created an error!
375*b1cdbd2cSJim Jagielski 	        if ( bIsStorage )
376*b1cdbd2cSJim Jagielski 			{
377*b1cdbd2cSJim Jagielski                 uno::Reference < embed::XStorage > xStorage(aMedium.GetStorage( sal_False ));
378*b1cdbd2cSJim Jagielski 				if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
379*b1cdbd2cSJim Jagielski 				{
380*b1cdbd2cSJim Jagielski 					// error during storage creation means _here_ that the medium
381*b1cdbd2cSJim Jagielski 					// is broken, but we can not handle it in medium since unpossibility
382*b1cdbd2cSJim Jagielski 					// to create a storage does not _always_ means that the medium is broken
383*b1cdbd2cSJim Jagielski 					aMedium.SetError( aMedium.GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
384*b1cdbd2cSJim Jagielski 					if ( xInteraction.is() )
385*b1cdbd2cSJim Jagielski 					{
386*b1cdbd2cSJim Jagielski 						OUString empty;
387*b1cdbd2cSJim Jagielski 						try
388*b1cdbd2cSJim Jagielski 						{
389*b1cdbd2cSJim Jagielski 							InteractiveAppException xException( empty,
390*b1cdbd2cSJim Jagielski 															REFERENCE< XInterface >(),
391*b1cdbd2cSJim Jagielski 															InteractionClassification_ERROR,
392*b1cdbd2cSJim Jagielski 															aMedium.GetError() );
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski                             REFERENCE< XInteractionRequest > xRequest(
395*b1cdbd2cSJim Jagielski 								new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
396*b1cdbd2cSJim Jagielski 																 	 ucbhelper::CONTINUATION_APPROVE ) );
397*b1cdbd2cSJim Jagielski 							xInteraction->handle( xRequest );
398*b1cdbd2cSJim Jagielski 						}
399*b1cdbd2cSJim Jagielski 						catch ( Exception & ) {};
400*b1cdbd2cSJim Jagielski 					}
401*b1cdbd2cSJim Jagielski 				}
402*b1cdbd2cSJim Jagielski                 else if ( xStorage.is() )
403*b1cdbd2cSJim Jagielski 				{
404*b1cdbd2cSJim Jagielski 					try
405*b1cdbd2cSJim Jagielski 					{
406*b1cdbd2cSJim Jagielski                         String aFilterName;
407*b1cdbd2cSJim Jagielski                         if ( pFilter )
408*b1cdbd2cSJim Jagielski                             aFilterName = pFilter->GetName();
409*b1cdbd2cSJim Jagielski                         aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsOwnTemplateFormat() : sal_False, &aFilterName );
410*b1cdbd2cSJim Jagielski 					}
411*b1cdbd2cSJim Jagielski 					catch( lang::WrappedTargetException& aWrap )
412*b1cdbd2cSJim Jagielski 					{
413*b1cdbd2cSJim Jagielski 						packages::zip::ZipIOException aZipException;
414*b1cdbd2cSJim Jagielski 
415*b1cdbd2cSJim Jagielski 						// repairing is done only if this type is requested from outside
416*b1cdbd2cSJim Jagielski 						if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() )
417*b1cdbd2cSJim Jagielski 						{
418*b1cdbd2cSJim Jagielski 							if ( xInteraction.is() )
419*b1cdbd2cSJim Jagielski 							{
420*b1cdbd2cSJim Jagielski 								// the package is broken one
421*b1cdbd2cSJim Jagielski        							aDocumentTitle = aMedium.GetURLObject().getName(
422*b1cdbd2cSJim Jagielski 															INetURLObject::LAST_SEGMENT,
423*b1cdbd2cSJim Jagielski 															true,
424*b1cdbd2cSJim Jagielski 															INetURLObject::DECODE_WITH_CHARSET );
425*b1cdbd2cSJim Jagielski 
426*b1cdbd2cSJim Jagielski 								if ( !bRepairPackage )
427*b1cdbd2cSJim Jagielski 								{
428*b1cdbd2cSJim Jagielski                                     // ask the user whether he wants to try to repair
429*b1cdbd2cSJim Jagielski                                     RequestPackageReparation aRequest( aDocumentTitle );
430*b1cdbd2cSJim Jagielski                                     xInteraction->handle( aRequest.GetRequest() );
431*b1cdbd2cSJim Jagielski                                     bRepairAllowed = aRequest.isApproved();
432*b1cdbd2cSJim Jagielski 								}
433*b1cdbd2cSJim Jagielski 
434*b1cdbd2cSJim Jagielski 								if ( !bRepairAllowed )
435*b1cdbd2cSJim Jagielski 								{
436*b1cdbd2cSJim Jagielski 									// repair either not allowed or not successful
437*b1cdbd2cSJim Jagielski                                     NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
438*b1cdbd2cSJim Jagielski                                     xInteraction->handle( aNotifyRequest.GetRequest() );
439*b1cdbd2cSJim Jagielski 								}
440*b1cdbd2cSJim Jagielski 							}
441*b1cdbd2cSJim Jagielski 
442*b1cdbd2cSJim Jagielski 							if ( !bRepairAllowed )
443*b1cdbd2cSJim Jagielski 								aTypeName.Erase();
444*b1cdbd2cSJim Jagielski 						}
445*b1cdbd2cSJim Jagielski 					}
446*b1cdbd2cSJim Jagielski 					catch( uno::RuntimeException& )
447*b1cdbd2cSJim Jagielski 					{
448*b1cdbd2cSJim Jagielski 						throw;
449*b1cdbd2cSJim Jagielski 					}
450*b1cdbd2cSJim Jagielski 					catch( uno::Exception& )
451*b1cdbd2cSJim Jagielski 					{
452*b1cdbd2cSJim Jagielski 						aTypeName.Erase();
453*b1cdbd2cSJim Jagielski 					}
454*b1cdbd2cSJim Jagielski 
455*b1cdbd2cSJim Jagielski                    	if ( aTypeName.Len() )
456*b1cdbd2cSJim Jagielski                        	pFilter = SfxFilterMatcher( String::CreateFromAscii("scalc") ).GetFilter4EA( aTypeName );
457*b1cdbd2cSJim Jagielski 
458*b1cdbd2cSJim Jagielski 				}
459*b1cdbd2cSJim Jagielski 			}
460*b1cdbd2cSJim Jagielski 			else
461*b1cdbd2cSJim Jagielski 			{
462*b1cdbd2cSJim Jagielski                 bool bIsXLS = false;
463*b1cdbd2cSJim Jagielski                 SvStream* pStream = aMedium.GetInStream();
464*b1cdbd2cSJim Jagielski                 const SfxFilter* pPreselectedFilter = pFilter;
465*b1cdbd2cSJim Jagielski                 if ( pPreselectedFilter && pPreselectedFilter->GetName().SearchAscii("Excel") != STRING_NOTFOUND )
466*b1cdbd2cSJim Jagielski                     bIsXLS = true;
467*b1cdbd2cSJim Jagielski                 pFilter = 0;
468*b1cdbd2cSJim Jagielski                 if ( pStream )
469*b1cdbd2cSJim Jagielski                 {
470*b1cdbd2cSJim Jagielski                     SotStorageRef aStorage = new SotStorage ( pStream, sal_False );
471*b1cdbd2cSJim Jagielski                     if ( !aStorage->GetError() )
472*b1cdbd2cSJim Jagielski                     {
473*b1cdbd2cSJim Jagielski                         // Excel-5: detect through contained streams
474*b1cdbd2cSJim Jagielski                         // there are some "excel" formats from 3rd party vendors that need to be distinguished
475*b1cdbd2cSJim Jagielski                         String aStreamName(RTL_CONSTASCII_STRINGPARAM("Workbook"));
476*b1cdbd2cSJim Jagielski                         sal_Bool bExcel97Stream = ( aStorage->IsStream( aStreamName ) );
477*b1cdbd2cSJim Jagielski 
478*b1cdbd2cSJim Jagielski                         aStreamName = String(RTL_CONSTASCII_STRINGPARAM("Book"));
479*b1cdbd2cSJim Jagielski                         sal_Bool bExcel5Stream = ( aStorage->IsStream( aStreamName ) );
480*b1cdbd2cSJim Jagielski                         if ( bExcel97Stream || bExcel5Stream )
481*b1cdbd2cSJim Jagielski                         {
482*b1cdbd2cSJim Jagielski                             if ( bExcel97Stream )
483*b1cdbd2cSJim Jagielski                             {
484*b1cdbd2cSJim Jagielski                                 String aOldName;
485*b1cdbd2cSJim Jagielski                                 sal_Bool bIsCalcFilter = sal_True;
486*b1cdbd2cSJim Jagielski                                 if ( pPreselectedFilter )
487*b1cdbd2cSJim Jagielski                                 {
488*b1cdbd2cSJim Jagielski                                     // cross filter; now this should be a type detection only, not a filter detection
489*b1cdbd2cSJim Jagielski                                     // we can simulate it by preserving the preselected filter if the type matches
490*b1cdbd2cSJim Jagielski                                     // example: Excel filters for Writer
491*b1cdbd2cSJim Jagielski                                     aOldName = pPreselectedFilter->GetFilterName();
492*b1cdbd2cSJim Jagielski                                     bIsCalcFilter = pPreselectedFilter->GetServiceName().EqualsAscii("com.sun.star.sheet.SpreadsheetDocument");
493*b1cdbd2cSJim Jagielski                                 }
494*b1cdbd2cSJim Jagielski 
495*b1cdbd2cSJim Jagielski                                 if ( aOldName.EqualsAscii(pFilterEx97Temp) || !bIsCalcFilter )
496*b1cdbd2cSJim Jagielski                                 {
497*b1cdbd2cSJim Jagielski                                     //  Excel 97 template selected -> keep selection
498*b1cdbd2cSJim Jagielski                                 }
499*b1cdbd2cSJim Jagielski                                 else if ( bExcel5Stream &&
500*b1cdbd2cSJim Jagielski                                             ( aOldName.EqualsAscii(pFilterExcel5) || aOldName.EqualsAscii(pFilterEx5Temp) ||
501*b1cdbd2cSJim Jagielski                                             aOldName.EqualsAscii(pFilterExcel95) || aOldName.EqualsAscii(pFilterEx95Temp) ) )
502*b1cdbd2cSJim Jagielski                                 {
503*b1cdbd2cSJim Jagielski                                     //  dual format file and Excel 5 selected -> keep selection
504*b1cdbd2cSJim Jagielski                                 }
505*b1cdbd2cSJim Jagielski                                 else
506*b1cdbd2cSJim Jagielski                                 {
507*b1cdbd2cSJim Jagielski                                     //  else use Excel 97 filter
508*b1cdbd2cSJim Jagielski                                     pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterExcel97) );
509*b1cdbd2cSJim Jagielski                                 }
510*b1cdbd2cSJim Jagielski                             }
511*b1cdbd2cSJim Jagielski                             else if ( bExcel5Stream )
512*b1cdbd2cSJim Jagielski                             {
513*b1cdbd2cSJim Jagielski                                 String aOldName;
514*b1cdbd2cSJim Jagielski                                 sal_Bool bIsCalcFilter = sal_True;
515*b1cdbd2cSJim Jagielski                                 if ( pPreselectedFilter )
516*b1cdbd2cSJim Jagielski                                 {
517*b1cdbd2cSJim Jagielski                                     // cross filter; now this should be a type detection only, not a filter detection
518*b1cdbd2cSJim Jagielski                                     // we can simulate it by preserving the preselected filter if the type matches
519*b1cdbd2cSJim Jagielski                                     // example: Excel filters for Writer
520*b1cdbd2cSJim Jagielski                                     aOldName = pPreselectedFilter->GetFilterName();
521*b1cdbd2cSJim Jagielski                                     bIsCalcFilter = pPreselectedFilter->GetServiceName().EqualsAscii("com.sun.star.sheet.SpreadsheetDocument");
522*b1cdbd2cSJim Jagielski                                 }
523*b1cdbd2cSJim Jagielski 
524*b1cdbd2cSJim Jagielski                                 if ( aOldName.EqualsAscii(pFilterExcel95) || aOldName.EqualsAscii(pFilterEx95Temp) ||
525*b1cdbd2cSJim Jagielski                                         aOldName.EqualsAscii(pFilterEx5Temp) || !bIsCalcFilter )
526*b1cdbd2cSJim Jagielski                                 {
527*b1cdbd2cSJim Jagielski                                     //  Excel 95 oder Vorlage (5 oder 95) eingestellt -> auch gut
528*b1cdbd2cSJim Jagielski                                 }
529*b1cdbd2cSJim Jagielski                                 else if ( aOldName.EqualsAscii(pFilterEx97Temp) )
530*b1cdbd2cSJim Jagielski                                 {
531*b1cdbd2cSJim Jagielski                                     // #101923# auto detection has found template -> return Excel5 template
532*b1cdbd2cSJim Jagielski                                     pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterEx5Temp) );
533*b1cdbd2cSJim Jagielski                                 }
534*b1cdbd2cSJim Jagielski                                 else
535*b1cdbd2cSJim Jagielski                                 {
536*b1cdbd2cSJim Jagielski                                     //  sonst wird als Excel 5-Datei erkannt
537*b1cdbd2cSJim Jagielski                                     pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterExcel5) );
538*b1cdbd2cSJim Jagielski                                 }
539*b1cdbd2cSJim Jagielski                             }
540*b1cdbd2cSJim Jagielski                         }
541*b1cdbd2cSJim Jagielski                     }
542*b1cdbd2cSJim Jagielski                     else
543*b1cdbd2cSJim Jagielski                     {
544*b1cdbd2cSJim Jagielski                         SvStream &rStr = *pStream;
545*b1cdbd2cSJim Jagielski 
546*b1cdbd2cSJim Jagielski                         // Tabelle mit Suchmustern
547*b1cdbd2cSJim Jagielski                         // Bedeutung der Sequenzen
548*b1cdbd2cSJim Jagielski                         // 0x00??: genau Byte 0x?? muss an dieser Stelle stehen
549*b1cdbd2cSJim Jagielski                         // 0x0100: ein Byte ueberlesen (don't care)
550*b1cdbd2cSJim Jagielski                         // 0x02nn: ein Byte aus 0xnn Alternativen folgt
551*b1cdbd2cSJim Jagielski                         // 0x8000: Erkennung abgeschlossen
552*b1cdbd2cSJim Jagielski                         //
553*b1cdbd2cSJim Jagielski 
554*b1cdbd2cSJim Jagielski         #define M_DC        0x0100
555*b1cdbd2cSJim Jagielski         #define M_ALT(ANZ)  (0x0200+(ANZ))
556*b1cdbd2cSJim Jagielski         #define M_ENDE      0x8000
557*b1cdbd2cSJim Jagielski 
558*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pLotus[] =      // Lotus 1/1A/2
559*b1cdbd2cSJim Jagielski                             { 0x0000, 0x0000, 0x0002, 0x0000,
560*b1cdbd2cSJim Jagielski                             M_ALT(2), 0x0004, 0x0006,
561*b1cdbd2cSJim Jagielski                             0x0004, M_ENDE };
562*b1cdbd2cSJim Jagielski 
563*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pLotusNew[] =   // Lotus >= 9.7
564*b1cdbd2cSJim Jagielski                             { 0x0000, 0x0000, M_DC, 0x0000,     // Rec# + Len (0x1a)
565*b1cdbd2cSJim Jagielski                               M_ALT(3), 0x0003, 0x0004, 0x0005, // File Revision Code 97->ME
566*b1cdbd2cSJim Jagielski                               0x0010, 0x0004, 0x0000, 0x0000,
567*b1cdbd2cSJim Jagielski                               M_ENDE };
568*b1cdbd2cSJim Jagielski 
569*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pExcel1[] =     // Excel BIFF2, BIFF3, BIFF4
570*b1cdbd2cSJim Jagielski                             {   0x09,                                   // lobyte of BOF rec ID (0x0009, 0x0209, 0x0409)
571*b1cdbd2cSJim Jagielski                                 M_ALT(3), 0x00, 0x02, 0x04,             // hibyte of BOF rec ID (0x0009, 0x0209, 0x0409)
572*b1cdbd2cSJim Jagielski                                 M_ALT(3), 4, 6, 8,                      // lobyte of BOF rec size (4, 6, 8, 16)
573*b1cdbd2cSJim Jagielski                                 0x00,                                   // hibyte of BOF rec size (4, 6, 8, 16)
574*b1cdbd2cSJim Jagielski                                 M_DC, M_DC,                             // any version
575*b1cdbd2cSJim Jagielski                                 M_ALT(3), 0x10, 0x20, 0x40,             // lobyte of data type (0x0010, 0x0020, 0x0040)
576*b1cdbd2cSJim Jagielski                                 0x00,                                   // hibyte of data type (0x0010, 0x0020, 0x0040)
577*b1cdbd2cSJim Jagielski                                 M_ENDE };
578*b1cdbd2cSJim Jagielski 
579*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pExcel2[] =     // Excel BIFF4 Workspace
580*b1cdbd2cSJim Jagielski                             {   0x09,                                   // lobyte of BOF rec ID (0x0409)
581*b1cdbd2cSJim Jagielski                                 0x04,                                   // hibyte of BOF rec ID (0x0409)
582*b1cdbd2cSJim Jagielski                                 M_ALT(3), 4, 6, 8,                      // lobyte of BOF rec size (4, 6, 8, 16)
583*b1cdbd2cSJim Jagielski                                 0x00,                                   // hibyte of BOF rec size (4, 6, 8, 16)
584*b1cdbd2cSJim Jagielski                                 M_DC, M_DC,                             // any version
585*b1cdbd2cSJim Jagielski                                 0x00,                                   // lobyte of data type (0x0100)
586*b1cdbd2cSJim Jagielski                                 0x01,                                   // hibyte of data type (0x0100)
587*b1cdbd2cSJim Jagielski                                 M_ENDE };
588*b1cdbd2cSJim Jagielski 
589*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pExcel3[] =     // #i23425# Excel BIFF5, BIFF7, BIFF8 (simple book stream)
590*b1cdbd2cSJim Jagielski                             {   0x09,                                   // lobyte of BOF rec ID (0x0809)
591*b1cdbd2cSJim Jagielski                                 0x08,                                   // hibyte of BOF rec ID (0x0809)
592*b1cdbd2cSJim Jagielski                                 M_ALT(4), 4, 6, 8, 16,                  // lobyte of BOF rec size
593*b1cdbd2cSJim Jagielski                                 0x00,                                   // hibyte of BOF rec size
594*b1cdbd2cSJim Jagielski                                 M_DC, M_DC,                             // any version
595*b1cdbd2cSJim Jagielski                                 M_ALT(5), 0x05, 0x06, 0x10, 0x20, 0x40, // lobyte of data type
596*b1cdbd2cSJim Jagielski                                 0x00,                                   // hibyte of data type
597*b1cdbd2cSJim Jagielski                                 M_ENDE };
598*b1cdbd2cSJim Jagielski 
599*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pSc10[] =       // StarCalc 1.0 Dokumente
600*b1cdbd2cSJim Jagielski                             { 'B', 'l', 'a', 'i', 's', 'e', '-', 'T', 'a', 'b', 'e', 'l', 'l',
601*b1cdbd2cSJim Jagielski                             'e', 0x000A, 0x000D, 0x0000,    // Sc10CopyRight[16]
602*b1cdbd2cSJim Jagielski                             M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC, M_DC,
603*b1cdbd2cSJim Jagielski                             M_DC, M_DC,                   // Sc10CopyRight[29]
604*b1cdbd2cSJim Jagielski                             M_ALT(2), 0x0065, 0x0066,     // Versionsnummer 101 oder 102
605*b1cdbd2cSJim Jagielski                             0x0000,
606*b1cdbd2cSJim Jagielski                             M_ENDE };
607*b1cdbd2cSJim Jagielski 
608*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pLotus2[] =     // Lotus >3
609*b1cdbd2cSJim Jagielski                             { 0x0000, 0x0000, 0x001A, 0x0000,   // Rec# + Len (26)
610*b1cdbd2cSJim Jagielski                             M_ALT(2), 0x0000, 0x0002,         // File Revision Code
611*b1cdbd2cSJim Jagielski                             0x0010,
612*b1cdbd2cSJim Jagielski                             0x0004, 0x0000,                   // File Revision Subcode
613*b1cdbd2cSJim Jagielski                             M_ENDE };
614*b1cdbd2cSJim Jagielski 
615*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pQPro[] =
616*b1cdbd2cSJim Jagielski                                { 0x0000, 0x0000, 0x0002, 0x0000,
617*b1cdbd2cSJim Jagielski                                  M_ALT(4), 0x0001, 0x0002, // WB1, WB2
618*b1cdbd2cSJim Jagielski                                  0x0006, 0x0007,           // QPro 6/7 (?)
619*b1cdbd2cSJim Jagielski                                  0x0010,
620*b1cdbd2cSJim Jagielski                                  M_ENDE };
621*b1cdbd2cSJim Jagielski 
622*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pDIF1[] =       // DIF mit CR-LF
623*b1cdbd2cSJim Jagielski                             {
624*b1cdbd2cSJim Jagielski                             'T', 'A', 'B', 'L', 'E',
625*b1cdbd2cSJim Jagielski                             M_DC, M_DC,
626*b1cdbd2cSJim Jagielski                             '0', ',', '1',
627*b1cdbd2cSJim Jagielski                             M_DC, M_DC,
628*b1cdbd2cSJim Jagielski                             '\"',
629*b1cdbd2cSJim Jagielski                             M_ENDE };
630*b1cdbd2cSJim Jagielski 
631*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pDIF2[] =       // DIF mit CR oder LF
632*b1cdbd2cSJim Jagielski                             {
633*b1cdbd2cSJim Jagielski                             'T', 'A', 'B', 'L', 'E',
634*b1cdbd2cSJim Jagielski                             M_DC,
635*b1cdbd2cSJim Jagielski                             '0', ',', '1',
636*b1cdbd2cSJim Jagielski                             M_DC,
637*b1cdbd2cSJim Jagielski                             '\"',
638*b1cdbd2cSJim Jagielski                             M_ENDE };
639*b1cdbd2cSJim Jagielski 
640*b1cdbd2cSJim Jagielski                         static const sal_uInt16 pSylk[] =       // Sylk
641*b1cdbd2cSJim Jagielski                             {
642*b1cdbd2cSJim Jagielski                             'I', 'D', ';',
643*b1cdbd2cSJim Jagielski                             M_ALT(3), 'P', 'N', 'E',        // 'P' plus undocumented Excel extensions 'N' and 'E'
644*b1cdbd2cSJim Jagielski                             M_ENDE };
645*b1cdbd2cSJim Jagielski 
646*b1cdbd2cSJim Jagielski                         static const sal_uInt16 *ppFilterPatterns[] =      // Arrays mit Suchmustern
647*b1cdbd2cSJim Jagielski                             {
648*b1cdbd2cSJim Jagielski                             pLotus,
649*b1cdbd2cSJim Jagielski                             pExcel1,
650*b1cdbd2cSJim Jagielski                             pExcel2,
651*b1cdbd2cSJim Jagielski                             pExcel3,
652*b1cdbd2cSJim Jagielski                             pSc10,
653*b1cdbd2cSJim Jagielski                             pDIF1,
654*b1cdbd2cSJim Jagielski                             pDIF2,
655*b1cdbd2cSJim Jagielski                             pSylk,
656*b1cdbd2cSJim Jagielski                             pLotusNew,
657*b1cdbd2cSJim Jagielski                             pLotus2,
658*b1cdbd2cSJim Jagielski                             pQPro
659*b1cdbd2cSJim Jagielski                             };
660*b1cdbd2cSJim Jagielski                         const sal_uInt16 nFilterCount = sizeof(ppFilterPatterns) / sizeof(ppFilterPatterns[0]);
661*b1cdbd2cSJim Jagielski 
662*b1cdbd2cSJim Jagielski                         static const sal_Char* const pFilterName[] =     // zugehoerige Filter
663*b1cdbd2cSJim Jagielski                             {
664*b1cdbd2cSJim Jagielski                             pFilterLotus,
665*b1cdbd2cSJim Jagielski                             pFilterExcel4,
666*b1cdbd2cSJim Jagielski                             pFilterExcel4,
667*b1cdbd2cSJim Jagielski                             pFilterExcel4,
668*b1cdbd2cSJim Jagielski                             pFilterSc10,
669*b1cdbd2cSJim Jagielski                             pFilterDif,
670*b1cdbd2cSJim Jagielski                             pFilterDif,
671*b1cdbd2cSJim Jagielski                             pFilterSylk,
672*b1cdbd2cSJim Jagielski                             pFilterLotus,
673*b1cdbd2cSJim Jagielski                             pFilterLotus,
674*b1cdbd2cSJim Jagielski                             pFilterQPro6
675*b1cdbd2cSJim Jagielski                             };
676*b1cdbd2cSJim Jagielski 
677*b1cdbd2cSJim Jagielski                         // const sal_uInt16 nByteMask = 0xFF;
678*b1cdbd2cSJim Jagielski 
679*b1cdbd2cSJim Jagielski                         // suchen Sie jetzt!
680*b1cdbd2cSJim Jagielski                         // ... realisiert ueber 'Mustererkennung'
681*b1cdbd2cSJim Jagielski 
682*b1cdbd2cSJim Jagielski                         sal_uInt8            nAkt;
683*b1cdbd2cSJim Jagielski                         sal_Bool            bSync;          // Datei und Muster stimmen ueberein
684*b1cdbd2cSJim Jagielski                         sal_uInt16          nFilter;        // Zaehler ueber alle Filter
685*b1cdbd2cSJim Jagielski                         const sal_uInt16    *pSearch;       // aktuelles Musterwort
686*b1cdbd2cSJim Jagielski 
687*b1cdbd2cSJim Jagielski                         for ( nFilter = 0 ; nFilter < nFilterCount ; nFilter++ )
688*b1cdbd2cSJim Jagielski                         {
689*b1cdbd2cSJim Jagielski                             rStr.Seek( 0 ); // am Anfang war alles Uebel...
690*b1cdbd2cSJim Jagielski                             rStr >> nAkt;
691*b1cdbd2cSJim Jagielski                             pSearch = ppFilterPatterns[ nFilter ];
692*b1cdbd2cSJim Jagielski                             bSync = sal_True;
693*b1cdbd2cSJim Jagielski                             while( !rStr.IsEof() && bSync )
694*b1cdbd2cSJim Jagielski                             {
695*b1cdbd2cSJim Jagielski                                 register sal_uInt16 nMuster = *pSearch;
696*b1cdbd2cSJim Jagielski 
697*b1cdbd2cSJim Jagielski                                 if( nMuster < 0x0100 )
698*b1cdbd2cSJim Jagielski                                 { //                                direkter Byte-Vergleich
699*b1cdbd2cSJim Jagielski                                     if( ( sal_uInt8 ) nMuster != nAkt )
700*b1cdbd2cSJim Jagielski                                         bSync = sal_False;
701*b1cdbd2cSJim Jagielski                                 }
702*b1cdbd2cSJim Jagielski                                 else if( nMuster & M_DC )
703*b1cdbd2cSJim Jagielski                                 { //                                             don't care
704*b1cdbd2cSJim Jagielski                                 }
705*b1cdbd2cSJim Jagielski                                 else if( nMuster & M_ALT(0) )
706*b1cdbd2cSJim Jagielski                                 { //                                      alternative Bytes
707*b1cdbd2cSJim Jagielski                                     sal_uInt8 nAnzAlt = ( sal_uInt8 ) nMuster;
708*b1cdbd2cSJim Jagielski                                     bSync = sal_False;          // zunaechst unsynchron
709*b1cdbd2cSJim Jagielski                                     while( nAnzAlt > 0 )
710*b1cdbd2cSJim Jagielski                                     {
711*b1cdbd2cSJim Jagielski                                         pSearch++;
712*b1cdbd2cSJim Jagielski                                         if( ( sal_uInt8 ) *pSearch == nAkt )
713*b1cdbd2cSJim Jagielski                                             bSync = sal_True;   // jetzt erst Synchronisierung
714*b1cdbd2cSJim Jagielski                                         nAnzAlt--;
715*b1cdbd2cSJim Jagielski                                     }
716*b1cdbd2cSJim Jagielski                                 }
717*b1cdbd2cSJim Jagielski                                 else if( nMuster & M_ENDE )
718*b1cdbd2cSJim Jagielski                                 { //                                        Format detected
719*b1cdbd2cSJim Jagielski                                     if ( pFilterName[nFilter] == pFilterExcel4 && pPreselectedFilter &&
720*b1cdbd2cSJim Jagielski                                         ( (pPreselectedFilter)->GetFilterName().EqualsAscii(pFilterEx4Temp) || pPreselectedFilter->GetTypeName().EqualsAscii("calc_MS_Excel_40") ) )
721*b1cdbd2cSJim Jagielski                                     {
722*b1cdbd2cSJim Jagielski                                         //  Excel 4 erkannt, Excel 4 Vorlage eingestellt -> auch gut
723*b1cdbd2cSJim Jagielski                                         // oder Excel 4 Filter anderer Applikation (simulated type detection!)
724*b1cdbd2cSJim Jagielski                                     }
725*b1cdbd2cSJim Jagielski                                     else
726*b1cdbd2cSJim Jagielski                                     {   // gefundenen Filter einstellen
727*b1cdbd2cSJim Jagielski                                         pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterName[ nFilter ]) );
728*b1cdbd2cSJim Jagielski                                     }
729*b1cdbd2cSJim Jagielski                                     bSync = sal_False;              // leave inner loop
730*b1cdbd2cSJim Jagielski                                     nFilter = nFilterCount;     // leave outer loop
731*b1cdbd2cSJim Jagielski                                 }
732*b1cdbd2cSJim Jagielski                                 else
733*b1cdbd2cSJim Jagielski                                 { //                                         Tabellenfehler
734*b1cdbd2cSJim Jagielski                                     DBG_ERROR( "-ScApplication::DetectFilter(): Fehler in Mustertabelle");
735*b1cdbd2cSJim Jagielski                                 }
736*b1cdbd2cSJim Jagielski 
737*b1cdbd2cSJim Jagielski                                 pSearch++;
738*b1cdbd2cSJim Jagielski                                 rStr >> nAkt;
739*b1cdbd2cSJim Jagielski                             }
740*b1cdbd2cSJim Jagielski                         }
741*b1cdbd2cSJim Jagielski 
742*b1cdbd2cSJim Jagielski                         if ( pPreselectedFilter && !pFilter )
743*b1cdbd2cSJim Jagielski                         {
744*b1cdbd2cSJim Jagielski                             // further checks for filters only if they are preselected: ASCII, HTML, RTF, DBase
745*b1cdbd2cSJim Jagielski                             // without the preselection other filters (Writer) take precedence
746*b1cdbd2cSJim Jagielski                             // DBase can't be detected reliably, so it also needs preselection
747*b1cdbd2cSJim Jagielski                             bool bMaybeText = lcl_MayBeAscii( rStr );
748*b1cdbd2cSJim Jagielski                             if ( pPreselectedFilter->GetFilterName().EqualsAscii(pFilterAscii) && bMaybeText )
749*b1cdbd2cSJim Jagielski                             {
750*b1cdbd2cSJim Jagielski                                 // Text filter is accepted if preselected
751*b1cdbd2cSJim Jagielski                                 pFilter = pPreselectedFilter;
752*b1cdbd2cSJim Jagielski                             }
753*b1cdbd2cSJim Jagielski                             else
754*b1cdbd2cSJim Jagielski                             {
755*b1cdbd2cSJim Jagielski                                 // get file header
756*b1cdbd2cSJim Jagielski                                 rStr.Seek( 0 );
757*b1cdbd2cSJim Jagielski                                 const int nTrySize = 80;
758*b1cdbd2cSJim Jagielski                                 ByteString aHeader;
759*b1cdbd2cSJim Jagielski                                 for ( int j = 0; j < nTrySize && !rStr.IsEof(); j++ )
760*b1cdbd2cSJim Jagielski                                 {
761*b1cdbd2cSJim Jagielski                                     sal_Char c;
762*b1cdbd2cSJim Jagielski                                     rStr >> c;
763*b1cdbd2cSJim Jagielski                                     aHeader += c;
764*b1cdbd2cSJim Jagielski                                 }
765*b1cdbd2cSJim Jagielski                                 aHeader += '\0';
766*b1cdbd2cSJim Jagielski 
767*b1cdbd2cSJim Jagielski                                 if ( HTMLParser::IsHTMLFormat( aHeader.GetBuffer() ) )
768*b1cdbd2cSJim Jagielski                                 {
769*b1cdbd2cSJim Jagielski                                     // test for HTML
770*b1cdbd2cSJim Jagielski                                     if ( pPreselectedFilter->GetName().EqualsAscii(pFilterHtml) )
771*b1cdbd2cSJim Jagielski                                     {
772*b1cdbd2cSJim Jagielski                                         pFilter = pPreselectedFilter;
773*b1cdbd2cSJim Jagielski                                     }
774*b1cdbd2cSJim Jagielski                                     else
775*b1cdbd2cSJim Jagielski                                     {
776*b1cdbd2cSJim Jagielski                                         pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterHtmlWeb) );
777*b1cdbd2cSJim Jagielski                                         if ( bIsXLS )
778*b1cdbd2cSJim Jagielski                                             bFakeXLS = true;
779*b1cdbd2cSJim Jagielski                                     }
780*b1cdbd2cSJim Jagielski                                 }
781*b1cdbd2cSJim Jagielski                                 else if ( bIsXLS && bMaybeText )
782*b1cdbd2cSJim Jagielski                                 {
783*b1cdbd2cSJim Jagielski                                     // Detect Excel 2003 XML here only if XLS was preselected.
784*b1cdbd2cSJim Jagielski                                     // The configured detection for Excel 2003 XML is still in XMLFilterDetect.
785*b1cdbd2cSJim Jagielski                                     pFilter = lcl_DetectExcelXML( rStr, aMatcher );
786*b1cdbd2cSJim Jagielski                                     if (!pFilter)
787*b1cdbd2cSJim Jagielski                                         pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterAscii) );
788*b1cdbd2cSJim Jagielski                                     bFakeXLS = true;
789*b1cdbd2cSJim Jagielski                                 }
790*b1cdbd2cSJim Jagielski                                 else if ( aHeader.CompareTo( "{\\rtf", 5 ) == COMPARE_EQUAL )
791*b1cdbd2cSJim Jagielski                                 {
792*b1cdbd2cSJim Jagielski                                     // test for RTF
793*b1cdbd2cSJim Jagielski                                     pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterRtf) );
794*b1cdbd2cSJim Jagielski                                 }
795*b1cdbd2cSJim Jagielski                                 else if ( pPreselectedFilter->GetName().EqualsAscii(pFilterDBase) && lcl_MayBeDBase( rStr ) )
796*b1cdbd2cSJim Jagielski                                     pFilter = pPreselectedFilter;
797*b1cdbd2cSJim Jagielski                             }
798*b1cdbd2cSJim Jagielski                         }
799*b1cdbd2cSJim Jagielski                     }
800*b1cdbd2cSJim Jagielski 				}
801*b1cdbd2cSJim Jagielski 			}
802*b1cdbd2cSJim Jagielski 		}
803*b1cdbd2cSJim Jagielski 	}
804*b1cdbd2cSJim Jagielski 
805*b1cdbd2cSJim Jagielski     if ( nIndexOfInputStream == -1 && xStream.is() )
806*b1cdbd2cSJim Jagielski     {
807*b1cdbd2cSJim Jagielski         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
808*b1cdbd2cSJim Jagielski         lDescriptor.realloc( nPropertyCount + 1 );
809*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("InputStream");
810*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Value <<= xStream;
811*b1cdbd2cSJim Jagielski         nPropertyCount++;
812*b1cdbd2cSJim Jagielski     }
813*b1cdbd2cSJim Jagielski 
814*b1cdbd2cSJim Jagielski     if ( nIndexOfContent == -1 && xContent.is() )
815*b1cdbd2cSJim Jagielski     {
816*b1cdbd2cSJim Jagielski         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
817*b1cdbd2cSJim Jagielski         lDescriptor.realloc( nPropertyCount + 1 );
818*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("UCBContent");
819*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Value <<= xContent;
820*b1cdbd2cSJim Jagielski         nPropertyCount++;
821*b1cdbd2cSJim Jagielski     }
822*b1cdbd2cSJim Jagielski 
823*b1cdbd2cSJim Jagielski     if ( bReadOnly != bWasReadOnly )
824*b1cdbd2cSJim Jagielski     {
825*b1cdbd2cSJim Jagielski         if ( nIndexOfReadOnlyFlag == -1 )
826*b1cdbd2cSJim Jagielski         {
827*b1cdbd2cSJim Jagielski             lDescriptor.realloc( nPropertyCount + 1 );
828*b1cdbd2cSJim Jagielski             lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("ReadOnly");
829*b1cdbd2cSJim Jagielski             lDescriptor[nPropertyCount].Value <<= bReadOnly;
830*b1cdbd2cSJim Jagielski             nPropertyCount++;
831*b1cdbd2cSJim Jagielski         }
832*b1cdbd2cSJim Jagielski         else
833*b1cdbd2cSJim Jagielski             lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
834*b1cdbd2cSJim Jagielski     }
835*b1cdbd2cSJim Jagielski 
836*b1cdbd2cSJim Jagielski 	if ( !bRepairPackage && bRepairAllowed )
837*b1cdbd2cSJim Jagielski 	{
838*b1cdbd2cSJim Jagielski         lDescriptor.realloc( nPropertyCount + 1 );
839*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("RepairPackage");
840*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
841*b1cdbd2cSJim Jagielski         nPropertyCount++;
842*b1cdbd2cSJim Jagielski 
843*b1cdbd2cSJim Jagielski 		bOpenAsTemplate = sal_True;
844*b1cdbd2cSJim Jagielski 
845*b1cdbd2cSJim Jagielski 		// TODO/LATER: set progress bar that should be used
846*b1cdbd2cSJim Jagielski 	}
847*b1cdbd2cSJim Jagielski 
848*b1cdbd2cSJim Jagielski 	if ( bOpenAsTemplate )
849*b1cdbd2cSJim Jagielski 	{
850*b1cdbd2cSJim Jagielski 		if ( nIndexOfTemplateFlag == -1 )
851*b1cdbd2cSJim Jagielski 		{
852*b1cdbd2cSJim Jagielski         	lDescriptor.realloc( nPropertyCount + 1 );
853*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("AsTemplate");
854*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
855*b1cdbd2cSJim Jagielski         	nPropertyCount++;
856*b1cdbd2cSJim Jagielski 		}
857*b1cdbd2cSJim Jagielski 		else
858*b1cdbd2cSJim Jagielski         	lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
859*b1cdbd2cSJim Jagielski 	}
860*b1cdbd2cSJim Jagielski 
861*b1cdbd2cSJim Jagielski 	if ( aDocumentTitle.getLength() )
862*b1cdbd2cSJim Jagielski 	{
863*b1cdbd2cSJim Jagielski 		// the title was set here
864*b1cdbd2cSJim Jagielski 		if ( nIndexOfDocumentTitle == -1 )
865*b1cdbd2cSJim Jagielski 		{
866*b1cdbd2cSJim Jagielski         	lDescriptor.realloc( nPropertyCount + 1 );
867*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("DocumentTitle");
868*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
869*b1cdbd2cSJim Jagielski         	nPropertyCount++;
870*b1cdbd2cSJim Jagielski 		}
871*b1cdbd2cSJim Jagielski 		else
872*b1cdbd2cSJim Jagielski         	lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
873*b1cdbd2cSJim Jagielski 	}
874*b1cdbd2cSJim Jagielski 
875*b1cdbd2cSJim Jagielski     if ( bFakeXLS )
876*b1cdbd2cSJim Jagielski     {
877*b1cdbd2cSJim Jagielski         if ( nIndexOfFilterName == -1 )
878*b1cdbd2cSJim Jagielski         {
879*b1cdbd2cSJim Jagielski             lDescriptor.realloc( nPropertyCount + 1 );
880*b1cdbd2cSJim Jagielski             lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("FilterName");
881*b1cdbd2cSJim Jagielski             lDescriptor[nPropertyCount].Value <<= rtl::OUString(pFilter->GetName());
882*b1cdbd2cSJim Jagielski             nPropertyCount++;
883*b1cdbd2cSJim Jagielski         }
884*b1cdbd2cSJim Jagielski         else
885*b1cdbd2cSJim Jagielski             lDescriptor[nIndexOfFilterName].Value <<= rtl::OUString(pFilter->GetName());
886*b1cdbd2cSJim Jagielski     }
887*b1cdbd2cSJim Jagielski 
888*b1cdbd2cSJim Jagielski     if ( pFilter )
889*b1cdbd2cSJim Jagielski         aTypeName = pFilter->GetTypeName();
890*b1cdbd2cSJim Jagielski     else
891*b1cdbd2cSJim Jagielski         aTypeName.Erase();
892*b1cdbd2cSJim Jagielski     return aTypeName;
893*b1cdbd2cSJim Jagielski }
894*b1cdbd2cSJim Jagielski 
SFX_IMPL_SINGLEFACTORY(ScFilterDetect)895*b1cdbd2cSJim Jagielski SFX_IMPL_SINGLEFACTORY( ScFilterDetect )
896*b1cdbd2cSJim Jagielski 
897*b1cdbd2cSJim Jagielski /* XServiceInfo */
898*b1cdbd2cSJim Jagielski UNOOUSTRING SAL_CALL ScFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
899*b1cdbd2cSJim Jagielski {
900*b1cdbd2cSJim Jagielski     return impl_getStaticImplementationName();
901*b1cdbd2cSJim Jagielski }
902*b1cdbd2cSJim Jagielski                                                                                                                                 \
903*b1cdbd2cSJim Jagielski /* XServiceInfo */
supportsService(const UNOOUSTRING & sServiceName)904*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL ScFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION )
905*b1cdbd2cSJim Jagielski {
906*b1cdbd2cSJim Jagielski     UNOSEQUENCE< UNOOUSTRING >  seqServiceNames(getSupportedServiceNames());
907*b1cdbd2cSJim Jagielski     const UNOOUSTRING*          pArray          =   seqServiceNames.getConstArray();
908*b1cdbd2cSJim Jagielski     for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
909*b1cdbd2cSJim Jagielski     {
910*b1cdbd2cSJim Jagielski         if ( pArray[nCounter] == sServiceName )
911*b1cdbd2cSJim Jagielski         {
912*b1cdbd2cSJim Jagielski             return sal_True ;
913*b1cdbd2cSJim Jagielski         }
914*b1cdbd2cSJim Jagielski     }
915*b1cdbd2cSJim Jagielski     return sal_False ;
916*b1cdbd2cSJim Jagielski }
917*b1cdbd2cSJim Jagielski 
918*b1cdbd2cSJim Jagielski /* XServiceInfo */
getSupportedServiceNames()919*b1cdbd2cSJim Jagielski UNOSEQUENCE< UNOOUSTRING > SAL_CALL ScFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
920*b1cdbd2cSJim Jagielski {
921*b1cdbd2cSJim Jagielski     return impl_getStaticSupportedServiceNames();
922*b1cdbd2cSJim Jagielski }
923*b1cdbd2cSJim Jagielski 
924*b1cdbd2cSJim Jagielski /* Helper for XServiceInfo */
impl_getStaticSupportedServiceNames()925*b1cdbd2cSJim Jagielski UNOSEQUENCE< UNOOUSTRING > ScFilterDetect::impl_getStaticSupportedServiceNames()
926*b1cdbd2cSJim Jagielski {
927*b1cdbd2cSJim Jagielski     UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() );
928*b1cdbd2cSJim Jagielski     UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 1 );
929*b1cdbd2cSJim Jagielski     seqServiceNames.getArray() [0] = UNOOUSTRING::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection"  );
930*b1cdbd2cSJim Jagielski     return seqServiceNames ;
931*b1cdbd2cSJim Jagielski }
932*b1cdbd2cSJim Jagielski 
933*b1cdbd2cSJim Jagielski /* Helper for XServiceInfo */
impl_getStaticImplementationName()934*b1cdbd2cSJim Jagielski UNOOUSTRING ScFilterDetect::impl_getStaticImplementationName()
935*b1cdbd2cSJim Jagielski {
936*b1cdbd2cSJim Jagielski     return UNOOUSTRING::createFromAscii( "com.sun.star.comp.calc.FormatDetector" );
937*b1cdbd2cSJim Jagielski }
938*b1cdbd2cSJim Jagielski 
939*b1cdbd2cSJim Jagielski /* Helper for registry */
impl_createInstance(const UNOREFERENCE<UNOXMULTISERVICEFACTORY> & xServiceManager)940*b1cdbd2cSJim Jagielski UNOREFERENCE< UNOXINTERFACE > SAL_CALL ScFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
941*b1cdbd2cSJim Jagielski {
942*b1cdbd2cSJim Jagielski     return UNOREFERENCE< UNOXINTERFACE >( *new ScFilterDetect( xServiceManager ) );
943*b1cdbd2cSJim Jagielski }
944*b1cdbd2cSJim Jagielski 
945