Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / framework / source / xml / imagesdocumenthandler.cxx
blob00aa56bef7093faec9beb9f246f19216323bc4d2
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 <memory>
21 #include <stdio.h>
23 #include <xml/imagesdocumenthandler.hxx>
25 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
26 #include <com/sun/star/xml/sax/SAXException.hpp>
28 #include <vcl/svapp.hxx>
29 #include <vcl/toolbox.hxx>
30 #include <rtl/ustrbuf.hxx>
32 #include <comphelper/attributelist.hxx>
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star::xml::sax;
37 #define ELEMENT_IMAGECONTAINER "imagescontainer"
38 #define ELEMENT_IMAGES "images"
39 #define ELEMENT_ENTRY "entry"
40 #define ELEMENT_EXTERNALIMAGES "externalimages"
41 #define ELEMENT_EXTERNALENTRY "externalentry"
43 #define ELEMENT_NS_IMAGESCONTAINER "image:imagescontainer"
44 #define ELEMENT_NS_IMAGES "image:images"
45 #define ELEMENT_NS_ENTRY "image:entry"
47 #define ATTRIBUTE_HREF "href"
48 #define ATTRIBUTE_MASKCOLOR "maskcolor"
49 #define ATTRIBUTE_COMMAND "command"
50 #define ATTRIBUTE_BITMAPINDEX "bitmap-index"
51 #define ATTRIBUTE_MASKURL "maskurl"
52 #define ATTRIBUTE_MASKMODE "maskmode"
53 #define ATTRIBUTE_HIGHCONTRASTURL "highcontrasturl"
54 #define ATTRIBUTE_HIGHCONTRASTMASKURL "highcontrastmaskurl"
55 #define ATTRIBUTE_TYPE_CDATA "CDATA"
57 #define ATTRIBUTE_XMLNS_IMAGE "xmlns:image"
58 #define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink"
60 #define ATTRIBUTE_XLINK_TYPE "xlink:type"
61 #define ATTRIBUTE_XLINK_TYPE_VALUE "simple"
63 #define XMLNS_IMAGE "http://openoffice.org/2001/image"
64 #define XMLNS_XLINK "http://www.w3.org/1999/xlink"
65 #define XMLNS_IMAGE_PREFIX "image:"
67 #define XMLNS_FILTER_SEPARATOR "^"
69 #define IMAGES_DOCTYPE "<!DOCTYPE image:imagecontainer PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"image.dtd\">"
71 namespace framework
74 struct ImageXMLEntryProperty
76 OReadImagesDocumentHandler::Image_XML_Namespace nNamespace;
77 char aEntryName[20];
80 ImageXMLEntryProperty const ImagesEntries[OReadImagesDocumentHandler::IMG_XML_ENTRY_COUNT] =
82 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_IMAGECONTAINER },
83 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_IMAGES },
84 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_ENTRY },
85 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_EXTERNALIMAGES },
86 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_EXTERNALENTRY },
87 { OReadImagesDocumentHandler::IMG_NS_XLINK, ATTRIBUTE_HREF },
88 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKCOLOR },
89 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_COMMAND },
90 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_BITMAPINDEX },
91 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKURL },
92 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKMODE },
93 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTURL },
94 { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTMASKURL }
97 OReadImagesDocumentHandler::OReadImagesDocumentHandler( ImageItemDescriptorList& rItems ) :
98 m_rImageList( rItems )
100 // create hash map to speed up lookup
101 for ( int i = 0; i < int(IMG_XML_ENTRY_COUNT); i++ )
103 OUStringBuffer temp( 20 );
105 if ( ImagesEntries[i].nNamespace == IMG_NS_IMAGE )
106 temp.append( XMLNS_IMAGE );
107 else
108 temp.append( XMLNS_XLINK );
110 temp.append( XMLNS_FILTER_SEPARATOR );
111 temp.appendAscii( ImagesEntries[i].aEntryName );
112 m_aImageMap.emplace( temp.makeStringAndClear(), static_cast<Image_XML_Entry>(i) );
115 // reset states
116 m_bImageContainerStartFound = false;
117 m_bImageContainerEndFound = false;
118 m_bImagesStartFound = false;
121 OReadImagesDocumentHandler::~OReadImagesDocumentHandler()
125 // XDocumentHandler
126 void SAL_CALL OReadImagesDocumentHandler::startDocument()
130 void SAL_CALL OReadImagesDocumentHandler::endDocument()
132 SolarMutexGuard g;
134 if (m_bImageContainerStartFound != m_bImageContainerEndFound)
136 OUString aErrorMessage = getErrorLineString() + "No matching start or end element 'image:imagecontainer' found!";
137 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
141 void SAL_CALL OReadImagesDocumentHandler::startElement(
142 const OUString& aName, const Reference< XAttributeList > &xAttribs )
144 SolarMutexGuard g;
146 ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName );
147 if ( pImageEntry != m_aImageMap.end() )
149 switch ( pImageEntry->second )
151 case IMG_ELEMENT_IMAGECONTAINER:
153 // image:imagecontainer element (container element for all further image elements)
154 if ( m_bImageContainerStartFound )
156 OUString aErrorMessage = getErrorLineString() + "Element 'image:imagecontainer' cannot be embedded into 'image:imagecontainer'!";
157 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
160 m_bImageContainerStartFound = true;
162 break;
164 case IMG_ELEMENT_IMAGES:
166 if ( !m_bImageContainerStartFound )
168 OUString aErrorMessage = getErrorLineString() + "Element 'image:images' must be embedded into element 'image:imagecontainer'!";
169 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
172 if ( m_bImagesStartFound )
174 OUString aErrorMessage = getErrorLineString() + "Element 'image:images' cannot be embedded into 'image:images'!";
175 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
178 m_bImagesStartFound = true;
180 break;
182 case IMG_ELEMENT_ENTRY:
184 // Check that image:entry is embedded into image:images!
185 if ( !m_bImagesStartFound )
187 OUString aErrorMessage = getErrorLineString() + "Element 'image:entry' must be embedded into element 'image:images'!";
188 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
191 // Create new image item descriptor
192 ImageItemDescriptor aItem;
194 // Read attributes for this image definition
195 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
197 pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
198 if ( pImageEntry != m_aImageMap.end() )
200 switch ( pImageEntry->second )
202 case IMG_ATTRIBUTE_COMMAND:
204 aItem.aCommandURL = xAttribs->getValueByIndex( n );
206 break;
208 default:
209 break;
214 // Check required attribute "command"
215 if ( aItem.aCommandURL.isEmpty() )
217 OUString aErrorMessage = getErrorLineString() + "Required attribute 'image:command' must have a value!";
218 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
221 m_rImageList.push_back( aItem );
223 break;
225 default:
226 break;
231 void SAL_CALL OReadImagesDocumentHandler::endElement(const OUString& aName)
233 SolarMutexGuard g;
235 ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName );
236 if ( pImageEntry != m_aImageMap.end() )
238 switch ( pImageEntry->second )
240 case IMG_ELEMENT_IMAGECONTAINER:
242 m_bImageContainerEndFound = true;
244 break;
246 case IMG_ELEMENT_IMAGES:
248 m_bImagesStartFound = false;
250 break;
252 default: break;
257 void SAL_CALL OReadImagesDocumentHandler::characters(const OUString&)
261 void SAL_CALL OReadImagesDocumentHandler::ignorableWhitespace(const OUString&)
265 void SAL_CALL OReadImagesDocumentHandler::processingInstruction(
266 const OUString& /*aTarget*/, const OUString& /*aData*/ )
270 void SAL_CALL OReadImagesDocumentHandler::setDocumentLocator(
271 const Reference< XLocator > &xLocator)
273 SolarMutexGuard g;
274 m_xLocator = xLocator;
277 OUString OReadImagesDocumentHandler::getErrorLineString()
279 SolarMutexGuard g;
280 if ( m_xLocator.is() )
282 OUStringBuffer buffer("Line: ");
283 buffer.append(m_xLocator->getLineNumber());
284 buffer.append(" - ");
285 return buffer.makeStringAndClear();
287 else
288 return OUString();
291 // OWriteImagesDocumentHandler
293 OWriteImagesDocumentHandler::OWriteImagesDocumentHandler(
294 const ImageItemDescriptorList& rItems,
295 Reference< XDocumentHandler > const & rWriteDocumentHandler ) :
296 m_rImageItemList( rItems ),
297 m_xWriteDocumentHandler( rWriteDocumentHandler )
299 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
300 m_xEmptyList.set( static_cast<XAttributeList *>(pList), UNO_QUERY );
301 m_aAttributeType = ATTRIBUTE_TYPE_CDATA;
302 m_aXMLImageNS = XMLNS_IMAGE_PREFIX;
303 m_aAttributeXlinkType = ATTRIBUTE_XLINK_TYPE;
304 m_aAttributeValueSimple = ATTRIBUTE_XLINK_TYPE_VALUE;
307 OWriteImagesDocumentHandler::~OWriteImagesDocumentHandler()
311 void OWriteImagesDocumentHandler::WriteImagesDocument()
313 SolarMutexGuard g;
315 m_xWriteDocumentHandler->startDocument();
317 // write DOCTYPE line!
318 Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
319 if ( xExtendedDocHandler.is() )
321 xExtendedDocHandler->unknown( IMAGES_DOCTYPE );
322 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
325 rtl::Reference<::comphelper::AttributeList> pList = new ::comphelper::AttributeList;
327 pList->AddAttribute( ATTRIBUTE_XMLNS_IMAGE,
328 m_aAttributeType,
329 XMLNS_IMAGE );
331 pList->AddAttribute( ATTRIBUTE_XMLNS_XLINK,
332 m_aAttributeType,
333 XMLNS_XLINK );
335 m_xWriteDocumentHandler->startElement( ELEMENT_NS_IMAGESCONTAINER, pList.get() );
336 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
338 WriteImageList( &m_rImageItemList );
340 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
341 m_xWriteDocumentHandler->endElement( ELEMENT_NS_IMAGESCONTAINER );
342 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
343 m_xWriteDocumentHandler->endDocument();
346 // protected member functions
348 void OWriteImagesDocumentHandler::WriteImageList( const ImageItemDescriptorList* pImageList )
350 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
351 Reference< XAttributeList > xList( static_cast<XAttributeList *>(pList) , UNO_QUERY );
353 // save required attributes
354 pList->AddAttribute( m_aAttributeXlinkType,
355 m_aAttributeType,
356 m_aAttributeValueSimple );
358 m_xWriteDocumentHandler->startElement( ELEMENT_NS_IMAGES, xList );
359 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
361 for (const ImageItemDescriptor & i : *pImageList)
362 WriteImage( &i );
364 m_xWriteDocumentHandler->endElement( ELEMENT_NS_IMAGES );
365 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
368 void OWriteImagesDocumentHandler::WriteImage( const ImageItemDescriptor* pImage )
370 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
371 Reference< XAttributeList > xList( static_cast<XAttributeList *>(pList) , UNO_QUERY );
373 pList->AddAttribute( m_aXMLImageNS + ATTRIBUTE_COMMAND,
374 m_aAttributeType,
375 pImage->aCommandURL );
377 m_xWriteDocumentHandler->startElement( ELEMENT_NS_ENTRY, xList );
378 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
380 m_xWriteDocumentHandler->endElement( ELEMENT_NS_ENTRY );
381 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
384 } // namespace framework
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */