fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / filter / source / svg / svgfilter.cxx
blob755684091bc0c6826fe3bc934275c4f05b70da05
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <cstdio>
23 #include <comphelper/servicedecl.hxx>
24 #include <uno/environment.h>
25 #include <com/sun/star/drawing/XDrawPage.hpp>
26 #include <com/sun/star/drawing/XDrawView.hpp>
27 #include <com/sun/star/frame/Desktop.hpp>
28 #include <com/sun/star/frame/XController.hpp>
29 #include <com/sun/star/view/XSelectionSupplier.hpp>
30 #include <com/sun/star/drawing/XDrawSubController.hpp>
31 #include <com/sun/star/container/XNamed.hpp>
32 #include <com/sun/star/uno/XComponentContext.hpp>
33 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
34 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
35 #include <com/sun/star/drawing/framework/XConfiguration.hpp>
36 #include <com/sun/star/drawing/framework/AnchorBindingMode.hpp>
37 #include <com/sun/star/drawing/framework/XResourceId.hpp>
38 #include <com/sun/star/drawing/framework/XResource.hpp>
39 #include <com/sun/star/drawing/framework/XView.hpp>
40 #include <com/sun/star/drawing/framework/ResourceId.hpp>
41 #include <comphelper/processfactory.hxx>
43 #include <osl/mutex.hxx>
45 #include "svgfilter.hxx"
46 #include "svgwriter.hxx"
48 using namespace ::com::sun::star;
50 // -------------
51 // - SVGFilter -
52 // -------------
54 SVGFilter::SVGFilter( const Reference< XComponentContext >& rxCtx ) :
55 mxContext( rxCtx ),
56 mpSVGDoc( NULL ),
57 mpSVGExport( NULL ),
58 mpSVGFontExport( NULL ),
59 mpSVGWriter( NULL ),
60 mpDefaultSdrPage( NULL ),
61 mpSdrModel( NULL ),
62 mbPresentation( sal_False ),
63 mbExportAll( sal_False ),
64 mpObjects( NULL )
69 // -----------------------------------------------------------------------------
71 SVGFilter::~SVGFilter()
73 DBG_ASSERT( mpSVGDoc == NULL, "mpSVGDoc not destroyed" );
74 DBG_ASSERT( mpSVGExport == NULL, "mpSVGExport not destroyed" );
75 DBG_ASSERT( mpSVGFontExport == NULL, "mpSVGFontExport not destroyed" );
76 DBG_ASSERT( mpSVGWriter == NULL, "mpSVGWriter not destroyed" );
77 DBG_ASSERT( mpObjects == NULL, "mpObjects not destroyed" );
80 // -----------------------------------------------------------------------------
82 sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescriptor )
83 throw (RuntimeException)
85 SolarMutexGuard aGuard;
86 Window* pFocusWindow = Application::GetFocusWindow();
87 sal_Bool bRet;
89 if( pFocusWindow )
90 pFocusWindow->EnterWait();
92 if( mxDstDoc.is() )
93 bRet = implImport( rDescriptor );
94 #ifndef DISABLE_EXPORT
95 else if( mxSrcDoc.is() )
97 if( !mbExportAll && !mSelectedPages.hasElements() )
99 uno::Reference< frame::XDesktop2 > xDesktop(frame::Desktop::create(mxContext));
100 uno::Reference< frame::XFrame > xFrame(xDesktop->getCurrentFrame(),
101 uno::UNO_QUERY_THROW);
102 uno::Reference<frame::XController > xController(xFrame->getController(),
103 uno::UNO_QUERY_THROW);
104 uno::Reference<drawing::XDrawView > xDrawView(xController,
105 uno::UNO_QUERY_THROW);
106 uno::Reference<drawing::framework::XControllerManager> xManager(xController,
107 uno::UNO_QUERY_THROW);
108 uno::Reference<drawing::framework::XConfigurationController> xConfigController(xManager->getConfigurationController());
110 // which view configuration are we in?
112 // * traverse Impress resources to find slide preview pane, grab selection from there
113 // * otherwise, fallback to current slide
115 uno::Sequence<uno::Reference<drawing::framework::XResourceId> > aResIds(
116 xConfigController->getCurrentConfiguration()->getResources(
117 uno::Reference<drawing::framework::XResourceId>(),
119 drawing::framework::AnchorBindingMode_INDIRECT));
121 for( sal_Int32 i=0; i<aResIds.getLength(); ++i )
123 // can we somehow obtain the slidesorter from the Impress framework?
124 if( aResIds[i]->getResourceURL() == "private:resource/view/SlideSorter" )
126 // got it, grab current selection from there
127 uno::Reference<drawing::framework::XResource> xRes(
128 xConfigController->getResource(aResIds[i]));
130 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
131 xRes,
132 uno::UNO_QUERY );
133 if( xSelectionSupplier.is() )
135 uno::Any aSelection = xSelectionSupplier->getSelection();
136 if( aSelection.hasValue() )
138 ObjectSequence aSelectedPageSequence;
139 aSelection >>= aSelectedPageSequence;
140 mSelectedPages.realloc( aSelectedPageSequence.getLength() );
141 for( sal_Int32 j=0; j<mSelectedPages.getLength(); ++j )
143 uno::Reference< drawing::XDrawPage > xDrawPage( aSelectedPageSequence[j],
144 uno::UNO_QUERY );
145 mSelectedPages[j] = xDrawPage;
148 // and stop looping. it is likely not getting better
149 break;
155 if( !mSelectedPages.hasElements() )
157 // apparently failed to glean selection - fallback to current page
158 mSelectedPages.realloc( 1 );
159 mSelectedPages[0] = xDrawView->getCurrentPage();
164 * Export all slides, or requested "PagePos"
166 if( !mSelectedPages.hasElements() )
168 sal_Int32 nLength = rDescriptor.getLength();
169 const PropertyValue* pValue = rDescriptor.getConstArray();
170 sal_Int32 nPageToExport = -1;
172 for ( sal_Int32 i = 0 ; i < nLength; ++i)
174 if ( pValue[ i ].Name == "PagePos" )
176 pValue[ i ].Value >>= nPageToExport;
180 uno::Reference< drawing::XMasterPagesSupplier > xMasterPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
181 uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
183 if( xMasterPagesSupplier.is() && xDrawPagesSupplier.is() )
185 uno::Reference< drawing::XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), uno::UNO_QUERY );
186 uno::Reference< drawing::XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), uno::UNO_QUERY );
187 if( xMasterPages.is() && xMasterPages->getCount() &&
188 xDrawPages.is() && xDrawPages->getCount() )
190 sal_Int32 nDPCount = xDrawPages->getCount();
192 mSelectedPages.realloc( nPageToExport != -1 ? 1 : nDPCount );
193 sal_Int32 i;
194 for( i = 0; i < nDPCount; ++i )
196 if( nPageToExport != -1 && nPageToExport == i )
198 uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), uno::UNO_QUERY );
199 mSelectedPages[0] = xDrawPage;
201 else
203 uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), uno::UNO_QUERY );
204 mSelectedPages[i] = xDrawPage;
212 * We get all master page that are targeted by at least one draw page.
213 * The master page are put in an unordered set.
215 ObjectSet aMasterPageTargetSet;
216 for( sal_Int32 i = 0; i < mSelectedPages.getLength(); ++i )
218 uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( mSelectedPages[i], uno::UNO_QUERY );
219 if( xMasterPageTarget.is() )
221 aMasterPageTargetSet.insert( xMasterPageTarget->getMasterPage() );
224 // Later we move them to a uno::Sequence so we can get them by index
225 mMasterPageTargets.realloc( aMasterPageTargetSet.size() );
226 ObjectSet::const_iterator aElem = aMasterPageTargetSet.begin();
227 for( sal_Int32 i = 0; aElem != aMasterPageTargetSet.end(); ++aElem, ++i)
229 uno::Reference< drawing::XDrawPage > xMasterPage( *aElem, uno::UNO_QUERY );
230 mMasterPageTargets[i] = xMasterPage;
233 bRet = implExport( rDescriptor );
235 #endif
236 else
237 bRet = sal_False;
239 if( pFocusWindow )
240 pFocusWindow->LeaveWait();
242 return bRet;
245 // -----------------------------------------------------------------------------
247 void SAL_CALL SVGFilter::cancel( ) throw (RuntimeException)
251 // -----------------------------------------------------------------------------
253 void SAL_CALL SVGFilter::setSourceDocument( const Reference< XComponent >& xDoc )
254 throw (IllegalArgumentException, RuntimeException)
256 mxSrcDoc = xDoc;
259 // -----------------------------------------------------------------------------
261 void SAL_CALL SVGFilter::setTargetDocument( const Reference< XComponent >& xDoc )
262 throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
264 mxDstDoc = xDoc;
267 // -----------------------------------------------------------------------------
269 OUString SAL_CALL SVGFilter::detect( Sequence< PropertyValue >& io_rDescriptor ) throw (RuntimeException)
271 uno::Reference< io::XInputStream > xInput;
273 const beans::PropertyValue* pAttribs = io_rDescriptor.getConstArray();
274 const sal_Int32 nAttribs = io_rDescriptor.getLength();
275 for( sal_Int32 i = 0; i < nAttribs; i++ )
277 if ( pAttribs[i].Name == "InputStream" )
278 pAttribs[i].Value >>= xInput;
281 if( !xInput.is() )
282 return OUString();
284 uno::Reference< io::XSeekable > xSeek( xInput, uno::UNO_QUERY );
285 if( xSeek.is() )
286 xSeek->seek( 0 );
288 // read the first 1024 bytes & check a few magic string
289 // constants (heuristically)
290 const sal_Int32 nLookAhead = 1024;
291 uno::Sequence< sal_Int8 > aBuf( nLookAhead );
292 const sal_uInt64 nBytes=xInput->readBytes(aBuf, nLookAhead);
293 const sal_Int8* const pBuf=aBuf.getConstArray();
295 sal_Int8 aMagic1[] = {'<', 's', 'v', 'g'};
296 if( std::search(pBuf, pBuf+nBytes,
297 aMagic1, aMagic1+sizeof(aMagic1)/sizeof(*aMagic1)) != pBuf+nBytes )
298 return OUString("svg_Scalable_Vector_Graphics");
300 sal_Int8 aMagic2[] = {'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ', 's', 'v', 'g'};
301 if( std::search(pBuf, pBuf+nBytes,
302 aMagic2, aMagic2+sizeof(aMagic2)/sizeof(*aMagic2)) != pBuf+nBytes )
303 return OUString("svg_Scalable_Vector_Graphics");
305 return OUString();
308 // -----------------------------------------------------------------------------
310 #define SVG_FILTER_IMPL_NAME "com.sun.star.comp.Draw.SVGFilter"
311 #define SVG_WRITER_IMPL_NAME "com.sun.star.comp.Draw.SVGWriter"
313 namespace sdecl = comphelper::service_decl;
314 sdecl::class_<SVGFilter> serviceFilterImpl;
315 const sdecl::ServiceDecl svgFilter(
316 serviceFilterImpl,
317 SVG_FILTER_IMPL_NAME,
318 "com.sun.star.document.ImportFilter;"
319 "com.sun.star.document.ExportFilter;"
320 "com.sun.star.document.ExtendedTypeDetection" );
322 sdecl::class_<SVGWriter> serviceWriterImpl;
323 const sdecl::ServiceDecl svgWriter(
324 serviceWriterImpl,
325 SVG_WRITER_IMPL_NAME,
326 "com.sun.star.svg.SVGWriter" );
328 // The C shared lib entry points
329 extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL svgfilter_component_getFactory(
330 sal_Char const* pImplName,
331 ::com::sun::star::lang::XMultiServiceFactory* pServiceManager,
332 ::com::sun::star::registry::XRegistryKey* pRegistryKey )
334 if ( rtl_str_compare (pImplName, SVG_FILTER_IMPL_NAME) == 0 )
336 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, svgFilter );
338 else if ( rtl_str_compare (pImplName, SVG_WRITER_IMPL_NAME) == 0 )
340 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, svgWriter );
342 return NULL;
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */