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