calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / framework / source / xml / imagesdocumenthandler.cxx
blobebdd5366f24037769da36d63b99d2311598ea885
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 <xml/imagesdocumenthandler.hxx>
22 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
23 #include <com/sun/star/xml/sax/SAXException.hpp>
25 #include <rtl/ref.hxx>
26 #include <rtl/ustrbuf.hxx>
28 #include <comphelper/attributelist.hxx>
30 using namespace ::com::sun::star::uno;
31 using namespace ::com::sun::star::xml::sax;
33 #define ELEMENT_IMAGECONTAINER "imagescontainer"
34 #define ELEMENT_IMAGES "images"
35 #define ELEMENT_ENTRY "entry"
36 #define ELEMENT_EXTERNALIMAGES "externalimages"
37 #define ELEMENT_EXTERNALENTRY "externalentry"
39 constexpr OUStringLiteral ELEMENT_NS_IMAGESCONTAINER = u"image:imagescontainer";
40 constexpr OUStringLiteral ELEMENT_NS_IMAGES = u"image:images";
41 constexpr OUStringLiteral ELEMENT_NS_ENTRY = u"image:entry";
43 #define ATTRIBUTE_HREF "href"
44 #define ATTRIBUTE_MASKCOLOR "maskcolor"
45 #define ATTRIBUTE_COMMAND "command"
46 #define ATTRIBUTE_BITMAPINDEX "bitmap-index"
47 #define ATTRIBUTE_MASKURL "maskurl"
48 #define ATTRIBUTE_MASKMODE "maskmode"
49 #define ATTRIBUTE_HIGHCONTRASTURL "highcontrasturl"
50 #define ATTRIBUTE_HIGHCONTRASTMASKURL "highcontrastmaskurl"
51 constexpr OUStringLiteral ATTRIBUTE_TYPE_CDATA = u"CDATA";
53 constexpr OUStringLiteral ATTRIBUTE_XMLNS_IMAGE = u"xmlns:image";
54 constexpr OUStringLiteral ATTRIBUTE_XMLNS_XLINK = u"xmlns:xlink";
56 constexpr OUStringLiteral ATTRIBUTE_XLINK_TYPE = u"xlink:type";
57 constexpr OUStringLiteral ATTRIBUTE_XLINK_TYPE_VALUE = u"simple";
59 constexpr OUStringLiteral XMLNS_IMAGE = u"http://openoffice.org/2001/image";
60 constexpr OUStringLiteral XMLNS_XLINK = u"http://www.w3.org/1999/xlink";
61 constexpr OUStringLiteral XMLNS_IMAGE_PREFIX = u"image:";
63 constexpr OUStringLiteral XMLNS_FILTER_SEPARATOR = u"^";
65 constexpr OUStringLiteral IMAGES_DOCTYPE = u"<!DOCTYPE image:imagecontainer PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"image.dtd\">";
67 namespace framework
70 namespace {
72 struct ImageXMLEntryProperty
74 OReadImagesDocumentHandler::Image_XML_Namespace nNamespace;
75 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 < 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 if (m_bImageContainerStartFound != m_bImageContainerEndFound)
134 OUString aErrorMessage = getErrorLineString() + "No matching start or end element 'image:imagecontainer' found!";
135 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
139 void SAL_CALL OReadImagesDocumentHandler::startElement(
140 const OUString& aName, const Reference< XAttributeList > &xAttribs )
142 ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName );
143 if ( pImageEntry == m_aImageMap.end() )
144 return;
146 switch ( pImageEntry->second )
148 case IMG_ELEMENT_IMAGECONTAINER:
150 // image:imagecontainer element (container element for all further image elements)
151 if ( m_bImageContainerStartFound )
153 OUString aErrorMessage = getErrorLineString() + "Element 'image:imagecontainer' cannot be embedded into 'image:imagecontainer'!";
154 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
157 m_bImageContainerStartFound = true;
159 break;
161 case IMG_ELEMENT_IMAGES:
163 if ( !m_bImageContainerStartFound )
165 OUString aErrorMessage = getErrorLineString() + "Element 'image:images' must be embedded into element 'image:imagecontainer'!";
166 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
169 if ( m_bImagesStartFound )
171 OUString aErrorMessage = getErrorLineString() + "Element 'image:images' cannot be embedded into 'image:images'!";
172 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
175 m_bImagesStartFound = true;
177 break;
179 case IMG_ELEMENT_ENTRY:
181 // Check that image:entry is embedded into image:images!
182 if ( !m_bImagesStartFound )
184 OUString aErrorMessage = getErrorLineString() + "Element 'image:entry' must be embedded into element 'image:images'!";
185 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
188 // Create new image item descriptor
189 ImageItemDescriptor aItem;
191 // Read attributes for this image definition
192 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
194 pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
195 if ( pImageEntry != m_aImageMap.end() )
197 switch ( pImageEntry->second )
199 case IMG_ATTRIBUTE_COMMAND:
201 aItem.aCommandURL = xAttribs->getValueByIndex( n );
203 break;
205 default:
206 break;
211 // Check required attribute "command"
212 if ( aItem.aCommandURL.isEmpty() )
214 OUString aErrorMessage = getErrorLineString() + "Required attribute 'image:command' must have a value!";
215 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
218 m_rImageList.push_back( aItem );
220 break;
222 default:
223 break;
227 void SAL_CALL OReadImagesDocumentHandler::endElement(const OUString& aName)
229 ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName );
230 if ( pImageEntry == m_aImageMap.end() )
231 return;
233 switch ( pImageEntry->second )
235 case IMG_ELEMENT_IMAGECONTAINER:
237 m_bImageContainerEndFound = true;
239 break;
241 case IMG_ELEMENT_IMAGES:
243 m_bImagesStartFound = false;
245 break;
247 default: break;
251 void SAL_CALL OReadImagesDocumentHandler::characters(const OUString&)
255 void SAL_CALL OReadImagesDocumentHandler::ignorableWhitespace(const OUString&)
259 void SAL_CALL OReadImagesDocumentHandler::processingInstruction(
260 const OUString& /*aTarget*/, const OUString& /*aData*/ )
264 void SAL_CALL OReadImagesDocumentHandler::setDocumentLocator(
265 const Reference< XLocator > &xLocator)
267 m_xLocator = xLocator;
270 OUString OReadImagesDocumentHandler::getErrorLineString()
272 if ( m_xLocator.is() )
274 return "Line: " +
275 OUString::number(m_xLocator->getLineNumber()) +
276 " - ";
278 else
279 return OUString();
282 // OWriteImagesDocumentHandler
284 OWriteImagesDocumentHandler::OWriteImagesDocumentHandler(
285 const ImageItemDescriptorList& rItems,
286 Reference< XDocumentHandler > const & rWriteDocumentHandler ) :
287 m_rImageItemList( rItems ),
288 m_xWriteDocumentHandler( rWriteDocumentHandler )
290 m_xEmptyList = new ::comphelper::AttributeList;
291 m_aAttributeType = ATTRIBUTE_TYPE_CDATA;
292 m_aXMLImageNS = XMLNS_IMAGE_PREFIX;
293 m_aAttributeXlinkType = ATTRIBUTE_XLINK_TYPE;
294 m_aAttributeValueSimple = ATTRIBUTE_XLINK_TYPE_VALUE;
297 OWriteImagesDocumentHandler::~OWriteImagesDocumentHandler()
301 void OWriteImagesDocumentHandler::WriteImagesDocument()
303 m_xWriteDocumentHandler->startDocument();
305 // write DOCTYPE line!
306 Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
307 if ( xExtendedDocHandler.is() )
309 xExtendedDocHandler->unknown( IMAGES_DOCTYPE );
310 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
313 rtl::Reference<::comphelper::AttributeList> pList = new ::comphelper::AttributeList;
315 pList->AddAttribute( ATTRIBUTE_XMLNS_IMAGE,
316 m_aAttributeType,
317 XMLNS_IMAGE );
319 pList->AddAttribute( ATTRIBUTE_XMLNS_XLINK,
320 m_aAttributeType,
321 XMLNS_XLINK );
323 m_xWriteDocumentHandler->startElement( ELEMENT_NS_IMAGESCONTAINER, pList );
324 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
326 WriteImageList( &m_rImageItemList );
328 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
329 m_xWriteDocumentHandler->endElement( ELEMENT_NS_IMAGESCONTAINER );
330 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
331 m_xWriteDocumentHandler->endDocument();
334 // protected member functions
336 void OWriteImagesDocumentHandler::WriteImageList( const ImageItemDescriptorList* pImageList )
338 rtl::Reference<::comphelper::AttributeList> pList = new ::comphelper::AttributeList;
340 // save required attributes
341 pList->AddAttribute( m_aAttributeXlinkType,
342 m_aAttributeType,
343 m_aAttributeValueSimple );
345 m_xWriteDocumentHandler->startElement( ELEMENT_NS_IMAGES, pList );
346 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
348 for (const ImageItemDescriptor & i : *pImageList)
349 WriteImage( &i );
351 m_xWriteDocumentHandler->endElement( ELEMENT_NS_IMAGES );
352 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
355 void OWriteImagesDocumentHandler::WriteImage( const ImageItemDescriptor* pImage )
357 rtl::Reference<::comphelper::AttributeList> pList = new ::comphelper::AttributeList;
359 pList->AddAttribute( m_aXMLImageNS + ATTRIBUTE_COMMAND,
360 m_aAttributeType,
361 pImage->aCommandURL );
363 m_xWriteDocumentHandler->startElement( ELEMENT_NS_ENTRY, pList );
364 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
366 m_xWriteDocumentHandler->endElement( ELEMENT_NS_ENTRY );
367 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
370 } // namespace framework
372 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */