LCOV - code coverage report
Current view: top level - sc/source/ui/unoobj - scdetect.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 106 263 40.3 %
Date: 2014-04-11 Functions: 7 12 58.3 %
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 <cppuhelper/supportsservice.hxx>
      34             : #include <com/sun/star/container/XNameAccess.hpp>
      35             : #include <com/sun/star/io/XInputStream.hpp>
      36             : #include <com/sun/star/task/XInteractionHandler.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 <svl/itemset.hxx>
      48             : #include <vcl/window.hxx>
      49             : #include <svl/eitem.hxx>
      50             : #include <svl/stritem.hxx>
      51             : #include <tools/urlobj.hxx>
      52             : #include <osl/mutex.hxx>
      53             : #include <svtools/sfxecode.hxx>
      54             : #include <svtools/ehdl.hxx>
      55             : #include <sot/storinfo.hxx>
      56             : #include <vcl/svapp.hxx>
      57             : #include <sfx2/sfxsids.hrc>
      58             : #include <sfx2/request.hxx>
      59             : #include <sfx2/docfile.hxx>
      60             : #include <sfx2/docfilt.hxx>
      61             : #include <sfx2/fcontnr.hxx>
      62             : #include <sfx2/app.hxx>
      63             : #include <sfx2/brokenpackageint.hxx>
      64             : 
      65             : using namespace ::com::sun::star;
      66             : using namespace ::com::sun::star::uno;
      67             : using namespace ::com::sun::star::io;
      68             : using namespace ::com::sun::star::frame;
      69             : using namespace ::com::sun::star::task;
      70             : using namespace ::com::sun::star::beans;
      71             : using namespace ::com::sun::star::lang;
      72             : using namespace ::com::sun::star::ucb;
      73             : 
      74             : namespace {
      75             : 
      76             : const sal_Char pFilterLotus[]        = "Lotus";
      77             : const sal_Char pFilterQPro6[]        = "Quattro Pro 6.0";
      78             : const sal_Char pFilterDBase[]        = "dBase";
      79             : const sal_Char pFilterDif[]      = "DIF";
      80             : const sal_Char pFilterSylk[]     = "SYLK";
      81             : 
      82             : // Tabelle mit Suchmustern
      83             : // Bedeutung der Sequenzen
      84             : // 0x00??: genau Byte 0x?? muss an dieser Stelle stehen
      85             : // 0x0100: ein Byte ueberlesen (don't care)
      86             : // 0x02nn: ein Byte aus 0xnn Alternativen folgt
      87             : // 0x8000: Erkennung abgeschlossen
      88             : 
      89             : 
      90             : #define M_DC        0x0100
      91             : #define M_ALT(ANZ)  (0x0200+(ANZ))
      92             : #define M_ENDE      0x8000
      93             : 
      94             : const sal_uInt16 pLotus[] =      // Lotus 1/1A/2
      95             :     { 0x0000, 0x0000, 0x0002, 0x0000,
      96             :     M_ALT(2), 0x0004, 0x0006,
      97             :     0x0004, M_ENDE };
      98             : 
      99             : const sal_uInt16 pLotusNew[] =   // Lotus >= 9.7
     100             :     { 0x0000, 0x0000, M_DC, 0x0000,     // Rec# + Len (0x1a)
     101             :       M_ALT(3), 0x0003, 0x0004, 0x0005, // File Revision Code 97->ME
     102             :       0x0010, 0x0004, 0x0000, 0x0000,
     103             :       M_ENDE };
     104             : 
     105             : const sal_uInt16 pLotus2[] =     // Lotus >3
     106             :     { 0x0000, 0x0000, 0x001A, 0x0000,   // Rec# + Len (26)
     107             :     M_ALT(2), 0x0000, 0x0002,         // File Revision Code
     108             :     0x0010,
     109             :     0x0004, 0x0000,                   // File Revision Subcode
     110             :     M_ENDE };
     111             : 
     112             : const sal_uInt16 pQPro[] =
     113             :        { 0x0000, 0x0000, 0x0002, 0x0000,
     114             :          M_ALT(4), 0x0001, 0x0002, // WB1, WB2
     115             :          0x0006, 0x0007,           // QPro 6/7 (?)
     116             :          0x0010,
     117             :          M_ENDE };
     118             : 
     119             : const sal_uInt16 pDIF1[] =       // DIF mit CR-LF
     120             :     {
     121             :     'T', 'A', 'B', 'L', 'E',
     122             :     M_DC, M_DC,
     123             :     '0', ',', '1',
     124             :     M_DC, M_DC,
     125             :     '\"',
     126             :     M_ENDE };
     127             : 
     128             : const sal_uInt16 pDIF2[] =       // DIF mit CR oder LF
     129             :     {
     130             :     'T', 'A', 'B', 'L', 'E',
     131             :     M_DC,
     132             :     '0', ',', '1',
     133             :     M_DC,
     134             :     '\"',
     135             :     M_ENDE };
     136             : 
     137             : const sal_uInt16 pSylk[] =       // Sylk
     138             :     {
     139             :     'I', 'D', ';',
     140             :     M_ALT(3), 'P', 'N', 'E',        // 'P' plus undocumented Excel extensions 'N' and 'E'
     141             :     M_ENDE };
     142             : 
     143           0 : bool detectThisFormat(SvStream& rStr, const sal_uInt16* pSearch)
     144             : {
     145             :     sal_uInt8 nByte;
     146           0 :     rStr.Seek( 0 ); // am Anfang war alles Uebel...
     147           0 :     rStr.ReadUChar( nByte );
     148           0 :     bool bSync = true;
     149           0 :     while( !rStr.IsEof() && bSync )
     150             :     {
     151           0 :         sal_uInt16 nMuster = *pSearch;
     152             : 
     153           0 :         if( nMuster < 0x0100 )
     154             :         { //                                direkter Byte-Vergleich
     155           0 :             if( ( sal_uInt8 ) nMuster != nByte )
     156           0 :                 bSync = false;
     157             :         }
     158           0 :         else if( nMuster & M_DC )
     159             :         { //                                             don't care
     160             :         }
     161           0 :         else if( nMuster & M_ALT(0) )
     162             :         { //                                      alternative Bytes
     163           0 :             sal_uInt8 nAnzAlt = ( sal_uInt8 ) nMuster;
     164           0 :             bSync = false;          // zunaechst unsynchron
     165           0 :             while( nAnzAlt > 0 )
     166             :             {
     167           0 :                 pSearch++;
     168           0 :                 if( ( sal_uInt8 ) *pSearch == nByte )
     169           0 :                     bSync = true;   // jetzt erst Synchronisierung
     170           0 :                 nAnzAlt--;
     171             :             }
     172             :         }
     173           0 :         else if( nMuster & M_ENDE )
     174             :         { //                                        Format detected
     175           0 :             return true;
     176             :         }
     177             : 
     178           0 :         pSearch++;
     179           0 :         rStr.ReadUChar( nByte );
     180             :     }
     181             : 
     182           0 :     return false;
     183             : }
     184             : 
     185             : }
     186             : 
     187          40 : ScFilterDetect::ScFilterDetect( const uno::Reference<uno::XComponentContext>& /*xContext*/ )
     188             : {
     189          40 : }
     190             : 
     191          80 : ScFilterDetect::~ScFilterDetect()
     192             : {
     193          80 : }
     194             : 
     195             : #if 0
     196             : // This method is no longer used, but I do want to keep this for now to see
     197             : // if we could transfer this check to the now centralized ascii detection
     198             : // code in the filter module.
     199             : static sal_Bool lcl_MayBeAscii( SvStream& rStream )
     200             : {
     201             :     // ASCII/CSV is considered possible if there are no null bytes, or a Byte
     202             :     // Order Mark is present, or if, for Unicode UCS2/UTF-16, all null bytes
     203             :     // are on either even or uneven byte positions.
     204             : 
     205             :     rStream.Seek(STREAM_SEEK_TO_BEGIN);
     206             : 
     207             :     const size_t nBufSize = 2048;
     208             :     sal_uInt16 aBuffer[ nBufSize ];
     209             :     sal_uInt8* pByte = reinterpret_cast<sal_uInt8*>(aBuffer);
     210             :     sal_uLong nBytesRead = rStream.Read( pByte, nBufSize*2);
     211             : 
     212             :     if ( nBytesRead >= 2 && (aBuffer[0] == 0xfffe || aBuffer[0] == 0xfeff) )
     213             :     {
     214             :         // Unicode BOM file may contain null bytes.
     215             :         return sal_True;
     216             :     }
     217             : 
     218             :     const sal_uInt16* p = aBuffer;
     219             :     sal_uInt16 nMask = 0xffff;
     220             :     nBytesRead /= 2;
     221             :     while( nBytesRead-- && nMask )
     222             :     {
     223             :         sal_uInt16 nVal = *p++ & nMask;
     224             :         if (!(nVal & 0x00ff))
     225             :             nMask &= 0xff00;
     226             :         if (!(nVal & 0xff00))
     227             :             nMask &= 0x00ff;
     228             :     }
     229             : 
     230             :     return nMask != 0;
     231             : }
     232             : #endif
     233             : 
     234           0 : static sal_Bool lcl_MayBeDBase( SvStream& rStream )
     235             : {
     236             :     // Look for dbf marker, see connectivity/source/inc/dbase/DTable.hxx
     237             :     // DBFType for values.
     238             :     const sal_uInt8 nValidMarks[] = {
     239           0 :         0x03, 0x04, 0x05, 0x30, 0x43, 0xB3, 0x83, 0x8b, 0x8e, 0xf5 };
     240             :     sal_uInt8 nMark;
     241           0 :     rStream.Seek(STREAM_SEEK_TO_BEGIN);
     242           0 :     rStream.ReadUChar( nMark );
     243           0 :     bool bValidMark = false;
     244           0 :     for (size_t i=0; i < sizeof(nValidMarks)/sizeof(nValidMarks[0]) && !bValidMark; ++i)
     245             :     {
     246           0 :         if (nValidMarks[i] == nMark)
     247           0 :             bValidMark = true;
     248             :     }
     249           0 :     if ( !bValidMark )
     250           0 :         return false;
     251             : 
     252           0 :     const size_t nHeaderBlockSize = 32;
     253             :     // Empty dbf is >= 32*2+1 bytes in size.
     254           0 :     const size_t nEmptyDbf = nHeaderBlockSize * 2 + 1;
     255             : 
     256           0 :     rStream.Seek(STREAM_SEEK_TO_END);
     257           0 :     sal_uLong nSize = rStream.Tell();
     258           0 :     if ( nSize < nEmptyDbf )
     259           0 :         return false;
     260             : 
     261             :     // length of header starts at 8
     262           0 :     rStream.Seek(8);
     263             :     sal_uInt16 nHeaderLen;
     264           0 :     rStream.ReadUInt16( nHeaderLen );
     265             : 
     266           0 :     if ( nHeaderLen < nEmptyDbf || nSize < nHeaderLen )
     267           0 :         return false;
     268             : 
     269             :     // Last byte of header must be 0x0d, this is how it's specified.
     270             :     // #i9581#,#i26407# but some applications don't follow the specification
     271             :     // and pad the header with one byte 0x00 to reach an
     272             :     // even boundary. Some (#i88577# ) even pad more or pad using a 0x1a ^Z
     273             :     // control character (#i8857#). This results in:
     274             :     // Last byte of header must be 0x0d on 32 bytes boundary.
     275           0 :     sal_uInt16 nBlocks = (nHeaderLen - 1) / nHeaderBlockSize;
     276           0 :     sal_uInt8 nEndFlag = 0;
     277           0 :     while ( nBlocks > 1 && nEndFlag != 0x0d ) {
     278           0 :         rStream.Seek( nBlocks-- * nHeaderBlockSize );
     279           0 :         rStream.ReadUChar( nEndFlag );
     280             :     }
     281             : 
     282           0 :     return ( 0x0d == nEndFlag );
     283             : }
     284             : 
     285          40 : OUString SAL_CALL ScFilterDetect::detect( uno::Sequence<beans::PropertyValue>& lDescriptor )
     286             :     throw( uno::RuntimeException, std::exception )
     287             : {
     288          40 :     uno::Reference< XInputStream > xStream;
     289          80 :     uno::Reference< XContent > xContent;
     290          80 :     uno::Reference< XInteractionHandler > xInteraction;
     291          80 :     OUString aURL;
     292          80 :     OUString sTemp;
     293          80 :     OUString aTypeName;            // a name describing the type (from MediaDescriptor, usually from flat detection)
     294          80 :     OUString aPreselectedFilterName;      // a name describing the filter to use (from MediaDescriptor, usually from UI action)
     295             : 
     296          80 :     OUString aDocumentTitle; // interesting only if set in this method
     297             : 
     298             :     // opening as template is done when a parameter tells to do so and a template filter can be detected
     299             :     // (otherwise no valid filter would be found) or if the detected filter is a template filter and
     300             :     // there is no parameter that forbids to open as template
     301          40 :     sal_Bool bOpenAsTemplate = false;
     302          40 :     sal_Bool bWasReadOnly = false, bReadOnly = false;
     303             : 
     304          40 :     sal_Bool bRepairPackage = false;
     305          40 :     sal_Bool bRepairAllowed = false;
     306          40 :     bool bDeepDetection = false;
     307             : 
     308             :     // now some parameters that can already be in the array, but may be overwritten or new inserted here
     309             :     // remember their indices in the case new values must be added to the array
     310          40 :     sal_Int32 nPropertyCount = lDescriptor.getLength();
     311          40 :     sal_Int32 nIndexOfFilterName = -1;
     312          40 :     sal_Int32 nIndexOfInputStream = -1;
     313          40 :     sal_Int32 nIndexOfContent = -1;
     314          40 :     sal_Int32 nIndexOfReadOnlyFlag = -1;
     315          40 :     sal_Int32 nIndexOfTemplateFlag = -1;
     316          40 :     sal_Int32 nIndexOfDocumentTitle = -1;
     317             : 
     318         325 :     for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
     319             :     {
     320             :         // extract properties
     321         285 :         if ( lDescriptor[nProperty].Name == "URL" )
     322             :         {
     323          40 :             lDescriptor[nProperty].Value >>= sTemp;
     324          40 :             aURL = sTemp;
     325             :         }
     326         245 :         else if( aURL.isEmpty() && lDescriptor[nProperty].Name == "FileName" )
     327             :         {
     328           0 :             lDescriptor[nProperty].Value >>= sTemp;
     329           0 :             aURL = sTemp;
     330             :         }
     331         245 :         else if ( lDescriptor[nProperty].Name == "TypeName" )
     332             :         {
     333          40 :             lDescriptor[nProperty].Value >>= sTemp;
     334          40 :             aTypeName = sTemp;
     335             :         }
     336         205 :         else if ( lDescriptor[nProperty].Name == "FilterName" )
     337             :         {
     338           0 :             lDescriptor[nProperty].Value >>= sTemp;
     339           0 :             aPreselectedFilterName = sTemp;
     340             : 
     341             :             // if the preselected filter name is not correct, it must be erased after detection
     342             :             // remember index of property to get access to it later
     343           0 :             nIndexOfFilterName = nProperty;
     344             :         }
     345         205 :         else if ( lDescriptor[nProperty].Name == "InputStream" )
     346          40 :             nIndexOfInputStream = nProperty;
     347         165 :         else if ( lDescriptor[nProperty].Name == "ReadOnly" )
     348           0 :             nIndexOfReadOnlyFlag = nProperty;
     349         165 :         else if ( lDescriptor[nProperty].Name == "UCBContent" )
     350          35 :             nIndexOfContent = nProperty;
     351         130 :         else if ( lDescriptor[nProperty].Name == "AsTemplate" )
     352             :         {
     353           0 :             lDescriptor[nProperty].Value >>= bOpenAsTemplate;
     354           0 :             nIndexOfTemplateFlag = nProperty;
     355             :         }
     356         130 :         else if ( lDescriptor[nProperty].Name == "InteractionHandler" )
     357          40 :             lDescriptor[nProperty].Value >>= xInteraction;
     358          90 :         else if ( lDescriptor[nProperty].Name == "RepairPackage" )
     359           0 :             lDescriptor[nProperty].Value >>= bRepairPackage;
     360          90 :         else if ( lDescriptor[nProperty].Name == "DocumentTitle" )
     361           0 :             nIndexOfDocumentTitle = nProperty;
     362          90 :         else if (lDescriptor[nProperty].Name == "DeepDetection")
     363           0 :             bDeepDetection = lDescriptor[nProperty].Value.get<sal_Bool>();
     364             :     }
     365             : 
     366             :     // can't check the type for external filters, so set the "dont" flag accordingly
     367          80 :     SolarMutexGuard aGuard;
     368             :     //SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED;
     369             : 
     370          40 :     SfxAllItemSet *pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
     371          40 :     TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
     372          40 :     SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, false );
     373             : 
     374          40 :     bWasReadOnly = pItem && pItem->GetValue();
     375             : 
     376          40 :     const SfxFilter* pFilter = 0;
     377          80 :     OUString aPrefix = "private:factory/";
     378          40 :     if( aURL.startsWith( aPrefix ) )
     379             :     {
     380           0 :         OUString aPattern = aPrefix + "scalc";
     381           0 :         if ( aURL.startsWith( aPattern ) )
     382           0 :             pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
     383             :     }
     384             :     else
     385             :     {
     386             :         // container for Calc filters
     387          40 :         SfxFilterMatcher aMatcher("scalc");
     388          40 :         if ( !aPreselectedFilterName.isEmpty() )
     389           0 :             pFilter = SfxFilter::GetFilterByName( aPreselectedFilterName );
     390          40 :         else if( !aTypeName.isEmpty() )
     391          40 :             pFilter = aMatcher.GetFilter4EA( aTypeName );
     392             : 
     393             :         // ctor of SfxMedium uses owner transition of ItemSet
     394          76 :         SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, NULL, pSet );
     395          40 :         aMedium.UseInteractionHandler( true );
     396             : 
     397          40 :         sal_Bool bIsStorage = aMedium.IsStorage();
     398          40 :         if ( aMedium.GetErrorCode() == ERRCODE_NONE )
     399             :         {
     400             :             // remember input stream and content and put them into the descriptor later
     401             :             // should be done here since later the medium can switch to a version
     402          40 :             xStream.set(aMedium.GetInputStream());
     403          40 :             xContent.set(aMedium.GetContent());
     404          40 :             bReadOnly = aMedium.IsReadOnly();
     405             : 
     406             :             // maybe that IsStorage() already created an error!
     407          40 :             if ( bIsStorage )
     408             :             {
     409          36 :                 uno::Reference < embed::XStorage > xStorage(aMedium.GetStorage( false ));
     410          36 :                 if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
     411             :                 {
     412             :                     // error during storage creation means _here_ that the medium
     413             :                     // is broken, but we can not handle it in medium since unpossibility
     414             :                     // to create a storage does not _always_ means that the medium is broken
     415           0 :                     aMedium.SetError(aMedium.GetLastStorageCreationState(), OUString(OSL_LOG_PREFIX));
     416           0 :                     if ( xInteraction.is() )
     417             :                     {
     418           0 :                         OUString empty;
     419             :                         try
     420             :                         {
     421             :                             InteractiveAppException xException( empty,
     422             :                                                             uno::Reference< XInterface >(),
     423             :                                                             InteractionClassification_ERROR,
     424           0 :                                                             aMedium.GetError() );
     425             : 
     426             :                             uno::Reference< XInteractionRequest > xRequest(
     427             :                                 new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
     428           0 :                                                                       ucbhelper::CONTINUATION_APPROVE ) );
     429           0 :                             xInteraction->handle( xRequest );
     430             :                         }
     431           0 :                         catch ( Exception & ) {};
     432             :                     }
     433             :                 }
     434          36 :                 else if ( xStorage.is() )
     435             :                 {
     436             :                     try
     437             :                     {
     438          36 :                         OUString aFilterName;
     439          36 :                         if ( pFilter )
     440          36 :                             aFilterName = pFilter->GetName();
     441          36 :                         aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsOwnTemplateFormat() : false, &aFilterName );
     442             :                     }
     443           0 :                     catch( const lang::WrappedTargetException& aWrap )
     444             :                     {
     445           0 :                         if (!bDeepDetection)
     446             :                             // Bail out early unless it's a deep detection.
     447           0 :                             return OUString();
     448             : 
     449           0 :                         packages::zip::ZipIOException aZipException;
     450             : 
     451             :                         // repairing is done only if this type is requested from outside
     452           0 :                         if ( ( aWrap.TargetException >>= aZipException ) && !aTypeName.isEmpty() )
     453             :                         {
     454           0 :                             if ( xInteraction.is() )
     455             :                             {
     456             :                                 // the package is broken one
     457           0 :                                    aDocumentTitle = aMedium.GetURLObject().getName(
     458             :                                                             INetURLObject::LAST_SEGMENT,
     459             :                                                             true,
     460           0 :                                                             INetURLObject::DECODE_WITH_CHARSET );
     461             : 
     462           0 :                                 if ( !bRepairPackage )
     463             :                                 {
     464             :                                     // ask the user whether he wants to try to repair
     465           0 :                                     RequestPackageReparation aRequest( aDocumentTitle );
     466           0 :                                     xInteraction->handle( aRequest.GetRequest() );
     467           0 :                                     bRepairAllowed = aRequest.isApproved();
     468             :                                 }
     469             : 
     470           0 :                                 if ( !bRepairAllowed )
     471             :                                 {
     472             :                                     // repair either not allowed or not successful
     473           0 :                                     NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
     474           0 :                                     xInteraction->handle( aNotifyRequest.GetRequest() );
     475             :                                 }
     476             :                             }
     477             : 
     478           0 :                             if ( !bRepairAllowed )
     479           0 :                                 aTypeName = "";
     480           0 :                         }
     481           0 :                     }
     482           0 :                     catch( uno::RuntimeException& )
     483             :                     {
     484           0 :                         throw;
     485             :                     }
     486           0 :                     catch( uno::Exception& )
     487             :                     {
     488           0 :                         aTypeName = "";
     489             :                     }
     490             : 
     491          36 :                     if ( !aTypeName.isEmpty() )
     492          36 :                         pFilter = SfxFilterMatcher("scalc").GetFilter4EA( aTypeName );
     493          36 :                 }
     494             :             }
     495             :             else
     496             :             {
     497             :                 // Non-storage format.
     498             : 
     499          11 :                 if (aTypeName == "calc8_template" ||
     500           5 :                     aTypeName == "calc8" ||
     501           7 :                     aTypeName == "calc_StarOffice_XML_Calc" ||
     502           1 :                     aTypeName == "calc_StarOffice_XML_Calc_Template")
     503             :                     // These types require storage.  Bail out.
     504           4 :                     return OUString();
     505             : 
     506           0 :                 SvStream* pStream = aMedium.GetInStream();
     507           0 :                 if (!pStream)
     508             :                     // No stream, no detection.
     509           0 :                     return OUString();
     510             : 
     511           0 :                 pFilter = NULL;
     512             : 
     513           0 :                 const char* pSearchFilterName = NULL;
     514           0 :                 if (aTypeName == "calc_Lotus")
     515             :                 {
     516           0 :                     if (!detectThisFormat(*pStream, pLotus) && !detectThisFormat(*pStream, pLotusNew) && !detectThisFormat(*pStream, pLotus2))
     517           0 :                         return OUString();
     518             : 
     519           0 :                     pSearchFilterName = pFilterLotus;
     520             :                 }
     521           0 :                 else if (aTypeName == "calc_QPro")
     522             :                 {
     523           0 :                     if (!detectThisFormat(*pStream, pQPro))
     524           0 :                         return OUString();
     525             : 
     526           0 :                     pSearchFilterName = pFilterQPro6;
     527             :                 }
     528           0 :                 else if (aTypeName == "calc_SYLK")
     529             :                 {
     530           0 :                     if (!detectThisFormat(*pStream, pSylk))
     531           0 :                         return OUString();
     532             : 
     533           0 :                     pSearchFilterName = pFilterSylk;
     534             :                 }
     535           0 :                 else if (aTypeName == "calc_DIF")
     536             :                 {
     537           0 :                     if (!detectThisFormat(*pStream, pDIF1) && !detectThisFormat(*pStream, pDIF2))
     538           0 :                         return OUString();
     539             : 
     540           0 :                     pSearchFilterName = pFilterDif;
     541             :                 }
     542           0 :                 else if (aTypeName == "calc_dBase")
     543             :                 {
     544           0 :                     if (!lcl_MayBeDBase(*pStream))
     545           0 :                         return OUString();
     546             : 
     547           0 :                     pSearchFilterName = pFilterDBase;
     548             :                 }
     549             : 
     550           0 :                 if (!pSearchFilterName)
     551           0 :                     return OUString();
     552             : 
     553           0 :                 pFilter = aMatcher.GetFilter4FilterName(OUString::createFromAscii(pSearchFilterName));
     554             :             }
     555          36 :         }
     556             :     }
     557             : 
     558          36 :     if ( nIndexOfInputStream == -1 && xStream.is() )
     559             :     {
     560             :         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opened twice
     561           0 :         lDescriptor.realloc( nPropertyCount + 1 );
     562           0 :         lDescriptor[nPropertyCount].Name = "InputStream";
     563           0 :         lDescriptor[nPropertyCount].Value <<= xStream;
     564           0 :         nPropertyCount++;
     565             :     }
     566             : 
     567          36 :     if ( nIndexOfContent == -1 && xContent.is() )
     568             :     {
     569             :         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opened twice
     570           5 :         lDescriptor.realloc( nPropertyCount + 1 );
     571           5 :         lDescriptor[nPropertyCount].Name = "UCBContent";
     572           5 :         lDescriptor[nPropertyCount].Value <<= xContent;
     573           5 :         nPropertyCount++;
     574             :     }
     575             : 
     576          36 :     if ( bReadOnly != bWasReadOnly )
     577             :     {
     578           0 :         if ( nIndexOfReadOnlyFlag == -1 )
     579             :         {
     580           0 :             lDescriptor.realloc( nPropertyCount + 1 );
     581           0 :             lDescriptor[nPropertyCount].Name = "ReadOnly";
     582           0 :             lDescriptor[nPropertyCount].Value <<= bReadOnly;
     583           0 :             nPropertyCount++;
     584             :         }
     585             :         else
     586           0 :             lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
     587             :     }
     588             : 
     589          36 :     if ( !bRepairPackage && bRepairAllowed )
     590             :     {
     591           0 :         lDescriptor.realloc( nPropertyCount + 1 );
     592           0 :         lDescriptor[nPropertyCount].Name = "RepairPackage";
     593           0 :         lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
     594           0 :         nPropertyCount++;
     595             : 
     596           0 :         bOpenAsTemplate = sal_True;
     597             : 
     598             :         // TODO/LATER: set progress bar that should be used
     599             :     }
     600             : 
     601          36 :     if ( bOpenAsTemplate )
     602             :     {
     603           0 :         if ( nIndexOfTemplateFlag == -1 )
     604             :         {
     605           0 :             lDescriptor.realloc( nPropertyCount + 1 );
     606           0 :             lDescriptor[nPropertyCount].Name = "AsTemplate";
     607           0 :             lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
     608           0 :             nPropertyCount++;
     609             :         }
     610             :         else
     611           0 :             lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
     612             :     }
     613             : 
     614          36 :     if ( !aDocumentTitle.isEmpty() )
     615             :     {
     616             :         // the title was set here
     617           0 :         if ( nIndexOfDocumentTitle == -1 )
     618             :         {
     619           0 :             lDescriptor.realloc( nPropertyCount + 1 );
     620           0 :             lDescriptor[nPropertyCount].Name = "DocumentTitle";
     621           0 :             lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
     622           0 :             nPropertyCount++;
     623             :         }
     624             :         else
     625           0 :             lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
     626             :     }
     627             : 
     628          36 :     if (!pFilter)
     629           0 :         return OUString();
     630             : 
     631          36 :     if (nIndexOfFilterName == -1)
     632             :     {
     633          36 :         lDescriptor.realloc(nPropertyCount + 1);
     634          36 :         lDescriptor[nPropertyCount].Name = "FilterName";
     635          36 :         lDescriptor[nPropertyCount].Value <<= pFilter->GetName();
     636          36 :         ++nPropertyCount;
     637             :     }
     638             :     else
     639           0 :         lDescriptor[nIndexOfFilterName].Value <<= pFilter->GetName();
     640             : 
     641          76 :     return aTypeName;
     642             : }
     643             : 
     644           0 : OUString SAL_CALL ScFilterDetect::getImplementationName() throw (uno::RuntimeException, std::exception)
     645             : {
     646           0 :     return impl_getStaticImplementationName();
     647             : }
     648             : 
     649           0 : sal_Bool ScFilterDetect::supportsService( const OUString& sServiceName )
     650             :     throw (uno::RuntimeException, std::exception)
     651             : {
     652           0 :     return cppu::supportsService(this, sServiceName);
     653             : }
     654             : 
     655           0 : com::sun::star::uno::Sequence<OUString> ScFilterDetect::getSupportedServiceNames()
     656             :     throw (uno::RuntimeException, std::exception)
     657             : {
     658           0 :     return impl_getStaticSupportedServiceNames();
     659             : }
     660             : 
     661          17 : uno::Sequence<OUString> ScFilterDetect::impl_getStaticSupportedServiceNames()
     662             : {
     663          17 :     uno::Sequence<OUString> seqServiceNames(1);
     664          17 :     seqServiceNames.getArray()[0] = "com.sun.star.frame.ExtendedTypeDetection";
     665          17 :     return seqServiceNames;
     666             : }
     667             : 
     668          20 : OUString ScFilterDetect::impl_getStaticImplementationName()
     669             : {
     670          20 :     return OUString("com.sun.star.comp.calc.FormatDetector");
     671             : }
     672             : 
     673          40 : uno::Reference<uno::XInterface> ScFilterDetect::impl_createInstance(
     674             :     const uno::Reference<uno::XComponentContext>& xContext ) throw (uno::Exception)
     675             : {
     676          40 :     return static_cast<cppu::OWeakObject*>(new ScFilterDetect(xContext));
     677             : }
     678             : 
     679             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10