1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
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"
29 namespace oox
{ namespace shape
{
31 using namespace ::com::sun::star
;
33 using namespace drawingml
;
35 OUString SAL_CALL
ShapeContextHandler_getImplementationName()
37 return OUString( "com.sun.star.comp.oox.ShapeContextHandler" );
40 uno::Sequence
< OUString
> SAL_CALL
41 ShapeContextHandler_getSupportedServiceNames()
43 uno::Sequence
< OUString
> s(1);
44 s
[0] = "com.sun.star.xml.sax.FastShapeContextHandler";
48 uno::Reference
< uno::XInterface
> SAL_CALL
49 ShapeContextHandler_createInstance( const uno::Reference
< uno::XComponentContext
> & context
)
50 SAL_THROW((uno::Exception
))
52 return static_cast< ::cppu::OWeakObject
* >( new ShapeContextHandler(context
) );
56 ShapeContextHandler::ShapeContextHandler
57 (uno::Reference
< uno::XComponentContext
> const & context
) :
58 mnStartToken(0), m_xContext(context
)
62 mxFilterBase
.set( new ShapeFilterBase(context
) );
64 catch( uno::Exception
& )
69 ShapeContextHandler::~ShapeContextHandler()
73 uno::Reference
<xml::sax::XFastContextHandler
> ShapeContextHandler::getLockedCanvasContext(sal_Int32 nElement
)
75 if (!mxLockedCanvasContext
.is())
77 FragmentHandlerRef
rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase
, msRelationFragmentPath
));
78 ShapePtr pMasterShape
;
80 switch (nElement
& 0xffff)
82 case XML_lockedCanvas
:
83 mxLockedCanvasContext
.set(new LockedCanvasContext(*rFragmentHandler
));
90 return mxLockedCanvasContext
;
93 uno::Reference
<xml::sax::XFastContextHandler
>
94 ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element
)
96 if (! mxGraphicShapeContext
.is())
98 FragmentHandlerRef rFragmentHandler
99 (new ShapeFragmentHandler(*mxFilterBase
, msRelationFragmentPath
));
100 ShapePtr pMasterShape
;
102 switch (Element
& 0xffff)
105 mpShape
.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
106 mxGraphicShapeContext
.set
107 (new GraphicalObjectFrameContext(*rFragmentHandler
, pMasterShape
, mpShape
, true));
110 mpShape
.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
111 mxGraphicShapeContext
.set
112 (new GraphicShapeContext(*rFragmentHandler
, pMasterShape
, mpShape
));
119 return mxGraphicShapeContext
;
122 uno::Reference
<xml::sax::XFastContextHandler
>
123 ShapeContextHandler::getDrawingShapeContext()
125 if (!mxDrawingFragmentHandler
.is())
127 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 ( *mxFilterBase
, msRelationFragmentPath
, *mpDrawing
)));
134 return mxDrawingFragmentHandler
;
137 uno::Reference
<xml::sax::XFastContextHandler
>
138 ShapeContextHandler::getDiagramShapeContext()
140 if (!mxDiagramShapeContext
.is())
142 FragmentHandlerRef
rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase
, msRelationFragmentPath
));
143 mpShape
.reset(new Shape());
144 mxDiagramShapeContext
.set(new DiagramGraphicDataContext(*rFragmentHandler
, mpShape
));
147 return mxDiagramShapeContext
;
150 uno::Reference
<xml::sax::XFastContextHandler
>
151 ShapeContextHandler::getContextHandler()
153 uno::Reference
<xml::sax::XFastContextHandler
> xResult
;
155 switch (getNamespace( mnStartToken
))
159 xResult
.set(getDrawingShapeContext());
161 case NMSP_dmlDiagram
:
162 xResult
.set(getDiagramShapeContext());
164 case NMSP_dmlLockedCanvas
:
165 xResult
.set(getLockedCanvasContext(mnStartToken
));
168 xResult
.set(getGraphicShapeContext(mnStartToken
));
175 // ::com::sun::star::xml::sax::XFastContextHandler:
176 void SAL_CALL
ShapeContextHandler::startFastElement
177 (::sal_Int32 Element
,
178 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
179 throw (uno::RuntimeException
, xml::sax::SAXException
)
181 static const OUString sInputStream
184 uno::Sequence
<beans::PropertyValue
> aSeq(1);
185 aSeq
[0].Name
= sInputStream
;
186 aSeq
[0].Value
<<= mxInputStream
;
187 mxFilterBase
->filter(aSeq
);
189 mpThemePtr
.reset(new Theme());
191 if (Element
== DGM_TOKEN(relIds
) || Element
== LC_TOKEN(lockedCanvas
))
193 // Parse the theme relation, if available; the diagram won't have colors without it.
194 if (!msRelationFragmentPath
.isEmpty())
196 FragmentHandlerRef
rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase
, msRelationFragmentPath
));
197 OUString aThemeFragmentPath
= rFragmentHandler
->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) );
198 uno::Reference
<xml::sax::XFastSAXSerializable
> xDoc(mxFilterBase
->importFragment(aThemeFragmentPath
), uno::UNO_QUERY_THROW
);
199 mxFilterBase
->importFragment(new ThemeFragmentHandler(*mxFilterBase
, aThemeFragmentPath
, *mpThemePtr
), xDoc
);
200 ShapeFilterBase
* pShapeFilterBase(dynamic_cast<ShapeFilterBase
*>(mxFilterBase
.get()));
201 if (pShapeFilterBase
)
202 pShapeFilterBase
->setCurrentTheme(mpThemePtr
);
205 createFastChildContext(Element
, Attribs
);
208 // Entering VML block (startFastElement() is called for the outermost tag),
209 // handle possible recursion.
210 if ( getContextHandler() == getDrawingShapeContext() )
211 mpDrawing
->getShapes().pushMark();
213 uno::Reference
<XFastContextHandler
> xContextHandler(getContextHandler());
215 if (xContextHandler
.is())
216 xContextHandler
->startFastElement(Element
, Attribs
);
219 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
)
224 if ( getContextHandler() == getDrawingShapeContext() )
225 mpDrawing
->getShapes().pushMark();
227 uno::Reference
<XFastContextHandler
> xContextHandler(getContextHandler());
229 if (xContextHandler
.is())
230 xContextHandler
->startUnknownElement(Namespace
, Name
, Attribs
);
233 void SAL_CALL
ShapeContextHandler::endFastElement(::sal_Int32 Element
)
234 throw (uno::RuntimeException
, xml::sax::SAXException
)
236 uno::Reference
<XFastContextHandler
> xContextHandler(getContextHandler());
238 if (xContextHandler
.is())
239 xContextHandler
->endFastElement(Element
);
242 void SAL_CALL
ShapeContextHandler::endUnknownElement
243 (const OUString
& Namespace
,
244 const OUString
& Name
)
245 throw (uno::RuntimeException
, xml::sax::SAXException
)
247 uno::Reference
<XFastContextHandler
> xContextHandler(getContextHandler());
249 if (xContextHandler
.is())
250 xContextHandler
->endUnknownElement(Namespace
, Name
);
253 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
254 ShapeContextHandler::createFastChildContext
255 (::sal_Int32 Element
,
256 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
257 throw (uno::RuntimeException
, xml::sax::SAXException
)
259 uno::Reference
< xml::sax::XFastContextHandler
> xResult
;
260 uno::Reference
< xml::sax::XFastContextHandler
> xContextHandler(getContextHandler());
262 if (xContextHandler
.is())
263 xResult
.set(xContextHandler
->createFastChildContext
269 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
270 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
)
276 uno::Reference
<XFastContextHandler
> xContextHandler(getContextHandler());
278 if (xContextHandler
.is())
279 return xContextHandler
->createUnknownChildContext
280 (Namespace
, Name
, Attribs
);
282 return uno::Reference
< xml::sax::XFastContextHandler
>();
285 void SAL_CALL
ShapeContextHandler::characters(const OUString
& aChars
)
286 throw (uno::RuntimeException
, xml::sax::SAXException
)
288 uno::Reference
<XFastContextHandler
> xContextHandler(getContextHandler());
290 if (xContextHandler
.is())
291 xContextHandler
->characters(aChars
);
294 // ::com::sun::star::xml::sax::XFastShapeContextHandler:
295 uno::Reference
< drawing::XShape
> SAL_CALL
296 ShapeContextHandler::getShape() throw (uno::RuntimeException
)
298 uno::Reference
< drawing::XShape
> xResult
;
299 uno::Reference
< drawing::XShapes
> xShapes( mxDrawPage
, uno::UNO_QUERY
);
301 if (mxFilterBase
.is() && xShapes
.is())
303 if ( getContextHandler() == getDrawingShapeContext() )
305 mpDrawing
->finalizeFragmentImport();
306 if( boost::shared_ptr
< vml::ShapeBase
> pShape
= mpDrawing
->getShapes().takeLastShape() )
307 xResult
= pShape
->convertAndInsert( xShapes
);
308 // Only now remove the recursion mark, because getShape() is called in writerfilter
309 // after endFastElement().
310 mpDrawing
->getShapes().popMark();
312 else if (mxDiagramShapeContext
.is())
314 basegfx::B2DHomMatrix aMatrix
;
315 if (mpShape
->getExtDrawings().size() == 0)
317 mpShape
->addShape( *mxFilterBase
, mpThemePtr
.get(), xShapes
, aMatrix
, mpShape
->getFillProperties() );
318 xResult
= mpShape
->getXShape();
322 // Prerendered diagram output is available, then use that, and throw away the original result.
323 for (std::vector
<OUString
>::const_iterator aIt
= mpShape
->getExtDrawings().begin(); aIt
!= mpShape
->getExtDrawings().end(); ++aIt
)
325 DiagramGraphicDataContext
* pDiagramGraphicDataContext
= dynamic_cast<DiagramGraphicDataContext
*>(mxDiagramShapeContext
.get());
326 OUString
aFragmentPath(pDiagramGraphicDataContext
->getFragmentPathFromRelId(*aIt
));
327 oox::drawingml::ShapePtr
pShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) );
328 mxFilterBase
->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase
, aFragmentPath
, pShapePtr
));
329 pShapePtr
->addShape( *mxFilterBase
, mpThemePtr
.get(), xShapes
, aMatrix
, pShapePtr
->getFillProperties() );
330 xResult
= pShapePtr
->getXShape();
332 mpShape
.reset((Shape
*)0);
334 mxDiagramShapeContext
.clear();
336 else if (mxLockedCanvasContext
.is())
338 ShapePtr pShape
= dynamic_cast<LockedCanvasContext
*>(mxLockedCanvasContext
.get())->getShape();
341 basegfx::B2DHomMatrix aMatrix
;
342 pShape
->addShape(*mxFilterBase
, mpThemePtr
.get(), xShapes
, aMatrix
, pShape
->getFillProperties());
343 xResult
= pShape
->getXShape();
344 mxLockedCanvasContext
.clear();
347 else if (mpShape
.get() != NULL
)
349 basegfx::B2DHomMatrix aTransformation
;
350 mpShape
->addShape(*mxFilterBase
, mpThemePtr
.get(), xShapes
, aTransformation
, mpShape
->getFillProperties() );
351 xResult
.set(mpShape
->getXShape());
352 mxGraphicShapeContext
.clear( );
359 css::uno::Reference
< css::drawing::XDrawPage
> SAL_CALL
360 ShapeContextHandler::getDrawPage() throw (css::uno::RuntimeException
)
365 void SAL_CALL
ShapeContextHandler::setDrawPage
366 (const css::uno::Reference
< css::drawing::XDrawPage
> & the_value
)
367 throw (css::uno::RuntimeException
)
369 mxDrawPage
= the_value
;
372 css::uno::Reference
< css::frame::XModel
> SAL_CALL
373 ShapeContextHandler::getModel() throw (css::uno::RuntimeException
)
375 if( !mxFilterBase
.is() )
376 throw uno::RuntimeException();
377 return mxFilterBase
->getModel();
380 void SAL_CALL
ShapeContextHandler::setModel
381 (const css::uno::Reference
< css::frame::XModel
> & the_value
)
382 throw (css::uno::RuntimeException
)
384 if( !mxFilterBase
.is() )
385 throw uno::RuntimeException();
386 uno::Reference
<lang::XComponent
> xComp(the_value
, uno::UNO_QUERY_THROW
);
387 mxFilterBase
->setTargetDocument(xComp
);
390 uno::Reference
< io::XInputStream
> SAL_CALL
391 ShapeContextHandler::getInputStream() throw (uno::RuntimeException
)
393 return mxInputStream
;
396 void SAL_CALL
ShapeContextHandler::setInputStream
397 (const uno::Reference
< io::XInputStream
> & the_value
)
398 throw (uno::RuntimeException
)
400 mxInputStream
= the_value
;
403 OUString SAL_CALL
ShapeContextHandler::getRelationFragmentPath()
404 throw (uno::RuntimeException
)
406 return msRelationFragmentPath
;
409 void SAL_CALL
ShapeContextHandler::setRelationFragmentPath
410 (const OUString
& the_value
)
411 throw (uno::RuntimeException
)
413 msRelationFragmentPath
= the_value
;
416 ::sal_Int32 SAL_CALL
ShapeContextHandler::getStartToken() throw (::com::sun::star::uno::RuntimeException
)
421 void SAL_CALL
ShapeContextHandler::setStartToken( ::sal_Int32 _starttoken
) throw (::com::sun::star::uno::RuntimeException
)
423 mnStartToken
= _starttoken
;
428 OUString
ShapeContextHandler::getImplementationName()
429 throw (css::uno::RuntimeException
)
431 return ShapeContextHandler_getImplementationName();
434 uno::Sequence
< OUString
> ShapeContextHandler::getSupportedServiceNames()
435 throw (css::uno::RuntimeException
)
437 return ShapeContextHandler_getSupportedServiceNames();
440 ::sal_Bool SAL_CALL
ShapeContextHandler::supportsService
441 (const OUString
& ServiceName
) throw (css::uno::RuntimeException
)
443 uno::Sequence
< OUString
> aSeq
= getSupportedServiceNames();
445 if (aSeq
[0].equals(ServiceName
))
453 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */