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