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/xml/sax/XAttributeList.hpp>
26 #include <com/sun/star/container/XIndexContainer.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/drawing/PointSequenceSequence.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/xmlnmspe.hxx>
35 #include <xmloff/nmspmap.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>
45 using namespace ::com::sun::star
;
46 using namespace ::xmloff::token
;
48 using ::com::sun::star::beans::XPropertySet
;
49 using ::com::sun::star::beans::XPropertySetInfo
;
50 using ::com::sun::star::container::XIndexContainer
;
51 using ::com::sun::star::lang::XMultiServiceFactory
;
52 using ::com::sun::star::uno::Reference
;
53 using ::com::sun::star::uno::UNO_QUERY
;
54 using ::com::sun::star::xml::sax::XAttributeList
;
55 using ::com::sun::star::uno::XInterface
;
56 using ::com::sun::star::uno::Any
;
57 using ::com::sun::star::drawing::PointSequenceSequence
;
58 using ::com::sun::star::document::XEventsSupplier
;
61 enum XMLImageMapToken
: decltype(XML_TOK_UNKNOWN
)
66 XML_TOK_IMAP_CENTER_X
,
67 XML_TOK_IMAP_CENTER_Y
,
78 static SvXMLTokenMapEntry aImageMapObjectTokenMap
[] =
80 { XML_NAMESPACE_XLINK
, XML_HREF
, XML_TOK_IMAP_URL
},
81 { XML_NAMESPACE_OFFICE
, XML_NAME
, XML_TOK_IMAP_NAME
},
82 { XML_NAMESPACE_DRAW
, XML_NOHREF
, XML_TOK_IMAP_NOHREF
},
83 { XML_NAMESPACE_SVG
, XML_X
, XML_TOK_IMAP_X
},
84 { XML_NAMESPACE_SVG
, XML_Y
, XML_TOK_IMAP_Y
},
85 { XML_NAMESPACE_SVG
, XML_CX
, XML_TOK_IMAP_CENTER_X
},
86 { XML_NAMESPACE_SVG
, XML_CY
, XML_TOK_IMAP_CENTER_Y
},
87 { XML_NAMESPACE_SVG
, XML_WIDTH
, XML_TOK_IMAP_WIDTH
},
88 { XML_NAMESPACE_SVG
, XML_HEIGHT
, XML_TOK_IMAP_HEIGHT
},
89 { XML_NAMESPACE_SVG
, XML_R
, XML_TOK_IMAP_RADIUS
},
90 { XML_NAMESPACE_SVG
, XML_VIEWBOX
, XML_TOK_IMAP_VIEWBOX
},
91 { XML_NAMESPACE_DRAW
, XML_POINTS
, XML_TOK_IMAP_POINTS
},
92 { XML_NAMESPACE_OFFICE
, XML_TARGET_FRAME_NAME
, XML_TOK_IMAP_TARGET
},
98 class XMLImageMapObjectContext
: public SvXMLImportContext
103 const OUString sBoundary
;
104 const OUString sCenter
;
105 const OUString sTitle
;
106 const OUString sDescription
;
107 const OUString sImageMap
;
108 const OUString sIsActive
;
109 const OUString sName
;
110 const OUString sPolygon
;
111 const OUString sRadius
;
112 const OUString sTarget
;
115 Reference
<XIndexContainer
> xImageMap
; /// the image map
116 Reference
<XPropertySet
> xMapEntry
; /// one map-entry (one area)
120 OUStringBuffer sDescriptionBuffer
;
121 OUStringBuffer sTitleBuffer
;
130 XMLImageMapObjectContext(
131 SvXMLImport
& rImport
,
133 const OUString
& rLocalName
,
134 ::com::sun::star::uno::Reference
<
135 ::com::sun::star::container::XIndexContainer
> xMap
,
136 const sal_Char
* pServiceName
);
139 const ::com::sun::star::uno::Reference
<
140 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
) SAL_OVERRIDE
;
142 void EndElement() SAL_OVERRIDE
;
144 SvXMLImportContext
*CreateChildContext(
146 const OUString
& rLocalName
,
147 const ::com::sun::star::uno::Reference
<
148 ::com::sun::star::xml::sax::XAttributeList
> & xAttrList
) SAL_OVERRIDE
;
152 virtual void ProcessAttribute(
153 enum XMLImageMapToken eToken
,
154 const OUString
& rValue
);
156 virtual void Prepare(
157 ::com::sun::star::uno::Reference
<
158 ::com::sun::star::beans::XPropertySet
> & rPropertySet
);
162 TYPEINIT1( XMLImageMapObjectContext
, SvXMLImportContext
);
164 XMLImageMapObjectContext::XMLImageMapObjectContext(
165 SvXMLImport
& rImport
,
167 const OUString
& rLocalName
,
168 Reference
<XIndexContainer
> xMap
,
169 const sal_Char
* pServiceName
) :
170 SvXMLImportContext(rImport
, nPrefix
, rLocalName
),
171 sBoundary("Boundary"),
174 sDescription("Description"),
175 sImageMap("ImageMap"),
176 sIsActive("IsActive"),
186 DBG_ASSERT(NULL
!= pServiceName
,
187 "Please supply the image map object service name");
189 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),UNO_QUERY
);
192 Reference
<XInterface
> xIfc
= xFactory
->createInstance(
193 OUString::createFromAscii(pServiceName
));
194 DBG_ASSERT(xIfc
.is(), "can't create image map object!");
197 Reference
<XPropertySet
> xPropertySet( xIfc
, UNO_QUERY
);
199 xMapEntry
= xPropertySet
;
201 // else: can't create service -> ignore
203 // else: can't even get factory -> ignore
206 void XMLImageMapObjectContext::StartElement(
207 const Reference
<XAttributeList
>& xAttrList
)
209 SvXMLTokenMap
aMap(aImageMapObjectTokenMap
);
211 sal_Int16 nLength
= xAttrList
->getLength();
212 for(sal_Int16 nAttr
= 0; nAttr
< nLength
; nAttr
++)
215 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
216 GetKeyByAttrName( xAttrList
->getNameByIndex(nAttr
),
218 OUString sValue
= xAttrList
->getValueByIndex(nAttr
);
221 (enum XMLImageMapToken
)aMap
.Get(nPrefix
, sLocalName
), sValue
);
225 void XMLImageMapObjectContext::EndElement()
227 // only create and insert image map object if validity flag is set
228 // (and we actually have an image map)
229 if ( bValid
&& xImageMap
.is() && xMapEntry
.is() )
232 Prepare( xMapEntry
);
234 // insert into image map
237 xImageMap
->insertByIndex( xImageMap
->getCount(), aAny
);
239 // else: not valid -> don't create and insert
242 SvXMLImportContext
* XMLImageMapObjectContext::CreateChildContext(
244 const OUString
& rLocalName
,
245 const Reference
<XAttributeList
> & xAttrList
)
247 if ( (XML_NAMESPACE_OFFICE
== nPrefix
) &&
248 IsXMLToken(rLocalName
, XML_EVENT_LISTENERS
) )
250 Reference
<XEventsSupplier
> xEvents( xMapEntry
, UNO_QUERY
);
251 return new XMLEventsImportContext(
252 GetImport(), nPrefix
, rLocalName
, xEvents
);
254 else if ( (XML_NAMESPACE_SVG
== nPrefix
) &&
255 IsXMLToken(rLocalName
, XML_TITLE
) )
257 return new XMLStringBufferImportContext(
258 GetImport(), nPrefix
, rLocalName
, sTitleBuffer
);
260 else if ( (XML_NAMESPACE_SVG
== nPrefix
) &&
261 IsXMLToken(rLocalName
, XML_DESC
) )
263 return new XMLStringBufferImportContext(
264 GetImport(), nPrefix
, rLocalName
, sDescriptionBuffer
);
267 return SvXMLImportContext::CreateChildContext(nPrefix
, rLocalName
,
272 void XMLImageMapObjectContext::ProcessAttribute(
273 enum XMLImageMapToken eToken
,
274 const OUString
& rValue
)
278 case XML_TOK_IMAP_URL
:
279 sUrl
= GetImport().GetAbsoluteReference(rValue
);
282 case XML_TOK_IMAP_TARGET
:
286 case XML_TOK_IMAP_NOHREF
:
287 bIsActive
= ! IsXMLToken(rValue
, XML_NOHREF
);
290 case XML_TOK_IMAP_NAME
:
299 void XMLImageMapObjectContext::Prepare(
300 Reference
<XPropertySet
> & rPropertySet
)
302 rPropertySet
->setPropertyValue( sURL
, Any( sUrl
) );
303 rPropertySet
->setPropertyValue( sTitle
, Any( sTitleBuffer
.makeStringAndClear() ) );
304 rPropertySet
->setPropertyValue( sDescription
, Any( sDescriptionBuffer
.makeStringAndClear() ) );
305 rPropertySet
->setPropertyValue( sTarget
, Any( sTargt
) );
306 rPropertySet
->setPropertyValue( sIsActive
, Any( bIsActive
) );
307 rPropertySet
->setPropertyValue( sName
, Any( sNam
) );
312 class XMLImageMapRectangleContext
: public XMLImageMapObjectContext
314 awt::Rectangle aRectangle
;
324 XMLImageMapRectangleContext(
325 SvXMLImport
& rImport
,
327 const OUString
& rLocalName
,
328 ::com::sun::star::uno::Reference
<
329 ::com::sun::star::container::XIndexContainer
> xMap
);
331 virtual ~XMLImageMapRectangleContext();
334 virtual void ProcessAttribute(
335 enum XMLImageMapToken eToken
,
336 const OUString
& rValue
) SAL_OVERRIDE
;
338 virtual void Prepare(
339 ::com::sun::star::uno::Reference
<
340 ::com::sun::star::beans::XPropertySet
> & rPropertySet
) SAL_OVERRIDE
;
345 TYPEINIT1(XMLImageMapRectangleContext
, XMLImageMapObjectContext
);
347 XMLImageMapRectangleContext::XMLImageMapRectangleContext(
348 SvXMLImport
& rImport
,
350 const OUString
& rLocalName
,
351 Reference
<XIndexContainer
> xMap
) :
352 XMLImageMapObjectContext(rImport
, nPrefix
, rLocalName
, xMap
,
353 "com.sun.star.image.ImageMapRectangleObject"),
361 XMLImageMapRectangleContext::~XMLImageMapRectangleContext()
365 void XMLImageMapRectangleContext::ProcessAttribute(
366 enum XMLImageMapToken eToken
,
367 const OUString
& rValue
)
373 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
381 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
388 case XML_TOK_IMAP_WIDTH
:
389 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
392 aRectangle
.Width
= nTmp
;
396 case XML_TOK_IMAP_HEIGHT
:
397 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
400 aRectangle
.Height
= nTmp
;
405 XMLImageMapObjectContext::ProcessAttribute(eToken
, rValue
);
408 bValid
= bHeightOK
&& bXOK
&& bYOK
&& bWidthOK
;
411 void XMLImageMapRectangleContext::Prepare(
412 Reference
<XPropertySet
> & rPropertySet
)
416 rPropertySet
->setPropertyValue( sBoundary
, aAny
);
418 // common properties handled by super class
419 XMLImageMapObjectContext::Prepare(rPropertySet
);
423 class XMLImageMapPolygonContext
: public XMLImageMapObjectContext
425 OUString sViewBoxString
;
426 OUString sPointsString
;
434 XMLImageMapPolygonContext(
435 SvXMLImport
& rImport
,
437 const OUString
& rLocalName
,
438 ::com::sun::star::uno::Reference
<
439 ::com::sun::star::container::XIndexContainer
> xMap
);
441 virtual ~XMLImageMapPolygonContext();
444 virtual void ProcessAttribute(
445 enum XMLImageMapToken eToken
,
446 const OUString
& rValue
) SAL_OVERRIDE
;
448 virtual void Prepare(
449 ::com::sun::star::uno::Reference
<
450 ::com::sun::star::beans::XPropertySet
> & rPropertySet
) SAL_OVERRIDE
;
455 TYPEINIT1(XMLImageMapPolygonContext
, XMLImageMapObjectContext
);
457 XMLImageMapPolygonContext::XMLImageMapPolygonContext(
458 SvXMLImport
& rImport
,
460 const OUString
& rLocalName
,
461 Reference
<XIndexContainer
> xMap
) :
462 XMLImageMapObjectContext(rImport
, nPrefix
, rLocalName
, xMap
,
463 "com.sun.star.image.ImageMapPolygonObject"),
469 XMLImageMapPolygonContext::~XMLImageMapPolygonContext()
473 void XMLImageMapPolygonContext::ProcessAttribute(
474 enum XMLImageMapToken eToken
,
475 const OUString
& rValue
)
479 case XML_TOK_IMAP_POINTS
:
480 sPointsString
= rValue
;
483 case XML_TOK_IMAP_VIEWBOX
:
484 sViewBoxString
= rValue
;
488 XMLImageMapObjectContext::ProcessAttribute(eToken
, rValue
);
492 bValid
= bViewBoxOK
&& bPointsOK
;
495 void XMLImageMapPolygonContext::Prepare(Reference
<XPropertySet
> & rPropertySet
)
498 SdXMLImExViewBox
aViewBox(sViewBoxString
, GetImport().GetMM100UnitConverter());
500 // get polygon sequence
501 basegfx::B2DPolygon aPolygon
;
503 if(basegfx::tools::importFromSvgPoints(aPolygon
, sPointsString
))
507 com::sun::star::drawing::PointSequence aPointSequence
;
510 basegfx::tools::B2DPolygonToUnoPointSequence(aPolygon
, aPointSequence
);
511 aAny
<<= aPointSequence
;
512 rPropertySet
->setPropertyValue(sPolygon
, aAny
);
517 XMLImageMapObjectContext::Prepare(rPropertySet
);
520 class XMLImageMapCircleContext
: public XMLImageMapObjectContext
532 XMLImageMapCircleContext(
533 SvXMLImport
& rImport
,
535 const OUString
& rLocalName
,
536 ::com::sun::star::uno::Reference
<
537 ::com::sun::star::container::XIndexContainer
> xMap
);
539 virtual ~XMLImageMapCircleContext();
542 virtual void ProcessAttribute(
543 enum XMLImageMapToken eToken
,
544 const OUString
& rValue
) SAL_OVERRIDE
;
546 virtual void Prepare(
547 ::com::sun::star::uno::Reference
<
548 ::com::sun::star::beans::XPropertySet
> & rPropertySet
) SAL_OVERRIDE
;
551 TYPEINIT1(XMLImageMapCircleContext
, XMLImageMapObjectContext
);
553 XMLImageMapCircleContext::XMLImageMapCircleContext(
554 SvXMLImport
& rImport
,
556 const OUString
& rLocalName
,
557 Reference
<XIndexContainer
> xMap
)
558 : XMLImageMapObjectContext(rImport
, nPrefix
, rLocalName
, xMap
,
559 "com.sun.star.image.ImageMapCircleObject")
567 XMLImageMapCircleContext::~XMLImageMapCircleContext()
571 void XMLImageMapCircleContext::ProcessAttribute(
572 enum XMLImageMapToken eToken
,
573 const OUString
& rValue
)
578 case XML_TOK_IMAP_CENTER_X
:
579 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
586 case XML_TOK_IMAP_CENTER_Y
:
587 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
594 case XML_TOK_IMAP_RADIUS
:
595 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp
,
603 XMLImageMapObjectContext::ProcessAttribute(eToken
, rValue
);
606 bValid
= bRadiusOK
&& bXOK
&& bYOK
;
609 void XMLImageMapCircleContext::Prepare(
610 Reference
<XPropertySet
> & rPropertySet
)
615 rPropertySet
->setPropertyValue( sCenter
, aAny
);
619 rPropertySet
->setPropertyValue( sRadius
, aAny
);
621 // common properties handled by super class
622 XMLImageMapObjectContext::Prepare(rPropertySet
);
634 TYPEINIT1(XMLImageMapContext
, SvXMLImportContext
);
636 XMLImageMapContext::XMLImageMapContext(
637 SvXMLImport
& rImport
,
639 const OUString
& rLocalName
,
640 Reference
<XPropertySet
> & rPropertySet
) :
641 SvXMLImportContext(rImport
, nPrefix
, rLocalName
),
642 sImageMap("ImageMap"),
643 xPropertySet(rPropertySet
)
648 Reference
< XPropertySetInfo
> xInfo
=
649 xPropertySet
->getPropertySetInfo();
650 if( xInfo
.is() && xInfo
->hasPropertyByName( sImageMap
) )
651 xPropertySet
->getPropertyValue(sImageMap
) >>= xImageMap
;
653 catch(const com::sun::star::uno::Exception
& e
)
655 uno::Sequence
<OUString
> aSeq(0);
656 rImport
.SetError( XMLERROR_FLAG_WARNING
| XMLERROR_API
, aSeq
, e
.Message
, NULL
);
660 XMLImageMapContext::~XMLImageMapContext()
664 SvXMLImportContext
*XMLImageMapContext::CreateChildContext(
666 const OUString
& rLocalName
,
667 const Reference
<XAttributeList
> & xAttrList
)
669 SvXMLImportContext
* pContext
= NULL
;
671 if ( XML_NAMESPACE_DRAW
== nPrefix
)
673 if ( IsXMLToken(rLocalName
, XML_AREA_RECTANGLE
) )
675 pContext
= new XMLImageMapRectangleContext(
676 GetImport(), nPrefix
, rLocalName
, xImageMap
);
678 else if ( IsXMLToken(rLocalName
, XML_AREA_POLYGON
) )
680 pContext
= new XMLImageMapPolygonContext(
681 GetImport(), nPrefix
, rLocalName
, xImageMap
);
683 else if ( IsXMLToken(rLocalName
, XML_AREA_CIRCLE
) )
685 pContext
= new XMLImageMapCircleContext(
686 GetImport(), nPrefix
, rLocalName
, xImageMap
);
690 pContext
= SvXMLImportContext::CreateChildContext(nPrefix
, rLocalName
,
696 void XMLImageMapContext::EndElement()
698 Reference
< XPropertySetInfo
> xInfo
=
699 xPropertySet
->getPropertySetInfo();
700 if( xInfo
.is() && xInfo
->hasPropertyByName( sImageMap
) )
701 xPropertySet
->setPropertyValue(sImageMap
, uno::makeAny( xImageMap
) );
704 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */