nss: upgrade to release 3.73
[LibreOffice.git] / xmloff / source / draw / XMLImageMapContext.cxx
blob446e3e60801a6c4cb457346fcfe85bf0cc3bef39
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 .
20 #include <XMLImageMapContext.hxx>
21 #include <rtl/ustrbuf.hxx>
22 #include <com/sun/star/uno/Reference.h>
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/beans/XPropertySetInfo.hpp>
25 #include <com/sun/star/frame/XModel.hpp>
26 #include <com/sun/star/xml/sax/XAttributeList.hpp>
27 #include <com/sun/star/container/XIndexContainer.hpp>
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 #include <com/sun/star/document/XEventsSupplier.hpp>
30 #include <com/sun/star/awt/Rectangle.hpp>
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/xmlimp.hxx>
33 #include <xmloff/xmltkmap.hxx>
34 #include <xmloff/xmlnamespace.hxx>
35 #include <xmloff/namespacemap.hxx>
36 #include <xmloff/xmluconv.hxx>
37 #include <xexptran.hxx>
38 #include <xmloff/xmlerror.hxx>
39 #include <xmloff/XMLEventsImportContext.hxx>
40 #include <XMLStringBufferImportContext.hxx>
41 #include <tools/debug.hxx>
42 #include <basegfx/polygon/b2dpolygon.hxx>
43 #include <basegfx/polygon/b2dpolygontools.hxx>
44 #include <sal/log.hxx>
46 using namespace ::com::sun::star;
47 using namespace ::xmloff::token;
49 using ::com::sun::star::beans::XPropertySet;
50 using ::com::sun::star::beans::XPropertySetInfo;
51 using ::com::sun::star::container::XIndexContainer;
52 using ::com::sun::star::lang::XMultiServiceFactory;
53 using ::com::sun::star::uno::Reference;
54 using ::com::sun::star::uno::UNO_QUERY;
55 using ::com::sun::star::xml::sax::XAttributeList;
56 using ::com::sun::star::uno::XInterface;
57 using ::com::sun::star::uno::Any;
58 using ::com::sun::star::document::XEventsSupplier;
60 namespace {
62 class XMLImageMapObjectContext : public SvXMLImportContext
65 protected:
67 Reference<XIndexContainer> xImageMap; /// the image map
68 Reference<XPropertySet> xMapEntry; /// one map-entry (one area)
70 OUString sUrl;
71 OUString sTargt;
72 OUStringBuffer sDescriptionBuffer;
73 OUStringBuffer sTitleBuffer;
74 OUString sNam;
75 bool bIsActive;
77 bool bValid;
79 public:
81 XMLImageMapObjectContext(
82 SvXMLImport& rImport,
83 css::uno::Reference<css::container::XIndexContainer> const & xMap,
84 const char* pServiceName);
86 virtual void SAL_CALL startFastElement( sal_Int32 nElement,
87 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
89 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
91 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
92 sal_Int32 nElement,
93 const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
95 protected:
97 virtual void ProcessAttribute(sal_Int32 nAttrToken, const OUString& rValue);
99 virtual void Prepare(
100 css::uno::Reference<css::beans::XPropertySet> & rPropertySet);
105 XMLImageMapObjectContext::XMLImageMapObjectContext(
106 SvXMLImport& rImport,
107 Reference<XIndexContainer> const & xMap,
108 const char* pServiceName) :
109 SvXMLImportContext(rImport),
110 xImageMap(xMap),
111 bIsActive(true),
112 bValid(false)
114 DBG_ASSERT(nullptr != pServiceName,
115 "Please supply the image map object service name");
117 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
118 if( !xFactory.is() )
119 return;
121 Reference<XInterface> xIfc = xFactory->createInstance(
122 OUString::createFromAscii(pServiceName));
123 DBG_ASSERT(xIfc.is(), "can't create image map object!");
124 if( xIfc.is() )
126 Reference<XPropertySet> xPropertySet( xIfc, UNO_QUERY );
128 xMapEntry = xPropertySet;
130 // else: can't create service -> ignore
131 // else: can't even get factory -> ignore
134 void XMLImageMapObjectContext::startFastElement( sal_Int32 /*nElement*/,
135 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
137 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
138 ProcessAttribute(aIter.getToken(), aIter.toString());
141 void XMLImageMapObjectContext::endFastElement(sal_Int32 )
143 // only create and insert image map object if validity flag is set
144 // (and we actually have an image map)
145 if ( bValid && xImageMap.is() && xMapEntry.is() )
147 // set values
148 Prepare( xMapEntry );
150 // insert into image map
151 xImageMap->insertByIndex( xImageMap->getCount(), Any(xMapEntry) );
153 // else: not valid -> don't create and insert
156 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLImageMapObjectContext::createFastChildContext(
157 sal_Int32 nElement,
158 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
160 switch (nElement)
162 case XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS):
164 Reference<XEventsSupplier> xEvents( xMapEntry, UNO_QUERY );
165 return new XMLEventsImportContext(
166 GetImport(), xEvents);
168 case XML_ELEMENT(SVG, XML_TITLE):
169 case XML_ELEMENT(SVG_COMPAT, XML_TITLE):
170 return new XMLStringBufferImportContext(
171 GetImport(), sTitleBuffer);
172 case XML_ELEMENT(SVG, XML_DESC):
173 case XML_ELEMENT(SVG_COMPAT, XML_DESC):
174 return new XMLStringBufferImportContext(
175 GetImport(), sDescriptionBuffer);
177 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
178 return nullptr;
181 void XMLImageMapObjectContext::ProcessAttribute(
182 sal_Int32 nAttrToken,
183 const OUString& rValue)
185 switch (nAttrToken)
187 case XML_ELEMENT(XLINK, XML_HREF):
188 sUrl = GetImport().GetAbsoluteReference(rValue);
189 break;
191 case XML_ELEMENT(OFFICE, XML_TARGET_FRAME_NAME):
192 sTargt = rValue;
193 break;
195 case XML_ELEMENT(DRAW, XML_NOHREF):
196 bIsActive = ! IsXMLToken(rValue, XML_NOHREF);
197 break;
199 case XML_ELEMENT(OFFICE, XML_NAME):
200 sNam = rValue;
201 break;
202 default:
203 // do nothing
204 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, rValue);
205 break;
209 void XMLImageMapObjectContext::Prepare(
210 Reference<XPropertySet> & rPropertySet)
212 rPropertySet->setPropertyValue( "URL", Any( sUrl ) );
213 rPropertySet->setPropertyValue( "Title", Any( sTitleBuffer.makeStringAndClear() ) );
214 rPropertySet->setPropertyValue( "Description", Any( sDescriptionBuffer.makeStringAndClear() ) );
215 rPropertySet->setPropertyValue( "Target", Any( sTargt ) );
216 rPropertySet->setPropertyValue( "IsActive", Any( bIsActive ) );
217 rPropertySet->setPropertyValue( "Name", Any( sNam ) );
220 namespace {
222 class XMLImageMapRectangleContext : public XMLImageMapObjectContext
224 awt::Rectangle aRectangle;
226 bool bXOK;
227 bool bYOK;
228 bool bWidthOK;
229 bool bHeightOK;
231 public:
233 XMLImageMapRectangleContext(
234 SvXMLImport& rImport,
235 css::uno::Reference<css::container::XIndexContainer> const & xMap);
237 protected:
238 virtual void ProcessAttribute(
239 sal_Int32 nAttrToken,
240 const OUString& rValue) override;
242 virtual void Prepare(
243 css::uno::Reference<css::beans::XPropertySet> & rPropertySet) override;
248 XMLImageMapRectangleContext::XMLImageMapRectangleContext(
249 SvXMLImport& rImport,
250 Reference<XIndexContainer> const & xMap) :
251 XMLImageMapObjectContext(rImport, xMap,
252 "com.sun.star.image.ImageMapRectangleObject"),
253 bXOK(false),
254 bYOK(false),
255 bWidthOK(false),
256 bHeightOK(false)
260 void XMLImageMapRectangleContext::ProcessAttribute(
261 sal_Int32 nAttrToken,
262 const OUString& rValue)
264 sal_Int32 nTmp;
265 switch (nAttrToken)
267 case XML_ELEMENT(SVG, XML_X):
268 case XML_ELEMENT(SVG_COMPAT, XML_X):
269 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
270 rValue))
272 aRectangle.X = nTmp;
273 bXOK = true;
275 break;
276 case XML_ELEMENT(SVG, XML_Y):
277 case XML_ELEMENT(SVG_COMPAT, XML_Y):
278 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
279 rValue))
281 aRectangle.Y = nTmp;
282 bYOK = true;
284 break;
285 case XML_ELEMENT(SVG, XML_WIDTH):
286 case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
287 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
288 rValue))
290 aRectangle.Width = nTmp;
291 bWidthOK = true;
293 break;
294 case XML_ELEMENT(SVG, XML_HEIGHT):
295 case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
296 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
297 rValue))
299 aRectangle.Height = nTmp;
300 bHeightOK = true;
302 break;
303 default:
304 XMLImageMapObjectContext::ProcessAttribute(nAttrToken, rValue);
307 bValid = bHeightOK && bXOK && bYOK && bWidthOK;
310 void XMLImageMapRectangleContext::Prepare(
311 Reference<XPropertySet> & rPropertySet)
313 rPropertySet->setPropertyValue( "Boundary", uno::Any(aRectangle) );
315 // common properties handled by super class
316 XMLImageMapObjectContext::Prepare(rPropertySet);
319 namespace {
321 class XMLImageMapPolygonContext : public XMLImageMapObjectContext
323 OUString sViewBoxString;
324 OUString sPointsString;
326 bool bViewBoxOK;
327 bool bPointsOK;
329 public:
331 XMLImageMapPolygonContext(
332 SvXMLImport& rImport,
333 css::uno::Reference<css::container::XIndexContainer> const & xMap);
335 protected:
336 virtual void ProcessAttribute(
337 sal_Int32 nAttrToken,
338 const OUString& rValue) override;
340 virtual void Prepare(
341 css::uno::Reference<css::beans::XPropertySet> & rPropertySet) override;
346 XMLImageMapPolygonContext::XMLImageMapPolygonContext(
347 SvXMLImport& rImport,
348 Reference<XIndexContainer> const & xMap) :
349 XMLImageMapObjectContext(rImport, xMap,
350 "com.sun.star.image.ImageMapPolygonObject"),
351 bViewBoxOK(false),
352 bPointsOK(false)
356 void XMLImageMapPolygonContext::ProcessAttribute(
357 sal_Int32 nAttrToken,
358 const OUString& rValue)
360 switch (nAttrToken)
362 case XML_ELEMENT(DRAW, XML_POINTS):
363 sPointsString = rValue;
364 bPointsOK = true;
365 break;
366 case XML_ELEMENT(SVG, XML_VIEWBOX):
367 case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
368 sViewBoxString = rValue;
369 bViewBoxOK = true;
370 break;
371 default:
372 XMLImageMapObjectContext::ProcessAttribute(nAttrToken, rValue);
373 break;
376 bValid = bViewBoxOK && bPointsOK;
379 void XMLImageMapPolygonContext::Prepare(Reference<XPropertySet> & rPropertySet)
381 // process view box
382 SdXMLImExViewBox aViewBox(sViewBoxString, GetImport().GetMM100UnitConverter());
384 // get polygon sequence
385 basegfx::B2DPolygon aPolygon;
387 if(basegfx::utils::importFromSvgPoints(aPolygon, sPointsString))
389 if(aPolygon.count())
391 css::drawing::PointSequence aPointSequence;
392 basegfx::utils::B2DPolygonToUnoPointSequence(aPolygon, aPointSequence);
393 rPropertySet->setPropertyValue("Polygon", Any(aPointSequence));
397 // parent properties
398 XMLImageMapObjectContext::Prepare(rPropertySet);
401 namespace {
403 class XMLImageMapCircleContext : public XMLImageMapObjectContext
405 awt::Point aCenter;
406 sal_Int32 nRadius;
408 bool bXOK;
409 bool bYOK;
410 bool bRadiusOK;
412 public:
414 XMLImageMapCircleContext(
415 SvXMLImport& rImport,
416 css::uno::Reference<css::container::XIndexContainer> const & xMap);
418 protected:
419 virtual void ProcessAttribute(
420 sal_Int32 nAttrToken,
421 const OUString& rValue) override;
423 virtual void Prepare(
424 css::uno::Reference<css::beans::XPropertySet> & rPropertySet) override;
429 XMLImageMapCircleContext::XMLImageMapCircleContext(
430 SvXMLImport& rImport,
431 Reference<XIndexContainer> const & xMap)
432 : XMLImageMapObjectContext(rImport, xMap,
433 "com.sun.star.image.ImageMapCircleObject")
434 , nRadius(0)
435 , bXOK(false)
436 , bYOK(false)
437 , bRadiusOK(false)
441 void XMLImageMapCircleContext::ProcessAttribute(
442 sal_Int32 nAttrToken,
443 const OUString& rValue)
445 sal_Int32 nTmp;
446 switch (nAttrToken)
448 case XML_ELEMENT(SVG, XML_CX):
449 case XML_ELEMENT(SVG_COMPAT, XML_CX):
450 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
451 rValue))
453 aCenter.X = nTmp;
454 bXOK = true;
456 break;
457 case XML_ELEMENT(SVG, XML_CY):
458 case XML_ELEMENT(SVG_COMPAT, XML_CY):
459 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
460 rValue))
462 aCenter.Y = nTmp;
463 bYOK = true;
465 break;
466 case XML_ELEMENT(SVG, XML_R):
467 case XML_ELEMENT(SVG_COMPAT, XML_R):
468 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
469 rValue))
471 nRadius = nTmp;
472 bRadiusOK = true;
474 break;
475 default:
476 XMLImageMapObjectContext::ProcessAttribute(nAttrToken, rValue);
479 bValid = bRadiusOK && bXOK && bYOK;
482 void XMLImageMapCircleContext::Prepare(
483 Reference<XPropertySet> & rPropertySet)
485 // center (x,y)
486 rPropertySet->setPropertyValue( "Center", uno::Any(aCenter) );
487 // radius
488 rPropertySet->setPropertyValue( "Radius", uno::Any(nRadius) );
490 // common properties handled by super class
491 XMLImageMapObjectContext::Prepare(rPropertySet);
495 constexpr OUStringLiteral gsImageMap(u"ImageMap");
497 XMLImageMapContext::XMLImageMapContext(
498 SvXMLImport& rImport,
499 sal_uInt16 nPrefix,
500 const OUString& rLocalName,
501 Reference<XPropertySet> const & rPropertySet) :
502 SvXMLImportContext(rImport, nPrefix, rLocalName),
503 xPropertySet(rPropertySet)
507 Reference < XPropertySetInfo > xInfo =
508 xPropertySet->getPropertySetInfo();
509 if( xInfo.is() && xInfo->hasPropertyByName( gsImageMap ) )
510 xPropertySet->getPropertyValue(gsImageMap) >>= xImageMap;
512 catch(const css::uno::Exception& e)
514 uno::Sequence<OUString> aSeq(0);
515 rImport.SetError( XMLERROR_FLAG_WARNING | XMLERROR_API, aSeq, e.Message, nullptr );
519 XMLImageMapContext::~XMLImageMapContext()
523 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLImageMapContext::createFastChildContext(
524 sal_Int32 nElement,
525 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
527 switch (nElement)
529 case XML_ELEMENT(DRAW, XML_AREA_RECTANGLE):
530 return new XMLImageMapRectangleContext(
531 GetImport(), xImageMap);
532 case XML_ELEMENT(DRAW, XML_AREA_POLYGON):
533 return new XMLImageMapPolygonContext(
534 GetImport(), xImageMap);
535 case XML_ELEMENT(DRAW, XML_AREA_CIRCLE):
536 return new XMLImageMapCircleContext(
537 GetImport(), xImageMap);
538 default:
539 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
542 return nullptr;
545 void XMLImageMapContext::endFastElement(sal_Int32 )
547 Reference < XPropertySetInfo > xInfo =
548 xPropertySet->getPropertySetInfo();
549 if( xInfo.is() && xInfo->hasPropertyByName( gsImageMap ) )
550 xPropertySet->setPropertyValue(gsImageMap, uno::makeAny( xImageMap ) );
553 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */