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