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 <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
;
62 class XMLImageMapObjectContext
: public SvXMLImportContext
67 Reference
<XIndexContainer
> xImageMap
; /// the image map
68 Reference
<XPropertySet
> xMapEntry
; /// one map-entry (one area)
72 OUStringBuffer sDescriptionBuffer
;
73 OUStringBuffer sTitleBuffer
;
81 XMLImageMapObjectContext(
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(
93 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
97 virtual void ProcessAttribute(sal_Int32 nAttrToken
, const OUString
& rValue
);
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
),
114 DBG_ASSERT(nullptr != pServiceName
,
115 "Please supply the image map object service name");
117 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),UNO_QUERY
);
121 Reference
<XInterface
> xIfc
= xFactory
->createInstance(
122 OUString::createFromAscii(pServiceName
));
123 DBG_ASSERT(xIfc
.is(), "can't create image map object!");
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() )
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(
158 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& )
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
);
181 void XMLImageMapObjectContext::ProcessAttribute(
182 sal_Int32 nAttrToken
,
183 const OUString
& rValue
)
187 case XML_ELEMENT(XLINK
, XML_HREF
):
188 sUrl
= GetImport().GetAbsoluteReference(rValue
);
191 case XML_ELEMENT(OFFICE
, XML_TARGET_FRAME_NAME
):
195 case XML_ELEMENT(DRAW
, XML_NOHREF
):
196 bIsActive
= ! IsXMLToken(rValue
, XML_NOHREF
);
199 case XML_ELEMENT(OFFICE
, XML_NAME
):
204 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken
, rValue
);
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
) );
222 class XMLImageMapRectangleContext
: public XMLImageMapObjectContext
224 awt::Rectangle aRectangle
;
233 XMLImageMapRectangleContext(
234 SvXMLImport
& rImport
,
235 css::uno::Reference
<css::container::XIndexContainer
> const & xMap
);
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"),
260 void XMLImageMapRectangleContext::ProcessAttribute(
261 sal_Int32 nAttrToken
,
262 const OUString
& rValue
)
267 case XML_ELEMENT(SVG
, XML_X
):
268 case XML_ELEMENT(SVG_COMPAT
, XML_X
):
269 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
276 case XML_ELEMENT(SVG
, XML_Y
):
277 case XML_ELEMENT(SVG_COMPAT
, XML_Y
):
278 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
285 case XML_ELEMENT(SVG
, XML_WIDTH
):
286 case XML_ELEMENT(SVG_COMPAT
, XML_WIDTH
):
287 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
290 aRectangle
.Width
= nTmp
;
294 case XML_ELEMENT(SVG
, XML_HEIGHT
):
295 case XML_ELEMENT(SVG_COMPAT
, XML_HEIGHT
):
296 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
299 aRectangle
.Height
= nTmp
;
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
);
321 class XMLImageMapPolygonContext
: public XMLImageMapObjectContext
323 OUString sViewBoxString
;
324 OUString sPointsString
;
331 XMLImageMapPolygonContext(
332 SvXMLImport
& rImport
,
333 css::uno::Reference
<css::container::XIndexContainer
> const & xMap
);
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"),
356 void XMLImageMapPolygonContext::ProcessAttribute(
357 sal_Int32 nAttrToken
,
358 const OUString
& rValue
)
362 case XML_ELEMENT(DRAW
, XML_POINTS
):
363 sPointsString
= rValue
;
366 case XML_ELEMENT(SVG
, XML_VIEWBOX
):
367 case XML_ELEMENT(SVG_COMPAT
, XML_VIEWBOX
):
368 sViewBoxString
= rValue
;
372 XMLImageMapObjectContext::ProcessAttribute(nAttrToken
, rValue
);
376 bValid
= bViewBoxOK
&& bPointsOK
;
379 void XMLImageMapPolygonContext::Prepare(Reference
<XPropertySet
> & rPropertySet
)
382 SdXMLImExViewBox
aViewBox(sViewBoxString
, GetImport().GetMM100UnitConverter());
384 // get polygon sequence
385 basegfx::B2DPolygon aPolygon
;
387 if(basegfx::utils::importFromSvgPoints(aPolygon
, sPointsString
))
391 css::drawing::PointSequence aPointSequence
;
392 basegfx::utils::B2DPolygonToUnoPointSequence(aPolygon
, aPointSequence
);
393 rPropertySet
->setPropertyValue("Polygon", Any(aPointSequence
));
398 XMLImageMapObjectContext::Prepare(rPropertySet
);
403 class XMLImageMapCircleContext
: public XMLImageMapObjectContext
414 XMLImageMapCircleContext(
415 SvXMLImport
& rImport
,
416 css::uno::Reference
<css::container::XIndexContainer
> const & xMap
);
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")
441 void XMLImageMapCircleContext::ProcessAttribute(
442 sal_Int32 nAttrToken
,
443 const OUString
& rValue
)
448 case XML_ELEMENT(SVG
, XML_CX
):
449 case XML_ELEMENT(SVG_COMPAT
, XML_CX
):
450 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
457 case XML_ELEMENT(SVG
, XML_CY
):
458 case XML_ELEMENT(SVG_COMPAT
, XML_CY
):
459 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
466 case XML_ELEMENT(SVG
, XML_R
):
467 case XML_ELEMENT(SVG_COMPAT
, XML_R
):
468 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
476 XMLImageMapObjectContext::ProcessAttribute(nAttrToken
, rValue
);
479 bValid
= bRadiusOK
&& bXOK
&& bYOK
;
482 void XMLImageMapCircleContext::Prepare(
483 Reference
<XPropertySet
> & rPropertySet
)
486 rPropertySet
->setPropertyValue( "Center", uno::Any(aCenter
) );
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
,
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(
525 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& )
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
);
539 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
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: */