LCOV - code coverage report
Current view: top level - libreoffice/starmath/source - smdetect.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 204 0.0 %
Date: 2012-12-27 Functions: 0 12 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             : 
      21             : #include "smdetect.hxx"
      22             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      23             : #include <com/sun/star/beans/PropertyValue.hpp>
      24             : #include <com/sun/star/frame/XFrame.hpp>
      25             : #include <com/sun/star/frame/XModel.hpp>
      26             : #include <com/sun/star/awt/XWindow.hpp>
      27             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      28             : #include <comphelper/processfactory.hxx>
      29             : #include <com/sun/star/io/XInputStream.hpp>
      30             : #include <com/sun/star/task/XInteractionHandler.hpp>
      31             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      32             : #include <com/sun/star/ucb/CommandAbortedException.hpp>
      33             : #include <com/sun/star/ucb/InteractiveAppException.hpp>
      34             : #include <com/sun/star/ucb/XContent.hpp>
      35             : #include <com/sun/star/packages/zip/ZipIOException.hpp>
      36             : #include <toolkit/helper/vclunohelper.hxx>
      37             : #include <ucbhelper/simpleinteractionrequest.hxx>
      38             : #include <rtl/ustring.h>
      39             : #include <rtl/logfile.hxx>
      40             : #include <svl/itemset.hxx>
      41             : #include <vcl/window.hxx>
      42             : #include <svl/eitem.hxx>
      43             : #include <svl/stritem.hxx>
      44             : #include <tools/urlobj.hxx>
      45             : #include <osl/mutex.hxx>
      46             : #include <svtools/sfxecode.hxx>
      47             : #include <svtools/ehdl.hxx>
      48             : #include <sot/storinfo.hxx>
      49             : #include <vcl/svapp.hxx>
      50             : #include <sfx2/app.hxx>
      51             : #include <sfx2/sfxsids.hrc>
      52             : #include <sfx2/request.hxx>
      53             : #include <sfx2/docfile.hxx>
      54             : #include <sfx2/docfilt.hxx>
      55             : #include <sfx2/fcontnr.hxx>
      56             : #include <sfx2/brokenpackageint.hxx>
      57             : 
      58             : #include "document.hxx"
      59             : #include "eqnolefilehdr.hxx"
      60             : 
      61             : using namespace ::com::sun::star;
      62             : using namespace ::com::sun::star::uno;
      63             : using namespace ::com::sun::star::io;
      64             : using namespace ::com::sun::star::frame;
      65             : using namespace ::com::sun::star::task;
      66             : using namespace ::com::sun::star::beans;
      67             : using namespace ::com::sun::star::lang;
      68             : using namespace ::com::sun::star::ucb;
      69             : using namespace ::rtl;
      70             : 
      71           0 : SmFilterDetect::SmFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& /*xFactory*/ )
      72             : {
      73           0 : }
      74             : 
      75           0 : SmFilterDetect::~SmFilterDetect()
      76             : {
      77           0 : }
      78             : 
      79           0 : ::rtl::OUString SAL_CALL SmFilterDetect::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
      80             : {
      81           0 :     REFERENCE< XInputStream > xStream;
      82           0 :     REFERENCE< XContent > xContent;
      83           0 :     REFERENCE< XInteractionHandler > xInteraction;
      84           0 :     String aURL;
      85           0 :     ::rtl::OUString sTemp;
      86           0 :     String aTypeName;            // a name describing the type (from MediaDescriptor, usually from flat detection)
      87           0 :     String aPreselectedFilterName;      // a name describing the filter to use (from MediaDescriptor, usually from UI action)
      88             : 
      89           0 :     ::rtl::OUString aDocumentTitle; // interesting only if set in this method
      90             : 
      91             :     // opening as template is done when a parameter tells to do so and a template filter can be detected
      92             :     // (otherwise no valid filter would be found) or if the detected filter is a template filter and
      93             :     // there is no parameter that forbids to open as template
      94           0 :     sal_Bool bOpenAsTemplate = sal_False;
      95           0 :     sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
      96             : 
      97           0 :     sal_Bool bRepairPackage = sal_False;
      98           0 :     sal_Bool bRepairAllowed = sal_False;
      99             : 
     100             :     // now some parameters that can already be in the array, but may be overwritten or new inserted here
     101             :     // remember their indices in the case new values must be added to the array
     102           0 :     sal_Int32 nPropertyCount = lDescriptor.getLength();
     103           0 :     sal_Int32 nIndexOfInputStream = -1;
     104           0 :     sal_Int32 nIndexOfContent = -1;
     105           0 :     sal_Int32 nIndexOfReadOnlyFlag = -1;
     106           0 :     sal_Int32 nIndexOfTemplateFlag = -1;
     107           0 :     sal_Int32 nIndexOfDocumentTitle = -1;
     108             : 
     109           0 :     for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
     110             :     {
     111             :         // extract properties
     112           0 :         if( lDescriptor[nProperty].Name == "URL" )
     113             :         {
     114           0 :             lDescriptor[nProperty].Value >>= sTemp;
     115           0 :             aURL = sTemp;
     116             :         }
     117           0 :         else if( !aURL.Len() && lDescriptor[nProperty].Name == "FileName" )
     118             :         {
     119           0 :             lDescriptor[nProperty].Value >>= sTemp;
     120           0 :             aURL = sTemp;
     121             :         }
     122           0 :         else if( lDescriptor[nProperty].Name == "TypeName" )
     123             :         {
     124           0 :             lDescriptor[nProperty].Value >>= sTemp;
     125           0 :             aTypeName = sTemp;
     126             :         }
     127           0 :         else if( lDescriptor[nProperty].Name == "FilterName" )
     128             :         {
     129           0 :             lDescriptor[nProperty].Value >>= sTemp;
     130           0 :             aPreselectedFilterName = sTemp;
     131             :         }
     132           0 :         else if( lDescriptor[nProperty].Name == "InputStream" )
     133           0 :             nIndexOfInputStream = nProperty;
     134           0 :         else if( lDescriptor[nProperty].Name == "ReadOnly" )
     135           0 :             nIndexOfReadOnlyFlag = nProperty;
     136           0 :         else if( lDescriptor[nProperty].Name == "UCBContent" )
     137           0 :             nIndexOfContent = nProperty;
     138           0 :         else if( lDescriptor[nProperty].Name == "AsTemplate" )
     139             :         {
     140           0 :             lDescriptor[nProperty].Value >>= bOpenAsTemplate;
     141           0 :             nIndexOfTemplateFlag = nProperty;
     142             :         }
     143           0 :         else if( lDescriptor[nProperty].Name == "InteractionHandler" )
     144           0 :             lDescriptor[nProperty].Value >>= xInteraction;
     145           0 :         else if( lDescriptor[nProperty].Name == "RepairPackage" )
     146           0 :             lDescriptor[nProperty].Value >>= bRepairPackage;
     147           0 :         else if( lDescriptor[nProperty].Name == "DocumentTitle" )
     148           0 :             nIndexOfDocumentTitle = nProperty;
     149             :     }
     150             : 
     151             :     // can't check the type for external filters, so set the "dont" flag accordingly
     152           0 :     SolarMutexGuard aGuard;
     153             : 
     154           0 :     SfxApplication* pApp = SFX_APP();
     155           0 :     SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() );
     156           0 :     TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
     157           0 :     SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
     158             : 
     159           0 :     bWasReadOnly = pItem && pItem->GetValue();
     160             : 
     161           0 :     String aFilterName;
     162           0 :     String aPrefix = rtl::OUString( "private:factory/" );
     163           0 :     if( aURL.Match( aPrefix ) == aPrefix.Len() )
     164             :     {
     165           0 :         const SfxFilter* pFilter = 0;
     166           0 :         String aPattern( aPrefix );
     167           0 :         aPattern += rtl::OUString("smath");
     168           0 :         if ( aURL.Match( aPattern ) >= aPattern.Len() )
     169             :         {
     170           0 :             pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
     171           0 :             aTypeName = pFilter->GetTypeName();
     172           0 :             aFilterName = pFilter->GetName();
     173           0 :         }
     174             :     }
     175             :     else
     176             :     {
     177             :         // ctor of SfxMedium uses owner transition of ItemSet
     178           0 :         SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, NULL, pSet );
     179           0 :         aMedium.UseInteractionHandler( true );
     180             : 
     181           0 :         bool bIsStorage = aMedium.IsStorage();
     182           0 :         if ( aMedium.GetErrorCode() == ERRCODE_NONE )
     183             :         {
     184             :             // remember input stream and content and put them into the descriptor later
     185             :             // should be done here since later the medium can switch to a version
     186           0 :             xStream = aMedium.GetInputStream();
     187           0 :             xContent = aMedium.GetContent();
     188           0 :             bReadOnly = aMedium.IsReadOnly();
     189             : 
     190           0 :             if ( bIsStorage )
     191             :             {
     192             :                 //TODO/LATER: factor this out!
     193           0 :                 uno::Reference < embed::XStorage > xStorage = aMedium.GetStorage( sal_False );
     194           0 :                 if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
     195             :                 {
     196             :                     // error during storage creation means _here_ that the medium
     197             :                     // is broken, but we can not handle it in medium since unpossibility
     198             :                     // to create a storage does not _always_ means that the medium is broken
     199           0 :                     aMedium.SetError( aMedium.GetLastStorageCreationState(), OSL_LOG_PREFIX );
     200           0 :                     if ( xInteraction.is() )
     201             :                     {
     202           0 :                         OUString empty;
     203             :                         try
     204             :                         {
     205             :                             InteractiveAppException xException( empty,
     206             :                                                             REFERENCE< XInterface >(),
     207             :                                                             InteractionClassification_ERROR,
     208           0 :                                                             aMedium.GetError() );
     209             : 
     210             :                             REFERENCE< XInteractionRequest > xRequest(
     211             :                                 new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
     212           0 :                                                                       ucbhelper::CONTINUATION_APPROVE ) );
     213           0 :                             xInteraction->handle( xRequest );
     214             :                         }
     215           0 :                         catch ( Exception & ) {};
     216             :                     }
     217             :                 }
     218             :                 else
     219             :                 {
     220           0 :                     aFilterName.Erase();
     221             : 
     222             :                     try
     223             :                     {
     224           0 :                         const SfxFilter* pFilter = aPreselectedFilterName.Len() ?
     225           0 :                                 SfxFilterMatcher().GetFilter4FilterName( aPreselectedFilterName ) : aTypeName.Len() ?
     226           0 :                                 SfxFilterMatcher(rtl::OUString("smath")).GetFilter4EA( aTypeName ) : 0;
     227           0 :                         String aTmpFilterName;
     228           0 :                         if ( pFilter )
     229           0 :                             aTmpFilterName = pFilter->GetName();
     230           0 :                         aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsAllowedAsTemplate() : sal_False, &aTmpFilterName );
     231             :                     }
     232           0 :                     catch( const lang::WrappedTargetException& aWrap )
     233             :                     {
     234           0 :                         packages::zip::ZipIOException aZipException;
     235             : 
     236             :                         // repairing is done only if this type is requested from outside
     237           0 :                         if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() )
     238             :                         {
     239           0 :                             if ( xInteraction.is() )
     240             :                             {
     241             :                                 // the package is broken one
     242           0 :                                    aDocumentTitle = aMedium.GetURLObject().getName(
     243             :                                                             INetURLObject::LAST_SEGMENT,
     244             :                                                             true,
     245           0 :                                                             INetURLObject::DECODE_WITH_CHARSET );
     246             : 
     247           0 :                                 if ( !bRepairPackage )
     248             :                                 {
     249             :                                     // ask the user whether he wants to try to repair
     250           0 :                                     RequestPackageReparation aRequest( aDocumentTitle );
     251           0 :                                     xInteraction->handle( aRequest.GetRequest() );
     252           0 :                                     bRepairAllowed = aRequest.isApproved();
     253             :                                 }
     254             : 
     255           0 :                                 if ( !bRepairAllowed )
     256             :                                 {
     257             :                                     // repair either not allowed or not successful
     258           0 :                                     NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
     259           0 :                                     xInteraction->handle( aNotifyRequest.GetRequest() );
     260             :                                 }
     261             :                             }
     262             : 
     263           0 :                             if ( !bRepairAllowed )
     264           0 :                                 aTypeName.Erase();
     265           0 :                         }
     266             :                     }
     267           0 :                     catch( uno::RuntimeException& )
     268             :                     {
     269           0 :                         throw;
     270             :                     }
     271           0 :                     catch( uno::Exception& )
     272             :                     {
     273           0 :                         aTypeName.Erase();
     274             :                     }
     275             : 
     276           0 :                        if ( aTypeName.Len() )
     277             :                     {
     278             :                            const SfxFilter* pFilter =
     279           0 :                                     SfxFilterMatcher( rtl::OUString("smath") ).GetFilter4EA( aTypeName );
     280           0 :                         if ( pFilter )
     281           0 :                             aFilterName = pFilter->GetName();
     282             :                     }
     283           0 :                 }
     284             :             }
     285             :             else
     286             :             {
     287             :                 //Test to see if this begins with xml and if so run it through
     288             :                 //the MathML filter. There are all sorts of things wrong with
     289             :                 //this approach, to be fixed at a better level than here
     290           0 :                 SvStream *pStrm = aMedium.GetInStream();
     291           0 :                 aTypeName.Erase();
     292           0 :                 if (pStrm && !pStrm->GetError())
     293             :                 {
     294           0 :                     SotStorageRef aStorage = new SotStorage ( pStrm, sal_False );
     295           0 :                     if ( !aStorage->GetError() )
     296             :                     {
     297           0 :                         if (aStorage->IsStream(rtl::OUString("Equation Native")))
     298             :                         {
     299             :                             sal_uInt8 nVersion;
     300           0 :                             if (GetMathTypeVersion( aStorage, nVersion ) && nVersion <=3)
     301           0 :                                 aTypeName.AssignAscii( "math_MathType_3x" );
     302             :                         }
     303             :                     }
     304             :                     else
     305             :                     {
     306           0 :                         const sal_uInt16 nSize = 5;
     307             :                         sal_Char aBuffer[nSize+1];
     308           0 :                         aBuffer[nSize] = 0;
     309           0 :                         pStrm->Seek( STREAM_SEEK_TO_BEGIN );
     310           0 :                         sal_uLong nBytesRead = pStrm->Read( aBuffer, nSize );
     311           0 :                         if (nBytesRead == nSize)
     312             :                         {
     313           0 :                             if (0 == strncmp( "<?xml",aBuffer,nSize))
     314             :                             {
     315             :                                 // 200 should be enough for the XML
     316             :                                 // version, encoding and !DOCTYPE
     317             :                                 // stuff I hope?
     318             :                                 sal_Char aBuffer2[200];
     319           0 :                                 nBytesRead = pStrm->Read( aBuffer2, sizeof(aBuffer2) - 1);
     320           0 :                                 aBuffer2[nBytesRead] = 0;
     321           0 :                                 if (strstr( aBuffer2, "<math>" ) != NULL ||
     322           0 :                                     strstr( aBuffer2, "<math " ) != NULL)
     323             :                                 {
     324             :                                     static const sal_Char sFltrNm_2[] = MATHML_XML;
     325             :                                     static const sal_Char sTypeNm_2[] = "math_MathML_XML_Math";
     326           0 :                                     aFilterName.AssignAscii( sFltrNm_2 );
     327           0 :                                     aTypeName.AssignAscii( sTypeNm_2 );
     328             :                                 }
     329             :                             }
     330             :                         }
     331             :                     }
     332             : 
     333           0 :                     if ( aTypeName.Len() )
     334             :                     {
     335           0 :                         const SfxFilter* pFilt = SfxFilterMatcher( rtl::OUString("smath") ).GetFilter4EA( aTypeName );
     336           0 :                         if ( pFilt )
     337           0 :                             aFilterName = pFilt->GetName();
     338           0 :                     }
     339             :                 }
     340             :             }
     341           0 :         }
     342             :     }
     343             : 
     344           0 :     if ( nIndexOfInputStream == -1 && xStream.is() )
     345             :     {
     346             :         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
     347           0 :         lDescriptor.realloc( nPropertyCount + 1 );
     348           0 :         lDescriptor[nPropertyCount].Name = "InputStream";
     349           0 :         lDescriptor[nPropertyCount].Value <<= xStream;
     350           0 :         nPropertyCount++;
     351             :     }
     352             : 
     353           0 :     if ( nIndexOfContent == -1 && xContent.is() )
     354             :     {
     355             :         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
     356           0 :         lDescriptor.realloc( nPropertyCount + 1 );
     357           0 :         lDescriptor[nPropertyCount].Name = "UCBContent";
     358           0 :         lDescriptor[nPropertyCount].Value <<= xContent;
     359           0 :         nPropertyCount++;
     360             :     }
     361             : 
     362           0 :     if ( bReadOnly != bWasReadOnly )
     363             :     {
     364           0 :         if ( nIndexOfReadOnlyFlag == -1 )
     365             :         {
     366           0 :             lDescriptor.realloc( nPropertyCount + 1 );
     367           0 :             lDescriptor[nPropertyCount].Name = "ReadOnly";
     368           0 :             lDescriptor[nPropertyCount].Value <<= bReadOnly;
     369           0 :             nPropertyCount++;
     370             :         }
     371             :         else
     372           0 :             lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
     373             :     }
     374             : 
     375           0 :     if ( !bRepairPackage && bRepairAllowed )
     376             :     {
     377           0 :         lDescriptor.realloc( nPropertyCount + 1 );
     378           0 :         lDescriptor[nPropertyCount].Name = "RepairPackage";
     379           0 :         lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
     380           0 :         nPropertyCount++;
     381             : 
     382           0 :         bOpenAsTemplate = sal_True;
     383             : 
     384             :         // TODO/LATER: set progress bar that should be used
     385             :     }
     386             : 
     387           0 :     if ( bOpenAsTemplate )
     388             :     {
     389           0 :         if ( nIndexOfTemplateFlag == -1 )
     390             :         {
     391           0 :             lDescriptor.realloc( nPropertyCount + 1 );
     392           0 :             lDescriptor[nPropertyCount].Name = "AsTemplate";
     393           0 :             lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
     394           0 :             nPropertyCount++;
     395             :         }
     396             :         else
     397           0 :             lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
     398             :     }
     399             : 
     400           0 :     if ( !aDocumentTitle.isEmpty() )
     401             :     {
     402             :         // the title was set here
     403           0 :         if ( nIndexOfDocumentTitle == -1 )
     404             :         {
     405           0 :             lDescriptor.realloc( nPropertyCount + 1 );
     406           0 :             lDescriptor[nPropertyCount].Name = "DocumentTitle";
     407           0 :             lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
     408           0 :             nPropertyCount++;
     409             :         }
     410             :         else
     411           0 :             lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
     412             :     }
     413             : 
     414           0 :     if ( !aFilterName.Len() )
     415           0 :         aTypeName.Erase();
     416             : 
     417           0 :     return aTypeName;
     418             : }
     419             : 
     420             : /* XServiceInfo */
     421           0 : rtl::OUString SAL_CALL SmFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
     422             : {
     423           0 :     return impl_getStaticImplementationName();
     424             : }
     425             :                                                                                                                                 \
     426             : /* XServiceInfo */
     427           0 : sal_Bool SAL_CALL SmFilterDetect::supportsService( const rtl::OUString& sServiceName ) throw( UNORUNTIMEEXCEPTION )
     428             : {
     429           0 :     UNOSEQUENCE< rtl::OUString > seqServiceNames = getSupportedServiceNames();
     430           0 :     const rtl::OUString*         pArray          = seqServiceNames.getConstArray();
     431           0 :     for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
     432             :     {
     433           0 :         if ( pArray[nCounter] == sServiceName )
     434             :         {
     435           0 :             return sal_True ;
     436             :         }
     437             :     }
     438           0 :     return sal_False ;
     439             : }
     440             : 
     441             : /* XServiceInfo */
     442           0 : UNOSEQUENCE< rtl::OUString > SAL_CALL SmFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
     443             : {
     444           0 :     return impl_getStaticSupportedServiceNames();
     445             : }
     446             : 
     447             : /* Helper for XServiceInfo */
     448           0 : UNOSEQUENCE< rtl::OUString > SmFilterDetect::impl_getStaticSupportedServiceNames()
     449             : {
     450           0 :     UNOSEQUENCE< rtl::OUString > seqServiceNames( 1 );
     451           0 :     seqServiceNames.getArray() [0] = "com.sun.star.frame.ExtendedTypeDetection";
     452           0 :     return seqServiceNames ;
     453             : }
     454             : 
     455             : /* Helper for XServiceInfo */
     456           0 : rtl::OUString SmFilterDetect::impl_getStaticImplementationName()
     457             : {
     458           0 :     return rtl::OUString("com.sun.star.comp.math.FormatDetector");
     459             : }
     460             : 
     461             : /* Helper for registry */
     462           0 : UNOREFERENCE< UNOXINTERFACE > SAL_CALL SmFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
     463             : {
     464           0 :     return UNOREFERENCE< UNOXINTERFACE >( *new SmFilterDetect( xServiceManager ) );
     465           0 : }
     466             : 
     467             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10