fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / writerperfect / source / impress / KeynoteImportFilter.cxx
blobf4e2cba4fd047067adacd3482bcd0f5a8eedad8a
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
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 */
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>
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>
28 #include <DirectoryStream.hxx>
29 #include <DocumentHandler.hxx>
30 #include <WPXSvInputStream.hxx>
32 #include <xmloff/attrlist.hxx>
34 #include "KeynoteImportFilter.hxx"
36 using boost::shared_ptr;
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;
48 using writerperfect::DocumentHandler;
49 using writerperfect::WPXSvInputStream;
51 namespace beans = com::sun::star::beans;
52 namespace container = com::sun::star::container;
53 namespace ucb = com::sun::star::ucb;
55 bool KeynoteImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdpGenerator &rGenerator, utl::MediaDescriptor &)
57 return libetonyek::EtonyekDocument::parse(&rInput, &rGenerator);
60 bool KeynoteImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName)
62 if (libetonyek::EtonyekDocument::isSupported(&rInput))
64 rTypeName = "impress_Keynote_Document";
65 return true;
68 return false;
71 // XExtendedFilterDetection
72 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)
75 sal_Int32 nLength = Descriptor.getLength();
76 sal_Int32 nNewLength = nLength + 2;
77 sal_Int32 nComponentDataLocation = -1;
78 sal_Int32 nTypeNameLocation = -1;
79 sal_Int32 nUCBContentLocation = -1;
80 bool bIsPackage = false;
81 bool bUCBContentChanged = false;
82 const beans::PropertyValue *pValue = Descriptor.getConstArray();
83 Reference < XInputStream > xInputStream;
84 Reference < ucb::XContent > xContent;
85 Sequence < beans::NamedValue > lComponentDataNV;
86 Sequence < beans::PropertyValue > lComponentDataPV;
87 bool bComponentDataNV = true;
89 for (sal_Int32 i = 0 ; i < nLength; i++)
91 if (pValue[i].Name == "TypeName")
93 nTypeNameLocation = i;
94 --nNewLength;
96 if (pValue[i].Name == "ComponentData")
98 bComponentDataNV = pValue[i].Value >>= lComponentDataNV;
99 if (!bComponentDataNV)
100 pValue[i].Value >>= lComponentDataPV;
101 nComponentDataLocation = i;
102 --nNewLength;
104 else if (pValue[i].Name == "InputStream")
106 pValue[i].Value >>= xInputStream;
108 else if (pValue[i].Name == "UCBContent")
110 pValue[i].Value >>= xContent;
111 nUCBContentLocation = i;
115 assert(nNewLength >= nLength);
117 if (!xInputStream.is())
118 return OUString();
120 shared_ptr< librevenge::RVNGInputStream > input(new WPXSvInputStream(xInputStream));
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.
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.
135 if (xContent.is())
137 ucbhelper::Content aContent(xContent, Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext());
140 if (aContent.isFolder())
142 input.reset(new writerperfect::DirectoryStream(xContent));
143 bIsPackage = true;
146 catch (...)
148 return OUString();
152 libetonyek::EtonyekDocument::Type type = libetonyek::EtonyekDocument::TYPE_UNKNOWN;
153 const libetonyek::EtonyekDocument::Confidence confidence = libetonyek::EtonyekDocument::isSupported(input.get(), &type);
154 if ((libetonyek::EtonyekDocument::CONFIDENCE_NONE == confidence) || (libetonyek::EtonyekDocument::TYPE_KEYNOTE != type))
155 return OUString();
157 if (confidence == libetonyek::EtonyekDocument::CONFIDENCE_SUPPORTED_PART)
159 if (bIsPackage) // we passed a directory stream, but the filter claims it's APXL file?
160 return OUString();
162 const Reference < container::XChild > xChild(xContent, UNO_QUERY);
163 if (xChild.is())
165 const Reference < ucb::XContent > xPackageContent(xChild->getParent(), UNO_QUERY);
166 if (xPackageContent.is())
168 input.reset(new writerperfect::DirectoryStream(xPackageContent));
169 if (libetonyek::EtonyekDocument::CONFIDENCE_EXCELLENT == libetonyek::EtonyekDocument::isSupported(input.get()))
171 xContent = xPackageContent;
172 bUCBContentChanged = true;
173 bIsPackage = true;
175 else
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 return OUString();
185 // we do not need to insert ComponentData if this is not a package
186 if (!bIsPackage && (nComponentDataLocation == -1))
187 --nNewLength;
189 if (nNewLength > nLength)
190 Descriptor.realloc(nNewLength);
192 if (nTypeNameLocation == -1)
194 assert(nLength < nNewLength);
195 nTypeNameLocation = nLength++;
196 Descriptor[nTypeNameLocation].Name = "TypeName";
199 if (bIsPackage && (nComponentDataLocation == -1))
201 assert(nLength < nNewLength);
202 nComponentDataLocation = nLength++;
203 Descriptor[nComponentDataLocation].Name = "ComponentData";
206 if (bIsPackage)
208 if (bComponentDataNV)
210 const sal_Int32 nCDSize = lComponentDataNV.getLength();
211 lComponentDataNV.realloc(nCDSize + 1);
212 beans::NamedValue aValue;
213 aValue.Name = "IsPackage";
214 aValue.Value = comphelper::makeBoolAny(true);
215 lComponentDataNV[nCDSize] = aValue;
216 Descriptor[nComponentDataLocation].Value <<= lComponentDataNV;
218 else
220 const sal_Int32 nCDSize = lComponentDataPV.getLength();
221 lComponentDataPV.realloc(nCDSize + 1);
222 beans::PropertyValue aProp;
223 aProp.Name = "IsPackage";
224 aProp.Value = comphelper::makeBoolAny(true);
225 aProp.Handle = -1;
226 aProp.State = beans::PropertyState_DIRECT_VALUE;
227 lComponentDataPV[nCDSize] = aProp;
228 Descriptor[nComponentDataLocation].Value <<= lComponentDataPV;
232 if (bUCBContentChanged)
233 Descriptor[nUCBContentLocation].Value <<= xContent;
235 const OUString sTypeName("impress_AppleKeynote");
236 Descriptor[nTypeNameLocation].Value <<= sTypeName;
238 return sTypeName;
241 OUString KeynoteImportFilter_getImplementationName()
242 throw (RuntimeException)
244 return OUString("org.libreoffice.comp.Impress.KeynoteImportFilter");
247 Sequence< OUString > SAL_CALL KeynoteImportFilter_getSupportedServiceNames()
248 throw (RuntimeException)
250 Sequence < OUString > aRet(2);
251 OUString *pArray = aRet.getArray();
252 pArray[0] = "com.sun.star.document.ImportFilter";
253 pArray[1] = "com.sun.star.document.ExtendedTypeDetection";
254 return aRet;
257 Reference< XInterface > SAL_CALL KeynoteImportFilter_createInstance(const Reference< XComponentContext > &rContext)
258 throw(Exception)
260 return (cppu::OWeakObject *) new KeynoteImportFilter(rContext);
263 // XServiceInfo
264 OUString SAL_CALL KeynoteImportFilter::getImplementationName()
265 throw (RuntimeException, std::exception)
267 return KeynoteImportFilter_getImplementationName();
270 sal_Bool SAL_CALL KeynoteImportFilter::supportsService(const OUString &rServiceName)
271 throw (RuntimeException, std::exception)
273 return cppu::supportsService(this, rServiceName);
276 Sequence< OUString > SAL_CALL KeynoteImportFilter::getSupportedServiceNames()
277 throw (RuntimeException, std::exception)
279 return KeynoteImportFilter_getSupportedServiceNames();
282 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */