Branch data 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 <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
21 : :
22 : : #include "ShapeContextHandler.hxx"
23 : : #include "ShapeDrawingFragmentHandler.hxx"
24 : : #include "oox/vml/vmldrawingfragment.hxx"
25 : : #include "oox/vml/vmlshape.hxx"
26 : : #include "oox/drawingml/themefragmenthandler.hxx"
27 : :
28 : : namespace oox { namespace shape {
29 : :
30 : : using namespace ::com::sun::star;
31 : : using namespace core;
32 : : using namespace drawingml;
33 : :
34 : 43 : ::rtl::OUString SAL_CALL ShapeContextHandler_getImplementationName()
35 : : {
36 : 43 : return CREATE_OUSTRING( "com.sun.star.comp.oox.ShapeContextHandler" );
37 : : }
38 : :
39 : : uno::Sequence< ::rtl::OUString > SAL_CALL
40 : 3 : ShapeContextHandler_getSupportedServiceNames()
41 : : {
42 : 3 : uno::Sequence< ::rtl::OUString > s(1);
43 [ + - ][ + - ]: 3 : s[0] = CREATE_OUSTRING( "com.sun.star.xml.sax.FastShapeContextHandler" );
44 : 3 : return s;
45 : : }
46 : :
47 : : uno::Reference< uno::XInterface > SAL_CALL
48 : 33 : ShapeContextHandler_createInstance( const uno::Reference< uno::XComponentContext > & context)
49 : : SAL_THROW((uno::Exception))
50 : : {
51 [ + - ]: 33 : return static_cast< ::cppu::OWeakObject* >( new ShapeContextHandler(context) );
52 : : }
53 : :
54 : :
55 : 33 : ShapeContextHandler::ShapeContextHandler
56 : : (uno::Reference< uno::XComponentContext > const & context) :
57 [ + - ][ + - ]: 33 : mnStartToken(0), m_xContext(context)
[ + - ]
58 : : {
59 : : try
60 : : {
61 [ # # ][ + - ]: 33 : mxFilterBase.set( new ShapeFilterBase(context) );
62 : : }
63 [ # # ]: 0 : catch( uno::Exception& )
64 : : {
65 : : }
66 : 33 : }
67 : :
68 [ + - ][ + - ]: 33 : ShapeContextHandler::~ShapeContextHandler()
[ + - ]
69 : : {
70 [ - + ]: 66 : }
71 : :
72 : : uno::Reference<xml::sax::XFastContextHandler>
73 : 84 : ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
74 : : {
75 [ + + ]: 84 : if (! mxGraphicShapeContext.is())
76 : : {
77 : : FragmentHandlerRef rFragmentHandler
78 [ + - ]: 12 : (new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
79 [ + - ]: 12 : ShapePtr pMasterShape;
80 : :
81 [ - + - ]: 12 : switch (Element & 0xffff)
82 : : {
83 : : case XML_graphic:
84 [ # # ][ # # ]: 0 : mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
[ # # ]
85 : : mxGraphicShapeContext.set
86 [ # # ][ # # ]: 0 : (new GraphicalObjectFrameContext(*rFragmentHandler, pMasterShape, mpShape, true));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
87 : 0 : break;
88 : : case XML_pic:
89 [ + - ][ + - ]: 12 : mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
[ + - ]
90 : : mxGraphicShapeContext.set
91 [ + - ][ + - ]: 12 : (new GraphicShapeContext(*rFragmentHandler, pMasterShape, mpShape));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
92 : 12 : break;
93 : : default:
94 : 0 : break;
95 [ + - ]: 12 : }
96 : : }
97 : :
98 : 84 : return mxGraphicShapeContext;
99 : : }
100 : :
101 : : uno::Reference<xml::sax::XFastContextHandler>
102 : 525 : ShapeContextHandler::getDrawingShapeContext()
103 : : {
104 [ + + ]: 525 : if (!mxDrawingFragmentHandler.is())
105 : : {
106 [ + - ]: 33 : mpDrawing.reset( new oox::vml::Drawing( *mxFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD ) );
107 : : mxDrawingFragmentHandler.set
108 : : (dynamic_cast<ContextHandler *>
109 : : (new oox::vml::DrawingFragment
110 [ + - ][ + - ]: 33 : ( *mxFilterBase, msRelationFragmentPath, *mpDrawing )));
111 : : }
112 : :
113 : 525 : return mxDrawingFragmentHandler;
114 : : }
115 : :
116 : : uno::Reference<xml::sax::XFastContextHandler>
117 : 15 : ShapeContextHandler::getDiagramShapeContext()
118 : : {
119 [ + + ]: 15 : if (!mxDiagramShapeContext.is())
120 : : {
121 [ + - ]: 3 : FragmentHandlerRef rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
122 [ + - ][ + - ]: 3 : mpShape.reset(new Shape());
[ + - ]
123 [ + - ][ + - ]: 3 : mxDiagramShapeContext.set(new DiagramGraphicDataContext(*rFragmentHandler, mpShape));
[ + - ][ + - ]
[ + - ]
124 : : }
125 : :
126 : 15 : return mxDiagramShapeContext;
127 : : }
128 : :
129 : : uno::Reference<xml::sax::XFastContextHandler>
130 : 510 : ShapeContextHandler::getContextHandler()
131 : : {
132 : 510 : uno::Reference<xml::sax::XFastContextHandler> xResult;
133 : :
134 [ + + + ]: 510 : switch (getNamespace( mnStartToken ))
135 : : {
136 : : case NMSP_doc:
137 : : case NMSP_vml:
138 [ + - ][ + - ]: 411 : xResult.set(getDrawingShapeContext());
139 : 411 : break;
140 : : case NMSP_dmlDiagram:
141 [ + - ][ + - ]: 15 : xResult.set(getDiagramShapeContext());
142 : 15 : break;
143 : : default:
144 [ + - ][ + - ]: 84 : xResult.set(getGraphicShapeContext(mnStartToken));
145 : 84 : break;
146 : : }
147 : :
148 : 510 : return xResult;
149 : : }
150 : :
151 : : // ::com::sun::star::xml::sax::XFastContextHandler:
152 : 57 : void SAL_CALL ShapeContextHandler::startFastElement
153 : : (::sal_Int32 Element,
154 : : const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
155 : : throw (uno::RuntimeException, xml::sax::SAXException)
156 : : {
157 : : static const ::rtl::OUString sInputStream
158 [ + + ][ + - ]: 57 : (RTL_CONSTASCII_USTRINGPARAM ("InputStream"));
[ + - ][ # # ]
159 : :
160 [ + - ]: 57 : uno::Sequence<beans::PropertyValue> aSeq(1);
161 [ + - ]: 57 : aSeq[0].Name = sInputStream;
162 [ + - ][ + - ]: 57 : aSeq[0].Value <<= mxInputStream;
163 [ + - ]: 57 : mxFilterBase->filter(aSeq);
164 : :
165 [ + - ][ + - ]: 57 : mpThemePtr.reset(new Theme());
[ + - ]
166 : :
167 [ + + ]: 57 : if (Element == DGM_TOKEN(relIds))
168 : : {
169 : : // Parse the theme relation, if available; the diagram won't have colors without it.
170 [ + - ]: 3 : if (!msRelationFragmentPath.isEmpty())
171 : : {
172 [ + - ]: 3 : FragmentHandlerRef rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
173 [ + - ][ + - ]: 3 : rtl::OUString aThemeFragmentPath = rFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) );
174 [ + - ][ + - ]: 3 : uno::Reference<xml::sax::XFastSAXSerializable> xDoc(mxFilterBase->importFragment(aThemeFragmentPath), uno::UNO_QUERY_THROW);
175 [ + - ][ + - ]: 3 : mxFilterBase->importFragment(new ThemeFragmentHandler(*mxFilterBase, aThemeFragmentPath, *mpThemePtr ), xDoc);
176 [ - + ]: 3 : ShapeFilterBase* pShapeFilterBase(dynamic_cast<ShapeFilterBase*>(mxFilterBase.get()));
177 [ + - ]: 3 : if (pShapeFilterBase)
178 [ + - ][ + - ]: 3 : pShapeFilterBase->setCurrentTheme(mpThemePtr);
[ + - ]
179 : : }
180 : :
181 [ + - ]: 3 : createFastChildContext(Element, Attribs);
182 : : }
183 : :
184 : : // Entering VML block (startFastElement() is called for the outermost tag),
185 : : // handle possible recursion.
186 [ + - ][ + - ]: 57 : if ( getContextHandler() == getDrawingShapeContext() )
[ + - ][ + + ]
187 [ + - ]: 42 : mpDrawing->getShapes().pushMark();
188 : :
189 [ + - ]: 57 : uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
190 : :
191 [ + - ]: 57 : if (xContextHandler.is())
192 [ + - ][ + - ]: 57 : xContextHandler->startFastElement(Element, Attribs);
[ + - ]
193 : 57 : }
194 : :
195 : 0 : void SAL_CALL ShapeContextHandler::startUnknownElement
196 : : (const ::rtl::OUString & Namespace, const ::rtl::OUString & Name,
197 : : const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
198 : : throw (uno::RuntimeException, xml::sax::SAXException)
199 : : {
200 [ # # ][ # # ]: 0 : if ( getContextHandler() == getDrawingShapeContext() )
[ # # ][ # # ]
201 [ # # ]: 0 : mpDrawing->getShapes().pushMark();
202 : :
203 [ # # ]: 0 : uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
204 : :
205 [ # # ]: 0 : if (xContextHandler.is())
206 [ # # ][ # # ]: 0 : xContextHandler->startUnknownElement(Namespace, Name, Attribs);
207 : 0 : }
208 : :
209 : 57 : void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
210 : : throw (uno::RuntimeException, xml::sax::SAXException)
211 : : {
212 [ + - ]: 57 : uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
213 : :
214 [ + - ]: 57 : if (xContextHandler.is())
215 [ + - ][ + - ]: 57 : xContextHandler->endFastElement(Element);
216 : 57 : }
217 : :
218 : 0 : void SAL_CALL ShapeContextHandler::endUnknownElement
219 : : (const ::rtl::OUString & Namespace,
220 : : const ::rtl::OUString & Name)
221 : : throw (uno::RuntimeException, xml::sax::SAXException)
222 : : {
223 [ # # ]: 0 : uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
224 : :
225 [ # # ]: 0 : if (xContextHandler.is())
226 [ # # ][ # # ]: 0 : xContextHandler->endUnknownElement(Namespace, Name);
227 : 0 : }
228 : :
229 : : uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
230 : 102 : ShapeContextHandler::createFastChildContext
231 : : (::sal_Int32 Element,
232 : : const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
233 : : throw (uno::RuntimeException, xml::sax::SAXException)
234 : : {
235 : 102 : uno::Reference< xml::sax::XFastContextHandler > xResult;
236 [ + - ]: 102 : uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler());
237 : :
238 [ + - ]: 102 : if (xContextHandler.is())
239 [ + - ]: 102 : xResult.set(xContextHandler->createFastChildContext
240 [ + - ][ + - ]: 102 : (Element, Attribs));
241 : :
242 : 102 : return xResult;
243 : : }
244 : :
245 : : uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
246 : 0 : ShapeContextHandler::createUnknownChildContext
247 : : (const ::rtl::OUString & Namespace,
248 : : const ::rtl::OUString & Name,
249 : : const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
250 : : throw (uno::RuntimeException, xml::sax::SAXException)
251 : : {
252 [ # # ]: 0 : uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
253 : :
254 [ # # ]: 0 : if (xContextHandler.is())
255 [ # # ]: 0 : return xContextHandler->createUnknownChildContext
256 [ # # ]: 0 : (Namespace, Name, Attribs);
257 : :
258 : 0 : return uno::Reference< xml::sax::XFastContextHandler >();
259 : : }
260 : :
261 : 180 : void SAL_CALL ShapeContextHandler::characters(const ::rtl::OUString & aChars)
262 : : throw (uno::RuntimeException, xml::sax::SAXException)
263 : : {
264 [ + - ]: 180 : uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
265 : :
266 [ + - ]: 180 : if (xContextHandler.is())
267 [ + - ][ + - ]: 180 : xContextHandler->characters(aChars);
268 : 180 : }
269 : :
270 : : // ::com::sun::star::xml::sax::XFastShapeContextHandler:
271 : : uno::Reference< drawing::XShape > SAL_CALL
272 : 57 : ShapeContextHandler::getShape() throw (uno::RuntimeException)
273 : : {
274 : 57 : uno::Reference< drawing::XShape > xResult;
275 [ + - ]: 57 : uno::Reference< drawing::XShapes > xShapes( mxDrawPage, uno::UNO_QUERY );
276 : :
277 [ + - ][ + - ]: 57 : if (mxFilterBase.is() && xShapes.is())
[ + - ]
278 : : {
279 [ + - ][ + - ]: 57 : if ( getContextHandler() == getDrawingShapeContext() )
[ + - ][ + + ]
280 : : {
281 [ + - ]: 42 : mpDrawing->finalizeFragmentImport();
282 [ + - ][ + + ]: 42 : if( boost::shared_ptr< vml::ShapeBase > pShape = mpDrawing->getShapes().takeLastShape() )
283 [ + - ][ + - ]: 42 : xResult = pShape->convertAndInsert( xShapes );
[ + - ]
284 : : // Only now remove the recursion mark, because getShape() is called in writerfilter
285 : : // after endFastElement().
286 [ + - ]: 42 : mpDrawing->getShapes().popMark();
287 : : }
288 [ + + ]: 15 : else if (mxDiagramShapeContext.is())
289 : : {
290 [ + - ]: 3 : basegfx::B2DHomMatrix aMatrix;
291 [ - + ]: 3 : if (mpShape->getExtDrawings().size() == 0)
292 : : {
293 [ # # ]: 0 : mpShape->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix );
294 [ # # ]: 0 : xResult = mpShape->getXShape();
295 : : }
296 : : else
297 : : {
298 : : // Prerendered diagram output is available, then use that, and throw away the original result.
299 [ + - ][ + + ]: 6 : for (std::vector<rtl::OUString>::const_iterator aIt = mpShape->getExtDrawings().begin(); aIt != mpShape->getExtDrawings().end(); ++aIt)
300 : : {
301 [ + - ][ - + ]: 3 : DiagramGraphicDataContext* pDiagramGraphicDataContext = dynamic_cast<DiagramGraphicDataContext*>(mxDiagramShapeContext.get());
302 [ + - ]: 3 : rtl::OUString aFragmentPath(pDiagramGraphicDataContext->getFragmentPathFromRelId(*aIt));
303 [ + - ][ + - ]: 3 : oox::drawingml::ShapePtr pShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) );
[ + - ]
304 [ + - ][ + - ]: 3 : mxFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase, aFragmentPath, pShapePtr));
[ + - ]
305 [ + - ]: 3 : pShapePtr->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix );
306 [ + - ]: 3 : xResult = pShapePtr->getXShape();
307 [ + - ]: 3 : }
308 [ + - ]: 3 : mpShape.reset((Shape*)0);
309 : : }
310 [ + - ]: 3 : mxDiagramShapeContext.clear();
311 : : }
312 [ + - ]: 12 : else if (mpShape.get() != NULL)
313 : : {
314 [ + - ]: 12 : basegfx::B2DHomMatrix aTransformation;
315 [ + - ]: 12 : mpShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aTransformation);
316 [ + - ]: 12 : xResult.set(mpShape->getXShape());
317 [ + - ]: 12 : mxGraphicShapeContext.clear( );
318 : : }
319 : : }
320 : :
321 : 57 : return xResult;
322 : : }
323 : :
324 : : css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
325 : 0 : ShapeContextHandler::getDrawPage() throw (css::uno::RuntimeException)
326 : : {
327 : 0 : return mxDrawPage;
328 : : }
329 : :
330 : 57 : void SAL_CALL ShapeContextHandler::setDrawPage
331 : : (const css::uno::Reference< css::drawing::XDrawPage > & the_value)
332 : : throw (css::uno::RuntimeException)
333 : : {
334 : 57 : mxDrawPage = the_value;
335 : 57 : }
336 : :
337 : : css::uno::Reference< css::frame::XModel > SAL_CALL
338 : 0 : ShapeContextHandler::getModel() throw (css::uno::RuntimeException)
339 : : {
340 [ # # ]: 0 : if( !mxFilterBase.is() )
341 [ # # ]: 0 : throw uno::RuntimeException();
342 : 0 : return mxFilterBase->getModel();
343 : : }
344 : :
345 : 57 : void SAL_CALL ShapeContextHandler::setModel
346 : : (const css::uno::Reference< css::frame::XModel > & the_value)
347 : : throw (css::uno::RuntimeException)
348 : : {
349 [ - + ]: 57 : if( !mxFilterBase.is() )
350 [ # # ]: 0 : throw uno::RuntimeException();
351 [ + - ]: 57 : uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
352 [ + - ]: 57 : mxFilterBase->setTargetDocument(xComp);
353 : 57 : }
354 : :
355 : : uno::Reference< io::XInputStream > SAL_CALL
356 : 0 : ShapeContextHandler::getInputStream() throw (uno::RuntimeException)
357 : : {
358 : 0 : return mxInputStream;
359 : : }
360 : :
361 : 57 : void SAL_CALL ShapeContextHandler::setInputStream
362 : : (const uno::Reference< io::XInputStream > & the_value)
363 : : throw (uno::RuntimeException)
364 : : {
365 : 57 : mxInputStream = the_value;
366 : 57 : }
367 : :
368 : 0 : ::rtl::OUString SAL_CALL ShapeContextHandler::getRelationFragmentPath()
369 : : throw (uno::RuntimeException)
370 : : {
371 : 0 : return msRelationFragmentPath;
372 : : }
373 : :
374 : 57 : void SAL_CALL ShapeContextHandler::setRelationFragmentPath
375 : : (const ::rtl::OUString & the_value)
376 : : throw (uno::RuntimeException)
377 : : {
378 : 57 : msRelationFragmentPath = the_value;
379 : 57 : }
380 : :
381 : 0 : ::sal_Int32 SAL_CALL ShapeContextHandler::getStartToken() throw (::com::sun::star::uno::RuntimeException)
382 : : {
383 : 0 : return mnStartToken;
384 : : }
385 : :
386 : 57 : void SAL_CALL ShapeContextHandler::setStartToken( ::sal_Int32 _starttoken ) throw (::com::sun::star::uno::RuntimeException)
387 : : {
388 : 57 : mnStartToken = _starttoken;
389 : :
390 : :
391 : 57 : }
392 : :
393 : 0 : ::rtl::OUString ShapeContextHandler::getImplementationName()
394 : : throw (css::uno::RuntimeException)
395 : : {
396 : 0 : return ShapeContextHandler_getImplementationName();
397 : : }
398 : :
399 : 0 : uno::Sequence< ::rtl::OUString > ShapeContextHandler::getSupportedServiceNames()
400 : : throw (css::uno::RuntimeException)
401 : : {
402 : 0 : return ShapeContextHandler_getSupportedServiceNames();
403 : : }
404 : :
405 : 0 : ::sal_Bool SAL_CALL ShapeContextHandler::supportsService
406 : : (const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException)
407 : : {
408 [ # # ]: 0 : uno::Sequence< ::rtl::OUString > aSeq = getSupportedServiceNames();
409 : :
410 [ # # ][ # # ]: 0 : if (aSeq[0].equals(ServiceName))
411 : 0 : return sal_True;
412 : :
413 [ # # ]: 0 : return sal_False;
414 : : }
415 : :
416 [ + - ][ + - ]: 285 : }}
417 : :
418 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|