bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / draw / XMLImageMapContext.cxx
blobabd7e20f68e75788806bf9bdc0caaeffd4d948f6
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/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)
63 XML_TOK_IMAP_URL,
64 XML_TOK_IMAP_X,
65 XML_TOK_IMAP_Y,
66 XML_TOK_IMAP_CENTER_X,
67 XML_TOK_IMAP_CENTER_Y,
68 XML_TOK_IMAP_WIDTH,
69 XML_TOK_IMAP_HEIGHT,
70 XML_TOK_IMAP_POINTS,
71 XML_TOK_IMAP_VIEWBOX,
72 XML_TOK_IMAP_NOHREF,
73 XML_TOK_IMAP_NAME,
74 XML_TOK_IMAP_RADIUS,
75 XML_TOK_IMAP_TARGET
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 },
93 XML_TOKEN_MAP_END
98 class XMLImageMapObjectContext : public SvXMLImportContext
101 protected:
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;
113 const OUString sURL;
115 Reference<XIndexContainer> xImageMap; /// the image map
116 Reference<XPropertySet> xMapEntry; /// one map-entry (one area)
118 OUString sUrl;
119 OUString sTargt;
120 OUStringBuffer sDescriptionBuffer;
121 OUStringBuffer sTitleBuffer;
122 OUString sNam;
123 bool bIsActive;
125 bool bValid;
127 public:
128 TYPEINFO_OVERRIDE();
130 XMLImageMapObjectContext(
131 SvXMLImport& rImport,
132 sal_uInt16 nPrefix,
133 const OUString& rLocalName,
134 ::com::sun::star::uno::Reference<
135 ::com::sun::star::container::XIndexContainer> xMap,
136 const sal_Char* pServiceName);
138 void StartElement(
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(
145 sal_uInt16 nPrefix,
146 const OUString& rLocalName,
147 const ::com::sun::star::uno::Reference<
148 ::com::sun::star::xml::sax::XAttributeList> & xAttrList ) SAL_OVERRIDE;
150 protected:
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,
166 sal_uInt16 nPrefix,
167 const OUString& rLocalName,
168 Reference<XIndexContainer> xMap,
169 const sal_Char* pServiceName) :
170 SvXMLImportContext(rImport, nPrefix, rLocalName),
171 sBoundary("Boundary"),
172 sCenter("Center"),
173 sTitle("Title"),
174 sDescription("Description"),
175 sImageMap("ImageMap"),
176 sIsActive("IsActive"),
177 sName("Name"),
178 sPolygon("Polygon"),
179 sRadius("Radius"),
180 sTarget("Target"),
181 sURL("URL"),
182 xImageMap(xMap),
183 bIsActive(true),
184 bValid(false)
186 DBG_ASSERT(NULL != pServiceName,
187 "Please supply the image map object service name");
189 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
190 if( xFactory.is() )
192 Reference<XInterface> xIfc = xFactory->createInstance(
193 OUString::createFromAscii(pServiceName));
194 DBG_ASSERT(xIfc.is(), "can't create image map object!");
195 if( xIfc.is() )
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++)
214 OUString sLocalName;
215 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
216 GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
217 &sLocalName );
218 OUString sValue = xAttrList->getValueByIndex(nAttr);
220 ProcessAttribute(
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() )
231 // set values
232 Prepare( xMapEntry );
234 // insert into image map
235 Any aAny;
236 aAny <<= xMapEntry;
237 xImageMap->insertByIndex( xImageMap->getCount(), aAny );
239 // else: not valid -> don't create and insert
242 SvXMLImportContext* XMLImageMapObjectContext::CreateChildContext(
243 sal_uInt16 nPrefix,
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);
266 else
267 return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
268 xAttrList);
272 void XMLImageMapObjectContext::ProcessAttribute(
273 enum XMLImageMapToken eToken,
274 const OUString& rValue)
276 switch (eToken)
278 case XML_TOK_IMAP_URL:
279 sUrl = GetImport().GetAbsoluteReference(rValue);
280 break;
282 case XML_TOK_IMAP_TARGET:
283 sTargt = rValue;
284 break;
286 case XML_TOK_IMAP_NOHREF:
287 bIsActive = ! IsXMLToken(rValue, XML_NOHREF);
288 break;
290 case XML_TOK_IMAP_NAME:
291 sNam = rValue;
292 break;
293 default:
294 // do nothing
295 break;
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;
316 bool bXOK;
317 bool bYOK;
318 bool bWidthOK;
319 bool bHeightOK;
321 public:
322 TYPEINFO_OVERRIDE();
324 XMLImageMapRectangleContext(
325 SvXMLImport& rImport,
326 sal_uInt16 nPrefix,
327 const OUString& rLocalName,
328 ::com::sun::star::uno::Reference<
329 ::com::sun::star::container::XIndexContainer> xMap);
331 virtual ~XMLImageMapRectangleContext();
333 protected:
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,
349 sal_uInt16 nPrefix,
350 const OUString& rLocalName,
351 Reference<XIndexContainer> xMap) :
352 XMLImageMapObjectContext(rImport, nPrefix, rLocalName, xMap,
353 "com.sun.star.image.ImageMapRectangleObject"),
354 bXOK(false),
355 bYOK(false),
356 bWidthOK(false),
357 bHeightOK(false)
361 XMLImageMapRectangleContext::~XMLImageMapRectangleContext()
365 void XMLImageMapRectangleContext::ProcessAttribute(
366 enum XMLImageMapToken eToken,
367 const OUString& rValue)
369 sal_Int32 nTmp;
370 switch (eToken)
372 case XML_TOK_IMAP_X:
373 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
374 rValue))
376 aRectangle.X = nTmp;
377 bXOK = true;
379 break;
380 case XML_TOK_IMAP_Y:
381 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
382 rValue))
384 aRectangle.Y = nTmp;
385 bYOK = true;
387 break;
388 case XML_TOK_IMAP_WIDTH:
389 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
390 rValue))
392 aRectangle.Width = nTmp;
393 bWidthOK = true;
395 break;
396 case XML_TOK_IMAP_HEIGHT:
397 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
398 rValue))
400 aRectangle.Height = nTmp;
401 bHeightOK = true;
403 break;
404 default:
405 XMLImageMapObjectContext::ProcessAttribute(eToken, rValue);
408 bValid = bHeightOK && bXOK && bYOK && bWidthOK;
411 void XMLImageMapRectangleContext::Prepare(
412 Reference<XPropertySet> & rPropertySet)
414 Any aAny;
415 aAny <<= aRectangle;
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;
428 bool bViewBoxOK;
429 bool bPointsOK;
431 public:
432 TYPEINFO_OVERRIDE();
434 XMLImageMapPolygonContext(
435 SvXMLImport& rImport,
436 sal_uInt16 nPrefix,
437 const OUString& rLocalName,
438 ::com::sun::star::uno::Reference<
439 ::com::sun::star::container::XIndexContainer> xMap);
441 virtual ~XMLImageMapPolygonContext();
443 protected:
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,
459 sal_uInt16 nPrefix,
460 const OUString& rLocalName,
461 Reference<XIndexContainer> xMap) :
462 XMLImageMapObjectContext(rImport, nPrefix, rLocalName, xMap,
463 "com.sun.star.image.ImageMapPolygonObject"),
464 bViewBoxOK(false),
465 bPointsOK(false)
469 XMLImageMapPolygonContext::~XMLImageMapPolygonContext()
473 void XMLImageMapPolygonContext::ProcessAttribute(
474 enum XMLImageMapToken eToken,
475 const OUString& rValue)
477 switch (eToken)
479 case XML_TOK_IMAP_POINTS:
480 sPointsString = rValue;
481 bPointsOK = true;
482 break;
483 case XML_TOK_IMAP_VIEWBOX:
484 sViewBoxString = rValue;
485 bViewBoxOK = true;
486 break;
487 default:
488 XMLImageMapObjectContext::ProcessAttribute(eToken, rValue);
489 break;
492 bValid = bViewBoxOK && bPointsOK;
495 void XMLImageMapPolygonContext::Prepare(Reference<XPropertySet> & rPropertySet)
497 // process view box
498 SdXMLImExViewBox aViewBox(sViewBoxString, GetImport().GetMM100UnitConverter());
500 // get polygon sequence
501 basegfx::B2DPolygon aPolygon;
503 if(basegfx::tools::importFromSvgPoints(aPolygon, sPointsString))
505 if(aPolygon.count())
507 com::sun::star::drawing::PointSequence aPointSequence;
508 uno::Any aAny;
510 basegfx::tools::B2DPolygonToUnoPointSequence(aPolygon, aPointSequence);
511 aAny <<= aPointSequence;
512 rPropertySet->setPropertyValue(sPolygon, aAny);
516 // parent properties
517 XMLImageMapObjectContext::Prepare(rPropertySet);
520 class XMLImageMapCircleContext : public XMLImageMapObjectContext
522 awt::Point aCenter;
523 sal_Int32 nRadius;
525 bool bXOK;
526 bool bYOK;
527 bool bRadiusOK;
529 public:
530 TYPEINFO_OVERRIDE();
532 XMLImageMapCircleContext(
533 SvXMLImport& rImport,
534 sal_uInt16 nPrefix,
535 const OUString& rLocalName,
536 ::com::sun::star::uno::Reference<
537 ::com::sun::star::container::XIndexContainer> xMap);
539 virtual ~XMLImageMapCircleContext();
541 protected:
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,
555 sal_uInt16 nPrefix,
556 const OUString& rLocalName,
557 Reference<XIndexContainer> xMap)
558 : XMLImageMapObjectContext(rImport, nPrefix, rLocalName, xMap,
559 "com.sun.star.image.ImageMapCircleObject")
560 , nRadius(0)
561 , bXOK(false)
562 , bYOK(false)
563 , bRadiusOK(false)
567 XMLImageMapCircleContext::~XMLImageMapCircleContext()
571 void XMLImageMapCircleContext::ProcessAttribute(
572 enum XMLImageMapToken eToken,
573 const OUString& rValue)
575 sal_Int32 nTmp;
576 switch (eToken)
578 case XML_TOK_IMAP_CENTER_X:
579 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
580 rValue))
582 aCenter.X = nTmp;
583 bXOK = true;
585 break;
586 case XML_TOK_IMAP_CENTER_Y:
587 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
588 rValue))
590 aCenter.Y = nTmp;
591 bYOK = true;
593 break;
594 case XML_TOK_IMAP_RADIUS:
595 if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
596 rValue))
598 nRadius = nTmp;
599 bRadiusOK = true;
601 break;
602 default:
603 XMLImageMapObjectContext::ProcessAttribute(eToken, rValue);
606 bValid = bRadiusOK && bXOK && bYOK;
609 void XMLImageMapCircleContext::Prepare(
610 Reference<XPropertySet> & rPropertySet)
612 // center (x,y)
613 Any aAny;
614 aAny <<= aCenter;
615 rPropertySet->setPropertyValue( sCenter, aAny );
617 // radius
618 aAny <<= nRadius;
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,
638 sal_uInt16 nPrefix,
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(
665 sal_uInt16 nPrefix,
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);
689 else
690 pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
691 xAttrList);
693 return pContext;
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: */