1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "ShapeContextHandler.hxx"
29 #include "oox/vml/vmldrawingfragment.hxx"
30 #include "oox/vml/vmlshape.hxx"
31 #include "oox/vml/vmlshapecontainer.hxx"
32 
33 namespace oox { namespace shape {
34 
35 using namespace ::com::sun::star;
36 using namespace core;
37 using namespace drawingml;
38 
39 ::rtl::OUString SAL_CALL ShapeContextHandler_getImplementationName()
40 {
41     return CREATE_OUSTRING( "com.sun.star.comp.oox.ShapeContextHandler" );
42 }
43 
44 uno::Sequence< ::rtl::OUString > SAL_CALL
45 ShapeContextHandler_getSupportedServiceNames()
46 {
47     uno::Sequence< ::rtl::OUString > s(1);
48     s[0] = CREATE_OUSTRING( "com.sun.star.xml.sax.FastShapeContextHandler" );
49     return s;
50 }
51 
52 uno::Reference< uno::XInterface > SAL_CALL
53 ShapeContextHandler_createInstance( const uno::Reference< uno::XComponentContext > & context)
54         SAL_THROW((uno::Exception))
55 {
56     return static_cast< ::cppu::OWeakObject* >( new ShapeContextHandler(context) );
57 }
58 
59 
60 ShapeContextHandler::ShapeContextHandler
61 (uno::Reference< uno::XComponentContext > const & context) :
62 mnStartToken(0), m_xContext(context)
63 {
64     try
65     {
66         mxFilterBase.set( new ShapeFilterBase(context) );
67     }
68     catch( uno::Exception& )
69     {
70     }
71 }
72 
73 ShapeContextHandler::~ShapeContextHandler()
74 {
75 }
76 
77 uno::Reference<xml::sax::XFastContextHandler>
78 ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
79 {
80     if (! mxGraphicShapeContext.is())
81     {
82         FragmentHandlerRef rFragmentHandler
83             (new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
84         ShapePtr pMasterShape;
85 
86         switch (Element & 0xffff)
87         {
88             case XML_graphic:
89                 mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
90                 mxGraphicShapeContext.set
91                 (new GraphicalObjectFrameContext(*rFragmentHandler, pMasterShape, mpShape, true));
92                 break;
93             case XML_pic:
94                 mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
95                 mxGraphicShapeContext.set
96                 (new GraphicShapeContext(*rFragmentHandler, pMasterShape, mpShape));
97                 break;
98             default:
99                 break;
100         }
101     }
102 
103     return mxGraphicShapeContext;
104 }
105 
106 uno::Reference<xml::sax::XFastContextHandler>
107 ShapeContextHandler::getDrawingShapeContext()
108 {
109     if (!mxDrawingFragmentHandler.is())
110     {
111         mpDrawing.reset( new oox::vml::Drawing( *mxFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD ) );
112         mxDrawingFragmentHandler.set
113           (dynamic_cast<ContextHandler *>
114            (new oox::vml::DrawingFragment
115             ( *mxFilterBase, msRelationFragmentPath, *mpDrawing )));
116     }
117 
118     return mxDrawingFragmentHandler;
119 }
120 
121 uno::Reference<xml::sax::XFastContextHandler>
122 ShapeContextHandler::getContextHandler()
123 {
124     uno::Reference<xml::sax::XFastContextHandler> xResult;
125 
126     switch (getNamespace( mnStartToken ))
127     {
128         case NMSP_doc:
129         case NMSP_vml:
130             xResult.set(getDrawingShapeContext());
131             break;
132         default:
133             xResult.set(getGraphicShapeContext(mnStartToken));
134             break;
135     }
136 
137     return xResult;
138 }
139 
140 // ::com::sun::star::xml::sax::XFastContextHandler:
141 void SAL_CALL ShapeContextHandler::startFastElement
142 (::sal_Int32 Element,
143  const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
144     throw (uno::RuntimeException, xml::sax::SAXException)
145 {
146     static const ::rtl::OUString sInputStream
147         (RTL_CONSTASCII_USTRINGPARAM ("InputStream"));
148 
149     uno::Sequence<beans::PropertyValue> aSeq(1);
150     aSeq[0].Name = sInputStream;
151     aSeq[0].Value <<= mxInputStream;
152     mxFilterBase->filter(aSeq);
153 
154     mpThemePtr.reset(new Theme());
155 
156     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
157 
158     if (xContextHandler.is())
159         xContextHandler->startFastElement(Element, Attribs);
160 }
161 
162 void SAL_CALL ShapeContextHandler::startUnknownElement
163 (const ::rtl::OUString & Namespace, const ::rtl::OUString & Name,
164  const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
165     throw (uno::RuntimeException, xml::sax::SAXException)
166 {
167     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
168 
169     if (xContextHandler.is())
170         xContextHandler->startUnknownElement(Namespace, Name, Attribs);
171 }
172 
173 void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
174     throw (uno::RuntimeException, xml::sax::SAXException)
175 {
176     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
177 
178     if (xContextHandler.is())
179         xContextHandler->endFastElement(Element);
180 }
181 
182 void SAL_CALL ShapeContextHandler::endUnknownElement
183 (const ::rtl::OUString & Namespace,
184  const ::rtl::OUString & Name)
185     throw (uno::RuntimeException, xml::sax::SAXException)
186 {
187     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
188 
189     if (xContextHandler.is())
190         xContextHandler->endUnknownElement(Namespace, Name);
191 }
192 
193 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
194 ShapeContextHandler::createFastChildContext
195 (::sal_Int32 Element,
196  const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
197     throw (uno::RuntimeException, xml::sax::SAXException)
198 {
199     uno::Reference< xml::sax::XFastContextHandler > xResult;
200     uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler());
201 
202     if (xContextHandler.is())
203         xResult.set(xContextHandler->createFastChildContext
204                     (Element, Attribs));
205 
206     return xResult;
207 }
208 
209 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
210 ShapeContextHandler::createUnknownChildContext
211 (const ::rtl::OUString & Namespace,
212  const ::rtl::OUString & Name,
213  const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
214     throw (uno::RuntimeException, xml::sax::SAXException)
215 {
216     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
217 
218     if (xContextHandler.is())
219         return xContextHandler->createUnknownChildContext
220             (Namespace, Name, Attribs);
221 
222     return uno::Reference< xml::sax::XFastContextHandler >();
223 }
224 
225 void SAL_CALL ShapeContextHandler::characters(const ::rtl::OUString & aChars)
226     throw (uno::RuntimeException, xml::sax::SAXException)
227 {
228     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
229 
230     if (xContextHandler.is())
231         xContextHandler->characters(aChars);
232 }
233 
234 // ::com::sun::star::xml::sax::XFastShapeContextHandler:
235 uno::Reference< drawing::XShape > SAL_CALL
236 ShapeContextHandler::getShape() throw (uno::RuntimeException)
237 {
238     uno::Reference< drawing::XShape > xResult;
239     uno::Reference< drawing::XShapes > xShapes( mxDrawPage, uno::UNO_QUERY );
240 
241     if (mxFilterBase.is() && xShapes.is())
242     {
243         if (mpDrawing.get() != NULL)
244         {
245             mpDrawing->finalizeFragmentImport();
246             if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().getFirstShape() )
247                 xResult = pShape->convertAndInsert( xShapes );
248         }
249         else if (mpShape.get() != NULL)
250         {
251             mpShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes);
252 			xResult.set(mpShape->getXShape());
253             mxGraphicShapeContext.clear( );
254 		}
255     }
256 
257     return xResult;
258 }
259 
260 css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
261 ShapeContextHandler::getDrawPage() throw (css::uno::RuntimeException)
262 {
263     return mxDrawPage;
264 }
265 
266 void SAL_CALL ShapeContextHandler::setDrawPage
267 (const css::uno::Reference< css::drawing::XDrawPage > & the_value)
268     throw (css::uno::RuntimeException)
269 {
270     mxDrawPage = the_value;
271 }
272 
273 css::uno::Reference< css::frame::XModel > SAL_CALL
274 ShapeContextHandler::getModel() throw (css::uno::RuntimeException)
275 {
276     if( !mxFilterBase.is() )
277         throw uno::RuntimeException();
278     return mxFilterBase->getModel();
279 }
280 
281 void SAL_CALL ShapeContextHandler::setModel
282 (const css::uno::Reference< css::frame::XModel > & the_value)
283     throw (css::uno::RuntimeException)
284 {
285     if( !mxFilterBase.is() )
286         throw uno::RuntimeException();
287     uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
288     mxFilterBase->setTargetDocument(xComp);
289 }
290 
291 uno::Reference< io::XInputStream > SAL_CALL
292 ShapeContextHandler::getInputStream() throw (uno::RuntimeException)
293 {
294     return mxInputStream;
295 }
296 
297 void SAL_CALL ShapeContextHandler::setInputStream
298 (const uno::Reference< io::XInputStream > & the_value)
299     throw (uno::RuntimeException)
300 {
301     mxInputStream = the_value;
302 }
303 
304 ::rtl::OUString SAL_CALL ShapeContextHandler::getRelationFragmentPath()
305     throw (uno::RuntimeException)
306 {
307     return msRelationFragmentPath;
308 }
309 
310 void SAL_CALL ShapeContextHandler::setRelationFragmentPath
311 (const ::rtl::OUString & the_value)
312     throw (uno::RuntimeException)
313 {
314     msRelationFragmentPath = the_value;
315 }
316 
317 ::sal_Int32 SAL_CALL ShapeContextHandler::getStartToken() throw (::com::sun::star::uno::RuntimeException)
318 {
319     return mnStartToken;
320 }
321 
322 void SAL_CALL ShapeContextHandler::setStartToken( ::sal_Int32 _starttoken ) throw (::com::sun::star::uno::RuntimeException)
323 {
324     mnStartToken = _starttoken;
325 
326 
327 }
328 
329 ::rtl::OUString ShapeContextHandler::getImplementationName()
330     throw (css::uno::RuntimeException)
331 {
332     return ShapeContextHandler_getImplementationName();
333 }
334 
335 uno::Sequence< ::rtl::OUString > ShapeContextHandler::getSupportedServiceNames()
336     throw (css::uno::RuntimeException)
337 {
338     return ShapeContextHandler_getSupportedServiceNames();
339 }
340 
341 ::sal_Bool SAL_CALL ShapeContextHandler::supportsService
342 (const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException)
343 {
344     uno::Sequence< ::rtl::OUString > aSeq = getSupportedServiceNames();
345 
346     if (aSeq[0].equals(ServiceName))
347         return sal_True;
348 
349     return sal_False;
350 }
351 
352 }}
353