LCOV - code coverage report
Current view: top level - libreoffice/sc/source/ui/unoobj - scdetect.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 345 0.0 %
Date: 2012-12-27 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10