LCOV - code coverage report
Current view: top level - writerperfect/source/impress - KeynoteImportFilter.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 65 116 56.0 %
Date: 2015-06-13 12:38:46 Functions: 9 11 81.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* KeynoteImportFilter: Sets up the filter, and calls OdpExporter
       3             :  * to do the actual filtering
       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             : 
      10             : #include <boost/shared_ptr.hpp>
      11             : #include <com/sun/star/beans/NamedValue.hpp>
      12             : #include <com/sun/star/beans/PropertyValue.hpp>
      13             : #include <com/sun/star/container/XChild.hpp>
      14             : #include <com/sun/star/io/XInputStream.hpp>
      15             : #include <com/sun/star/uno/Reference.h>
      16             : #include <com/sun/star/ucb/XContent.hpp>
      17             : #include <comphelper/processfactory.hxx>
      18             : #include <comphelper/types.hxx>
      19             : #include <cppuhelper/supportsservice.hxx>
      20             : 
      21             : #include <iostream>
      22             : #include <libetonyek/libetonyek.h>
      23             : #include <libodfgen/libodfgen.hxx>
      24             : #include <osl/diagnose.h>
      25             : #include <rtl/tencinfo.h>
      26             : #include <ucbhelper/content.hxx>
      27             : 
      28             : #include <DirectoryStream.hxx>
      29             : #include <DocumentHandler.hxx>
      30             : #include <WPXSvInputStream.hxx>
      31             : 
      32             : #include <xmloff/attrlist.hxx>
      33             : 
      34             : #include "KeynoteImportFilter.hxx"
      35             : 
      36             : using boost::shared_ptr;
      37             : 
      38             : using com::sun::star::io::XInputStream;
      39             : using com::sun::star::uno::Any;
      40             : using com::sun::star::uno::Exception;
      41             : using com::sun::star::uno::Reference;
      42             : using com::sun::star::uno::RuntimeException;
      43             : using com::sun::star::uno::Sequence;
      44             : using com::sun::star::uno::UNO_QUERY;
      45             : using com::sun::star::uno::XComponentContext;
      46             : using com::sun::star::uno::XInterface;
      47             : 
      48             : using writerperfect::DocumentHandler;
      49             : using writerperfect::WPXSvInputStream;
      50             : 
      51             : namespace beans = com::sun::star::beans;
      52             : namespace container = com::sun::star::container;
      53             : namespace ucb = com::sun::star::ucb;
      54             : 
      55           4 : bool KeynoteImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdpGenerator &rGenerator, utl::MediaDescriptor &)
      56             : {
      57           4 :     return libetonyek::EtonyekDocument::parse(&rInput, &rGenerator);
      58             : }
      59             : 
      60           0 : bool KeynoteImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName)
      61             : {
      62           0 :     if (libetonyek::EtonyekDocument::isSupported(&rInput))
      63             :     {
      64           0 :         rTypeName = "impress_Keynote_Document";
      65           0 :         return true;
      66             :     }
      67             : 
      68           0 :     return false;
      69             : }
      70             : 
      71             : // XExtendedFilterDetection
      72          92 : OUString SAL_CALL KeynoteImportFilter::detect(com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > &Descriptor)
      73             : throw(com::sun::star::uno::RuntimeException, std::exception)
      74             : {
      75          92 :     sal_Int32 nLength = Descriptor.getLength();
      76          92 :     sal_Int32 nNewLength = nLength + 2;
      77          92 :     sal_Int32 nComponentDataLocation = -1;
      78          92 :     sal_Int32 nTypeNameLocation = -1;
      79          92 :     sal_Int32 nUCBContentLocation = -1;
      80          92 :     bool bIsPackage = false;
      81          92 :     bool bUCBContentChanged = false;
      82          92 :     const beans::PropertyValue *pValue = Descriptor.getConstArray();
      83          92 :     Reference < XInputStream > xInputStream;
      84         184 :     Reference < ucb::XContent > xContent;
      85         184 :     Sequence < beans::NamedValue > lComponentDataNV;
      86         184 :     Sequence < beans::PropertyValue > lComponentDataPV;
      87          92 :     bool bComponentDataNV = true;
      88             : 
      89         799 :     for (sal_Int32 i = 0 ; i < nLength; i++)
      90             :     {
      91         707 :         if (pValue[i].Name == "TypeName")
      92             :         {
      93          87 :             nTypeNameLocation = i;
      94          87 :             --nNewLength;
      95             :         }
      96         707 :         if (pValue[i].Name == "ComponentData")
      97             :         {
      98           0 :             bComponentDataNV = pValue[i].Value >>= lComponentDataNV;
      99           0 :             if (!bComponentDataNV)
     100           0 :                 pValue[i].Value >>= lComponentDataPV;
     101           0 :             nComponentDataLocation = i;
     102           0 :             --nNewLength;
     103             :         }
     104         707 :         else if (pValue[i].Name == "InputStream")
     105             :         {
     106          92 :             pValue[i].Value >>= xInputStream;
     107             :         }
     108         615 :         else if (pValue[i].Name == "UCBContent")
     109             :         {
     110          91 :             pValue[i].Value >>= xContent;
     111          91 :             nUCBContentLocation = i;
     112             :         }
     113             :     }
     114             : 
     115             :     assert(nNewLength >= nLength);
     116             : 
     117          92 :     if (!xInputStream.is())
     118           0 :         return OUString();
     119             : 
     120         184 :     shared_ptr< librevenge::RVNGInputStream > input(new WPXSvInputStream(xInputStream));
     121             : 
     122             :     /* Apple Keynote documents come in two variants:
     123             :      * * actual files (zip), only produced by Keynote 5 (at least with
     124             :      *   default settings)
     125             :      * * packages (IOW, directories), produced by Keynote 1-4 and again
     126             :      *   starting with 6.
     127             :      * But since the libetonyek import only works with a stream, we need
     128             :      * to pass it one for the whole package. Here we determine if that
     129             :      * is needed.
     130             :      *
     131             :      * Note: for convenience, we also recognize that the main XML file
     132             :      * from a package was passed and pass the whole package to the
     133             :      * filter instead.
     134             :      */
     135          92 :     if (xContent.is())
     136             :     {
     137          91 :         ucbhelper::Content aContent(xContent, Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext());
     138             :         try
     139             :         {
     140          91 :             if (aContent.isFolder())
     141             :             {
     142           0 :                 input.reset(new writerperfect::DirectoryStream(xContent));
     143           0 :                 bIsPackage = true;
     144             :             }
     145             :         }
     146           0 :         catch (...)
     147             :         {
     148           0 :             return OUString();
     149          91 :         }
     150             :     }
     151             : 
     152          92 :     libetonyek::EtonyekDocument::Type type = libetonyek::EtonyekDocument::TYPE_UNKNOWN;
     153          92 :     const libetonyek::EtonyekDocument::Confidence confidence = libetonyek::EtonyekDocument::isSupported(input.get(), &type);
     154          92 :     if ((libetonyek::EtonyekDocument::CONFIDENCE_NONE == confidence) || (libetonyek::EtonyekDocument::TYPE_KEYNOTE != type))
     155          88 :         return OUString();
     156             : 
     157           4 :     if (confidence == libetonyek::EtonyekDocument::CONFIDENCE_SUPPORTED_PART)
     158             :     {
     159           0 :         if (bIsPackage)   // we passed a directory stream, but the filter claims it's APXL file?
     160           0 :             return OUString();
     161             : 
     162           0 :         const Reference < container::XChild > xChild(xContent, UNO_QUERY);
     163           0 :         if (xChild.is())
     164             :         {
     165           0 :             const Reference < ucb::XContent > xPackageContent(xChild->getParent(), UNO_QUERY);
     166           0 :             if (xPackageContent.is())
     167             :             {
     168           0 :                 input.reset(new writerperfect::DirectoryStream(xPackageContent));
     169           0 :                 if (libetonyek::EtonyekDocument::CONFIDENCE_EXCELLENT == libetonyek::EtonyekDocument::isSupported(input.get()))
     170             :                 {
     171           0 :                     xContent = xPackageContent;
     172           0 :                     bUCBContentChanged = true;
     173           0 :                     bIsPackage = true;
     174             :                 }
     175             :                 else
     176             :                 {
     177             :                     // The passed stream has been detected as APXL file, but its parent dir is not a valid Keynote
     178             :                     // package? Something is wrong here...
     179           0 :                     return OUString();
     180             :                 }
     181           0 :             }
     182           0 :         }
     183             :     }
     184             : 
     185             :     // we do not need to insert ComponentData if this is not a package
     186           4 :     if (!bIsPackage && (nComponentDataLocation == -1))
     187           4 :         --nNewLength;
     188             : 
     189           4 :     if (nNewLength > nLength)
     190           4 :         Descriptor.realloc(nNewLength);
     191             : 
     192           4 :     if (nTypeNameLocation == -1)
     193             :     {
     194             :         assert(nLength < nNewLength);
     195           4 :         nTypeNameLocation = nLength++;
     196           4 :         Descriptor[nTypeNameLocation].Name = "TypeName";
     197             :     }
     198             : 
     199           4 :     if (bIsPackage && (nComponentDataLocation == -1))
     200             :     {
     201             :         assert(nLength < nNewLength);
     202           0 :         nComponentDataLocation = nLength++;
     203           0 :         Descriptor[nComponentDataLocation].Name = "ComponentData";
     204             :     }
     205             : 
     206           4 :     if (bIsPackage)
     207             :     {
     208           0 :         if (bComponentDataNV)
     209             :         {
     210           0 :             const sal_Int32 nCDSize = lComponentDataNV.getLength();
     211           0 :             lComponentDataNV.realloc(nCDSize + 1);
     212           0 :             beans::NamedValue aValue;
     213           0 :             aValue.Name = "IsPackage";
     214           0 :             aValue.Value = comphelper::makeBoolAny(true);
     215           0 :             lComponentDataNV[nCDSize] = aValue;
     216           0 :             Descriptor[nComponentDataLocation].Value <<= lComponentDataNV;
     217             :         }
     218             :         else
     219             :         {
     220           0 :             const sal_Int32 nCDSize = lComponentDataPV.getLength();
     221           0 :             lComponentDataPV.realloc(nCDSize + 1);
     222           0 :             beans::PropertyValue aProp;
     223           0 :             aProp.Name = "IsPackage";
     224           0 :             aProp.Value = comphelper::makeBoolAny(true);
     225           0 :             aProp.Handle = -1;
     226           0 :             aProp.State = beans::PropertyState_DIRECT_VALUE;
     227           0 :             lComponentDataPV[nCDSize] = aProp;
     228           0 :             Descriptor[nComponentDataLocation].Value <<= lComponentDataPV;
     229             :         }
     230             :     }
     231             : 
     232           4 :     if (bUCBContentChanged)
     233           0 :         Descriptor[nUCBContentLocation].Value <<= xContent;
     234             : 
     235           8 :     const OUString sTypeName("impress_AppleKeynote");
     236           4 :     Descriptor[nTypeNameLocation].Value <<= sTypeName;
     237             : 
     238          96 :     return sTypeName;
     239             : }
     240             : 
     241          13 : OUString KeynoteImportFilter_getImplementationName()
     242             : throw (RuntimeException)
     243             : {
     244          13 :     return OUString("org.libreoffice.comp.Impress.KeynoteImportFilter");
     245             : }
     246             : 
     247           7 : Sequence< OUString > SAL_CALL KeynoteImportFilter_getSupportedServiceNames()
     248             : throw (RuntimeException)
     249             : {
     250           7 :     Sequence < OUString > aRet(2);
     251           7 :     OUString *pArray = aRet.getArray();
     252           7 :     pArray[0] = "com.sun.star.document.ImportFilter";
     253           7 :     pArray[1] = "com.sun.star.document.ExtendedTypeDetection";
     254           7 :     return aRet;
     255             : }
     256             : 
     257          89 : Reference< XInterface > SAL_CALL KeynoteImportFilter_createInstance(const Reference< XComponentContext > &rContext)
     258             : throw(Exception)
     259             : {
     260          89 :     return static_cast<cppu::OWeakObject *>(new KeynoteImportFilter(rContext));
     261             : }
     262             : 
     263             : // XServiceInfo
     264           1 : OUString SAL_CALL KeynoteImportFilter::getImplementationName()
     265             : throw (RuntimeException, std::exception)
     266             : {
     267           1 :     return KeynoteImportFilter_getImplementationName();
     268             : }
     269             : 
     270           0 : sal_Bool SAL_CALL KeynoteImportFilter::supportsService(const OUString &rServiceName)
     271             : throw (RuntimeException, std::exception)
     272             : {
     273           0 :     return cppu::supportsService(this, rServiceName);
     274             : }
     275             : 
     276           1 : Sequence< OUString > SAL_CALL KeynoteImportFilter::getSupportedServiceNames()
     277             : throw (RuntimeException, std::exception)
     278             : {
     279           1 :     return KeynoteImportFilter_getSupportedServiceNames();
     280          18 : }
     281             : 
     282             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11