1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #include <stdio.h>
28 
29 //_________________________________________________________________________________________________________________
30 //	my own includes
31 //_________________________________________________________________________________________________________________
32 
33 #include <threadhelp/resetableguard.hxx>
34 #include <xml/imagesdocumenthandler.hxx>
35 #include <macros/debug.hxx>
36 
37 //_________________________________________________________________________________________________________________
38 //	interface includes
39 //_________________________________________________________________________________________________________________
40 
41 #ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_
42 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
43 #endif
44 
45 //_________________________________________________________________________________________________________________
46 //	other includes
47 //_________________________________________________________________________________________________________________
48 #include <vcl/svapp.hxx>
49 #include <vcl/toolbox.hxx>
50 #include <rtl/ustrbuf.hxx>
51 
52 #include <comphelper/attributelist.hxx>
53 
54 //_________________________________________________________________________________________________________________
55 //	namespace
56 //_________________________________________________________________________________________________________________
57 
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::xml::sax;
60 
61 #define ELEMENT_IMAGECONTAINER		"imagescontainer"
62 #define ELEMENT_IMAGES				"images"
63 #define ELEMENT_ENTRY				"entry"
64 #define ELEMENT_EXTERNALIMAGES		"externalimages"
65 #define ELEMENT_EXTERNALENTRY		"externalentry"
66 
67 #define ELEMENT_NS_IMAGESCONTAINER	"image:imagescontainer"
68 #define ELEMENT_NS_IMAGES			"image:images"
69 #define ELEMENT_NS_ENTRY			"image:entry"
70 #define ELEMENT_NS_EXTERNALIMAGES	"image:externalimages"
71 #define ELEMENT_NS_EXTERNALENTRY	"image:externalentry"
72 
73 #define ATTRIBUTE_HREF					"href"
74 #define ATTRIBUTE_MASKCOLOR				"maskcolor"
75 #define ATTRIBUTE_COMMAND				"command"
76 #define ATTRIBUTE_BITMAPINDEX			"bitmap-index"
77 #define ATTRIBUTE_MASKURL				"maskurl"
78 #define ATTRIBUTE_MASKMODE				"maskmode"
79 #define ATTRIBUTE_HIGHCONTRASTURL		"highcontrasturl"
80 #define ATTRIBUTE_HIGHCONTRASTMASKURL	"highcontrastmaskurl"
81 #define ATTRIBUTE_TYPE_CDATA			"CDATA"
82 
83 #define ATTRIBUTE_MASKMODE_BITMAP	"maskbitmap"
84 #define ATTRIBUTE_MASKMODE_COLOR	"maskcolor"
85 
86 #define ATTRIBUTE_XMLNS_IMAGE		"xmlns:image"
87 #define ATTRIBUTE_XMLNS_XLINK		"xmlns:xlink"
88 
89 #define ATTRIBUTE_XLINK_TYPE		"xlink:type"
90 #define ATTRIBUTE_XLINK_TYPE_VALUE	"simple"
91 
92 #define XMLNS_IMAGE					"http://openoffice.org/2001/image"
93 #define XMLNS_XLINK					"http://www.w3.org/1999/xlink"
94 #define XMLNS_IMAGE_PREFIX			"image:"
95 #define XMLNS_XLINK_PREFIX			"xlink:"
96 
97 #define XMLNS_FILTER_SEPARATOR		"^"
98 
99 #define IMAGES_DOCTYPE	"<!DOCTYPE image:imagecontainer PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"image.dtd\">"
100 
101 namespace framework
102 {
103 
104 struct ImageXMLEntryProperty
105 {
106 	OReadImagesDocumentHandler::Image_XML_Namespace	nNamespace;
107 	char											aEntryName[20];
108 };
109 
110 ImageXMLEntryProperty ImagesEntries[OReadImagesDocumentHandler::IMG_XML_ENTRY_COUNT] =
111 {
112 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ELEMENT_IMAGECONTAINER			},
113 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ELEMENT_IMAGES					},
114 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ELEMENT_ENTRY					},
115 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ELEMENT_EXTERNALIMAGES			},
116 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ELEMENT_EXTERNALENTRY			},
117 	{ OReadImagesDocumentHandler::IMG_NS_XLINK,	ATTRIBUTE_HREF					},
118 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ATTRIBUTE_MASKCOLOR				},
119 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE,	ATTRIBUTE_COMMAND				},
120     { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_BITMAPINDEX			},
121     { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKURL				},
122     { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKMODE				},
123 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTURL		},
124 	{ OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTMASKURL	}
125 };
126 
127 
128 OReadImagesDocumentHandler::OReadImagesDocumentHandler( ImageListsDescriptor& aItems ) :
129 	ThreadHelpBase( &Application::GetSolarMutex() ),
130 	m_aImageList( aItems ),
131 	m_pImages( 0 ),
132 	m_pExternalImages( 0 )
133 {
134 	m_aImageList.pImageList			= NULL;
135 	m_aImageList.pExternalImageList = NULL;
136 
137 	m_nHashMaskModeBitmap	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )).hashCode();
138 	m_nHashMaskModeColor	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )).hashCode();
139 
140 	// create hash map to speed up lookup
141 	for ( int i = 0; i < (int)IMG_XML_ENTRY_COUNT; i++ )
142 	{
143 		::rtl::OUStringBuffer temp( 20 );
144 
145 		if ( ImagesEntries[i].nNamespace == IMG_NS_IMAGE )
146 			temp.appendAscii( XMLNS_IMAGE );
147 		else
148 			temp.appendAscii( XMLNS_XLINK );
149 
150 		temp.appendAscii( XMLNS_FILTER_SEPARATOR );
151 		temp.appendAscii( ImagesEntries[i].aEntryName );
152 		m_aImageMap.insert( ImageHashMap::value_type( temp.makeStringAndClear(), (Image_XML_Entry)i ) );
153 	}
154 
155 	// reset states
156 	m_bImageContainerStartFound		= sal_False;
157 	m_bImageContainerEndFound		= sal_False;
158 	m_bImagesStartFound				= sal_False;
159 	m_bImagesEndFound				= sal_False;
160 	m_bImageStartFound				= sal_False;
161 	m_bExternalImagesStartFound		= sal_False;
162 	m_bExternalImagesEndFound		= sal_False;
163 	m_bExternalImageStartFound		= sal_False;
164 }
165 
166 OReadImagesDocumentHandler::~OReadImagesDocumentHandler()
167 {
168 }
169 
170 // XDocumentHandler
171 void SAL_CALL OReadImagesDocumentHandler::startDocument(void)
172 throw (	SAXException, RuntimeException )
173 {
174 }
175 
176 void SAL_CALL OReadImagesDocumentHandler::endDocument(void)
177 throw(	SAXException, RuntimeException )
178 {
179 	ResetableGuard aGuard( m_aLock );
180 
181 	if (( m_bImageContainerStartFound && !m_bImageContainerEndFound ) ||
182 		( !m_bImageContainerStartFound && m_bImageContainerEndFound )	 )
183 	{
184 		::rtl::OUString aErrorMessage = getErrorLineString();
185 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'image:imagecontainer' found!" ));
186 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
187 	}
188 }
189 
190 void SAL_CALL OReadImagesDocumentHandler::startElement(
191 	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
192 throw(	SAXException, RuntimeException )
193 {
194 	ResetableGuard aGuard( m_aLock );
195 
196 	ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ;
197 	if ( pImageEntry != m_aImageMap.end() )
198 	{
199 		switch ( pImageEntry->second )
200 		{
201 			case IMG_ELEMENT_IMAGECONTAINER:
202 			{
203 				// image:imagecontainer element (container element for all further image elements)
204 				if ( m_bImageContainerStartFound )
205 				{
206 					::rtl::OUString aErrorMessage = getErrorLineString();
207 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:imagecontainer' cannot be embedded into 'image:imagecontainer'!" ));
208 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
209 				}
210 
211 				m_bImageContainerStartFound = sal_True;
212 			}
213 			break;
214 
215 			case IMG_ELEMENT_IMAGES:
216 			{
217 				if ( !m_bImageContainerStartFound )
218 				{
219 					::rtl::OUString aErrorMessage = getErrorLineString();
220 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' must be embedded into element 'image:imagecontainer'!" ));
221 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
222 				}
223 
224 				if ( m_bImagesStartFound )
225 				{
226 					::rtl::OUString aErrorMessage = getErrorLineString();
227 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' cannot be embedded into 'image:images'!" ));
228 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
229 				}
230 
231 				if ( !m_aImageList.pImageList )
232 					m_aImageList.pImageList = new ImageListDescriptor;
233 
234 				m_bImagesStartFound = sal_True;
235 				m_pImages = new ImageListItemDescriptor;
236 
237 				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
238 				{
239 					pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
240 					if ( pImageEntry != m_aImageMap.end() )
241 					{
242 						switch ( pImageEntry->second )
243 						{
244 							case IMG_ATTRIBUTE_HREF:
245 							{
246 								m_pImages->aURL = xAttribs->getValueByIndex( n );
247 							}
248 							break;
249 
250 							case IMG_ATTRIBUTE_MASKCOLOR:
251 							{
252 								::rtl::OUString aColor = xAttribs->getValueByIndex( n );
253 
254 								if ( aColor.getLength() > 0 )
255 								{
256 									if ( aColor.getStr()[0] == '#' )
257 									{
258 										// the color value is given as #rrggbb and used the hexadecimal system!!
259 										sal_uInt32 nColor = aColor.copy( 1 ).toInt32( 16 );
260 
261 										m_pImages->aMaskColor = Color( COLORDATA_RGB( nColor ) );
262 									}
263 								}
264 							}
265 							break;
266 
267 							case IMG_ATTRIBUTE_MASKURL:
268 							{
269 								m_pImages->aMaskURL = xAttribs->getValueByIndex( n );
270 							}
271 							break;
272 
273 							case IMG_ATTRIBUTE_MASKMODE:
274 							{
275 								sal_Int32 nHashCode = xAttribs->getValueByIndex( n ).hashCode();
276 								if ( nHashCode == m_nHashMaskModeBitmap )
277 									m_pImages->nMaskMode = ImageMaskMode_Bitmap;
278 								else if ( nHashCode == m_nHashMaskModeColor )
279 									m_pImages->nMaskMode = ImageMaskMode_Color;
280 								else
281 								{
282 									delete m_pImages;
283 									m_pImages = NULL;
284 
285 									::rtl::OUString aErrorMessage = getErrorLineString();
286 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute image:maskmode must be 'maskcolor' or 'maskbitmap'!" ));
287 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
288 								}
289 							}
290 							break;
291 
292 							case IMG_ATTRIBUTE_HIGHCONTRASTURL:
293 							{
294 								m_pImages->aHighContrastURL = xAttribs->getValueByIndex( n );
295 							}
296 							break;
297 
298 							case IMG_ATTRIBUTE_HIGHCONTRASTMASKURL:
299 							{
300 								m_pImages->aHighContrastMaskURL = xAttribs->getValueByIndex( n );
301 							}
302 							break;
303 
304                                           default:
305                                               break;
306 						}
307 					}
308 				} // for
309 
310 				if ( m_pImages->aURL.Len() == 0 )
311 				{
312 					delete m_pImages;
313 					m_pImages = NULL;
314 
315 					::rtl::OUString aErrorMessage = getErrorLineString();
316 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute xlink:href must have a value!" ));
317 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
318 				}
319 			}
320 			break;
321 
322 			case IMG_ELEMENT_ENTRY:
323 			{
324 				// Check that image:entry is embedded into image:images!
325 				if ( !m_bImagesStartFound )
326 				{
327 					delete m_pImages;
328 					m_pImages = NULL;
329 
330 					::rtl::OUString aErrorMessage = getErrorLineString();
331 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:entry' must be embedded into element 'image:images'!" ));
332 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
333 				}
334 
335 				if ( !m_pImages->pImageItemList )
336 					m_pImages->pImageItemList = new ImageItemListDescriptor;
337 
338 				m_bImageStartFound = sal_True;
339 
340 				// Create new image item descriptor
341 				ImageItemDescriptor* pItem = new ImageItemDescriptor;
342 				pItem->nIndex = -1;
343 
344 				// Read attributes for this image definition
345 				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
346 				{
347 					pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
348 					if ( pImageEntry != m_aImageMap.end() )
349 					{
350 						switch ( pImageEntry->second )
351 						{
352 							case IMG_ATTRIBUTE_COMMAND:
353 							{
354 								pItem->aCommandURL	= xAttribs->getValueByIndex( n );
355 							}
356 							break;
357 
358 							case IMG_ATTRIBUTE_BITMAPINDEX:
359 							{
360 								pItem->nIndex		= xAttribs->getValueByIndex( n ).toInt32();
361 							}
362 							break;
363 
364                                           default:
365                                               break;
366 						}
367 					}
368 				}
369 
370 				// Check required attribute "bitmap-index"
371 				if ( pItem->nIndex < 0 )
372 				{
373 					delete pItem;
374 					delete m_pImages;
375 					m_pImages = NULL;
376 
377 					::rtl::OUString aErrorMessage = getErrorLineString();
378 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:bitmap-index' must have a value >= 0!" ));
379 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
380 				}
381 
382 				// Check required attribute "command"
383 				if ( pItem->aCommandURL.Len() == 0 )
384 				{
385 					delete pItem;
386 					delete m_pImages;
387 					m_pImages = NULL;
388 
389 					::rtl::OUString aErrorMessage = getErrorLineString();
390 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" ));
391 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
392 				}
393 
394 				if ( m_pImages )
395 					m_pImages->pImageItemList->Insert( pItem, m_pImages->pImageItemList->Count() );
396 			}
397 			break;
398 
399 			case IMG_ELEMENT_EXTERNALIMAGES:
400 			{
401 				// Check that image:externalimages is embedded into image:imagecontainer
402 				if ( !m_bImageContainerStartFound )
403 				{
404 					delete m_pImages;
405 					m_pImages = NULL;
406 
407 					::rtl::OUString aErrorMessage = getErrorLineString();
408 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' must be embedded into element 'image:imagecontainer'!" ));
409 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
410 				}
411 
412 				// Check that image:externalentry is NOT embedded into image:externalentry
413 				if ( m_bExternalImagesStartFound )
414 				{
415 					delete m_pImages;
416 					m_pImages = NULL;
417 
418 					::rtl::OUString aErrorMessage = getErrorLineString();
419 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' cannot be embedded into 'image:externalimages'!" ));
420 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
421 				}
422 
423 				// Create unique external image container
424 				m_bExternalImagesStartFound = sal_True;
425 				m_pExternalImages = new ExternalImageItemListDescriptor;
426 			}
427 			break;
428 
429 			case IMG_ELEMENT_EXTERNALENTRY:
430 			{
431 				if ( !m_bExternalImagesStartFound )
432 				{
433 					delete m_pImages;
434 					delete m_pExternalImages;
435 					m_pImages = NULL;
436 					m_pExternalImages = NULL;
437 
438 					::rtl::OUString aErrorMessage = getErrorLineString();
439 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' must be embedded into 'image:externalimages'!" ));
440 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
441 				}
442 
443 				if ( m_bExternalImageStartFound )
444 				{
445 					delete m_pImages;
446 					delete m_pExternalImages;
447 					m_pImages = NULL;
448 					m_pExternalImages = NULL;
449 
450 					::rtl::OUString aErrorMessage = getErrorLineString();
451 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' cannot be embedded into 'image:externalentry'!" ));
452 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
453 				}
454 
455 				m_bExternalImageStartFound = sal_True;
456 
457 				ExternalImageItemDescriptor* pItem = new ExternalImageItemDescriptor;
458 
459 				// Read attributes for this external image definition
460 				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
461 				{
462 					pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
463 					if ( pImageEntry != m_aImageMap.end() )
464 					{
465 						switch ( pImageEntry->second )
466 						{
467 							case IMG_ATTRIBUTE_COMMAND:
468 							{
469 								pItem->aCommandURL	= xAttribs->getValueByIndex( n );
470 							}
471 							break;
472 
473 							case IMG_ATTRIBUTE_HREF:
474 							{
475 								pItem->aURL			= xAttribs->getValueByIndex( n );
476 							}
477 							break;
478 
479                                           default:
480                                               break;
481 						}
482 					}
483 				}
484 
485 				// Check required attribute "command"
486 				if ( pItem->aCommandURL.Len() == 0 )
487 				{
488 					delete pItem;
489 					delete m_pImages;
490 					delete m_pExternalImages;
491 					m_pImages = NULL;
492 					m_pExternalImages = NULL;
493 
494 					::rtl::OUString aErrorMessage = getErrorLineString();
495 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" ));
496 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
497 				}
498 
499 				// Check required attribute "href"
500 				if ( pItem->aURL.Len() == 0 )
501 				{
502 					delete pItem;
503 					delete m_pImages;
504 					delete m_pExternalImages;
505 					m_pImages = NULL;
506 					m_pExternalImages = NULL;
507 
508 					::rtl::OUString aErrorMessage = getErrorLineString();
509 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'xlink:href' must have a value!" ));
510 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
511 				}
512 
513 				if ( m_pExternalImages )
514 					m_pExternalImages->Insert( pItem, m_pExternalImages->Count() );
515 			}
516 			break;
517 
518                   default:
519                       break;
520 		}
521 	}
522 }
523 
524 void SAL_CALL OReadImagesDocumentHandler::endElement(const ::rtl::OUString& aName)
525 throw(	SAXException, RuntimeException )
526 {
527 	ResetableGuard aGuard( m_aLock );
528 
529 	ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ;
530 	if ( pImageEntry != m_aImageMap.end() )
531 	{
532 		switch ( pImageEntry->second )
533 		{
534 			case IMG_ELEMENT_IMAGECONTAINER:
535 			{
536 				m_bImageContainerEndFound = sal_True;
537 			}
538 			break;
539 
540 			case IMG_ELEMENT_IMAGES:
541 			{
542 				if ( m_pImages )
543 				{
544 					if ( m_aImageList.pImageList )
545 						m_aImageList.pImageList->Insert( m_pImages, m_aImageList.pImageList->Count() );
546 					m_pImages = NULL;
547 				}
548 				m_bImagesStartFound = sal_False;
549 			}
550 			break;
551 
552 			case IMG_ELEMENT_ENTRY:
553 			{
554 				m_bImageStartFound = sal_False;
555 			}
556 			break;
557 
558 			case IMG_ELEMENT_EXTERNALIMAGES:
559 			{
560 				if ( m_pExternalImages && !m_aImageList.pExternalImageList )
561 				{
562 					if ( !m_aImageList.pExternalImageList )
563 						m_aImageList.pExternalImageList = m_pExternalImages;
564 				}
565 
566 				m_bExternalImagesStartFound = sal_False;
567 				m_pExternalImages = NULL;
568 			}
569 			break;
570 
571 			case IMG_ELEMENT_EXTERNALENTRY:
572 			{
573 				m_bExternalImageStartFound = sal_False;
574 			}
575 			break;
576 
577                   default:
578                       break;
579 		}
580 	}
581 }
582 
583 void SAL_CALL OReadImagesDocumentHandler::characters(const ::rtl::OUString&)
584 throw(	SAXException, RuntimeException )
585 {
586 }
587 
588 void SAL_CALL OReadImagesDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
589 throw(	SAXException, RuntimeException )
590 {
591 }
592 
593 void SAL_CALL OReadImagesDocumentHandler::processingInstruction(
594 	const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
595 throw(	SAXException, RuntimeException )
596 {
597 }
598 
599 void SAL_CALL OReadImagesDocumentHandler::setDocumentLocator(
600 	const Reference< XLocator > &xLocator)
601 throw(	SAXException, RuntimeException )
602 {
603 	ResetableGuard aGuard( m_aLock );
604 
605 	m_xLocator = xLocator;
606 }
607 
608 ::rtl::OUString OReadImagesDocumentHandler::getErrorLineString()
609 {
610 	ResetableGuard aGuard( m_aLock );
611 
612 	char buffer[32];
613 
614 	if ( m_xLocator.is() )
615 	{
616 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
617 		return ::rtl::OUString::createFromAscii( buffer );
618 	}
619 	else
620 		return ::rtl::OUString();
621 }
622 
623 
624 //_________________________________________________________________________________________________________________
625 //	OWriteImagesDocumentHandler
626 //_________________________________________________________________________________________________________________
627 
628 OWriteImagesDocumentHandler::OWriteImagesDocumentHandler(
629 	const ImageListsDescriptor& aItems,
630 	Reference< XDocumentHandler > rWriteDocumentHandler ) :
631     ThreadHelpBase( &Application::GetSolarMutex() ),
632 	m_aImageListsItems( aItems ),
633 	m_xWriteDocumentHandler( rWriteDocumentHandler )
634 {
635 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
636 	m_xEmptyList			= Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
637 	m_aAttributeType		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
638 	m_aXMLImageNS			= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE_PREFIX ));
639 	m_aXMLXlinkNS			= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
640 	m_aAttributeXlinkType	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE ));
641 	m_aAttributeValueSimple = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE_VALUE ));
642 }
643 
644 OWriteImagesDocumentHandler::~OWriteImagesDocumentHandler()
645 {
646 }
647 
648 void OWriteImagesDocumentHandler::WriteImagesDocument() throw
649 ( SAXException, RuntimeException )
650 {
651 	ResetableGuard aGuard( m_aLock );
652 
653 	m_xWriteDocumentHandler->startDocument();
654 
655 	// write DOCTYPE line!
656 	Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
657 	if ( xExtendedDocHandler.is() )
658 	{
659 		xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMAGES_DOCTYPE )) );
660 		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
661 	}
662 
663 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
664 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
665 
666 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_IMAGE )),
667 						 m_aAttributeType,
668 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE )) );
669 
670 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
671 						 m_aAttributeType,
672 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
673 
674 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )), pList );
675 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
676 
677 	if ( m_aImageListsItems.pImageList )
678 	{
679 		ImageListDescriptor* pImageList = m_aImageListsItems.pImageList;
680 
681 		for ( sal_uInt16 i = 0; i < m_aImageListsItems.pImageList->Count(); i++ )
682 		{
683 			const ImageListItemDescriptor* pImageItems = (*pImageList)[i];
684 			WriteImageList( pImageItems );
685 		}
686 	}
687 
688 	if ( m_aImageListsItems.pExternalImageList )
689 	{
690 		WriteExternalImageList( m_aImageListsItems.pExternalImageList );
691 	}
692 
693 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
694 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )) );
695 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
696 	m_xWriteDocumentHandler->endDocument();
697 }
698 
699 //_________________________________________________________________________________________________________________
700 //	protected member functions
701 //_________________________________________________________________________________________________________________
702 
703 void OWriteImagesDocumentHandler::WriteImageList( const ImageListItemDescriptor* pImageList ) throw
704 ( SAXException, RuntimeException )
705 {
706 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
707 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
708 
709     // save required attributes
710 	pList->AddAttribute( m_aAttributeXlinkType,
711 						 m_aAttributeType,
712 						 m_aAttributeValueSimple );
713 
714 	pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )),
715 						 m_aAttributeType,
716 						 pImageList->aURL );
717 
718 	if ( pImageList->nMaskMode == ImageMaskMode_Bitmap )
719 	{
720 		pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )),
721 							 m_aAttributeType,
722 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )) );
723 
724 		pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKURL )),
725 							 m_aAttributeType,
726 							 pImageList->aMaskURL );
727 
728 		if ( pImageList->aHighContrastMaskURL.Len() > 0 )
729 		{
730 			pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTMASKURL )),
731 								 m_aAttributeType,
732 								 pImageList->aHighContrastMaskURL );
733 		}
734 	}
735 	else
736 	{
737 		::rtl::OUStringBuffer	aColorStrBuffer( 8 );
738 		sal_Int64		nValue = pImageList->aMaskColor.GetRGBColor();
739 
740 		aColorStrBuffer.appendAscii( "#" );
741 		aColorStrBuffer.append( ::rtl::OUString::valueOf( nValue, 16 ));
742 
743 		pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKCOLOR )),
744 							 m_aAttributeType,
745 							 aColorStrBuffer.makeStringAndClear() );
746 
747 		pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )),
748 							 m_aAttributeType,
749 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )) );
750 	}
751 
752 	if ( pImageList->aHighContrastURL.Len() > 0 )
753 	{
754 		pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTURL )),
755 							 m_aAttributeType,
756 							 pImageList->aHighContrastURL );
757 	}
758 
759     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )), xList );
760     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
761 
762 	ImageItemListDescriptor* pImageItemList = pImageList->pImageItemList;
763 	if ( pImageItemList )
764 	{
765 		for ( sal_uInt16 i = 0; i < pImageItemList->Count(); i++ )
766 			WriteImage( (*pImageItemList)[i] );
767 	}
768 
769 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )) );
770 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
771 }
772 
773 void OWriteImagesDocumentHandler::WriteImage( const ImageItemDescriptor* pImage ) throw
774 ( SAXException, RuntimeException )
775 {
776 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
777 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
778 
779 	pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BITMAPINDEX )),
780 						 m_aAttributeType,
781 						 ::rtl::OUString::valueOf( (sal_Int32)pImage->nIndex ) );
782 
783 	pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )),
784 						 m_aAttributeType,
785 						 pImage->aCommandURL );
786 
787 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )), xList );
788 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
789 
790 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )) );
791 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
792 }
793 
794 void OWriteImagesDocumentHandler::WriteExternalImageList( const ExternalImageItemListDescriptor* pExternalImageList ) throw
795 ( SAXException, RuntimeException )
796 {
797 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )), m_xEmptyList );
798 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
799 
800 	for ( sal_uInt16 i = 0; i < pExternalImageList->Count(); i++ )
801 	{
802 		ExternalImageItemDescriptor* pItem = (*pExternalImageList)[i];
803 		WriteExternalImage( pItem );
804 	}
805 
806 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
807 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )) );
808 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
809 }
810 
811 void OWriteImagesDocumentHandler::WriteExternalImage( const ExternalImageItemDescriptor* pExternalImage ) throw
812 ( SAXException, RuntimeException )
813 {
814 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
815 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
816 
817     // save required attributes
818 	pList->AddAttribute( m_aAttributeXlinkType,
819 						 m_aAttributeType,
820 						 m_aAttributeValueSimple );
821 
822 	if ( pExternalImage->aURL.Len() > 0 )
823 	{
824 		pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )),
825 							 m_aAttributeType,
826 							 pExternalImage->aURL );
827 	}
828 
829 	if ( pExternalImage->aCommandURL.Len() > 0 )
830 	{
831 		pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )),
832 							 m_aAttributeType,
833 							 pExternalImage->aCommandURL );
834 	}
835 
836 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )), xList );
837 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
838 
839 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )) );
840 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
841 }
842 
843 } // namespace framework
844 
845 
846 
847 
848