xref: /trunk/main/framework/source/xml/imagesdocumenthandler.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 
OReadImagesDocumentHandler(ImageListsDescriptor & aItems)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 
~OReadImagesDocumentHandler()166 OReadImagesDocumentHandler::~OReadImagesDocumentHandler()
167 {
168 }
169 
170 // XDocumentHandler
startDocument(void)171 void SAL_CALL OReadImagesDocumentHandler::startDocument(void)
172 {
173 }
174 
endDocument(void)175 void SAL_CALL OReadImagesDocumentHandler::endDocument(void)
176 {
177     ResetableGuard aGuard( m_aLock );
178 
179     if (( m_bImageContainerStartFound && !m_bImageContainerEndFound ) ||
180         ( !m_bImageContainerStartFound && m_bImageContainerEndFound )    )
181     {
182         ::rtl::OUString aErrorMessage = getErrorLineString();
183         aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'image:imagecontainer' found!" ));
184         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
185     }
186 }
187 
startElement(const::rtl::OUString & aName,const Reference<XAttributeList> & xAttribs)188 void SAL_CALL OReadImagesDocumentHandler::startElement(
189     const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
190 {
191     ResetableGuard aGuard( m_aLock );
192 
193     ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ;
194     if ( pImageEntry != m_aImageMap.end() )
195     {
196         switch ( pImageEntry->second )
197         {
198             case IMG_ELEMENT_IMAGECONTAINER:
199             {
200                 // image:imagecontainer element (container element for all further image elements)
201                 if ( m_bImageContainerStartFound )
202                 {
203                     ::rtl::OUString aErrorMessage = getErrorLineString();
204                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:imagecontainer' cannot be embedded into 'image:imagecontainer'!" ));
205                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
206                 }
207 
208                 m_bImageContainerStartFound = sal_True;
209             }
210             break;
211 
212             case IMG_ELEMENT_IMAGES:
213             {
214                 if ( !m_bImageContainerStartFound )
215                 {
216                     ::rtl::OUString aErrorMessage = getErrorLineString();
217                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' must be embedded into element 'image:imagecontainer'!" ));
218                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
219                 }
220 
221                 if ( m_bImagesStartFound )
222                 {
223                     ::rtl::OUString aErrorMessage = getErrorLineString();
224                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' cannot be embedded into 'image:images'!" ));
225                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
226                 }
227 
228                 if ( !m_aImageList.pImageList )
229                     m_aImageList.pImageList = new ImageListDescriptor;
230 
231                 m_bImagesStartFound = sal_True;
232                 m_pImages = new ImageListItemDescriptor;
233 
234                 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
235                 {
236                     pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
237                     if ( pImageEntry != m_aImageMap.end() )
238                     {
239                         switch ( pImageEntry->second )
240                         {
241                             case IMG_ATTRIBUTE_HREF:
242                             {
243                                 m_pImages->aURL = xAttribs->getValueByIndex( n );
244                             }
245                             break;
246 
247                             case IMG_ATTRIBUTE_MASKCOLOR:
248                             {
249                                 ::rtl::OUString aColor = xAttribs->getValueByIndex( n );
250 
251                                 if ( aColor.getLength() > 0 )
252                                 {
253                                     if ( aColor.getStr()[0] == '#' )
254                                     {
255                                         // the color value is given as #rrggbb and uses the hexadecimal system!
256                                         sal_uInt32 nColor = aColor.copy( 1 ).toInt32( 16 );
257 
258                                         m_pImages->aMaskColor = Color( COLORDATA_RGB( nColor ) );
259                                     }
260                                 }
261                             }
262                             break;
263 
264                             case IMG_ATTRIBUTE_MASKURL:
265                             {
266                                 m_pImages->aMaskURL = xAttribs->getValueByIndex( n );
267                             }
268                             break;
269 
270                             case IMG_ATTRIBUTE_MASKMODE:
271                             {
272                                 sal_Int32 nHashCode = xAttribs->getValueByIndex( n ).hashCode();
273                                 if ( nHashCode == m_nHashMaskModeBitmap )
274                                     m_pImages->nMaskMode = ImageMaskMode_Bitmap;
275                                 else if ( nHashCode == m_nHashMaskModeColor )
276                                     m_pImages->nMaskMode = ImageMaskMode_Color;
277                                 else
278                                 {
279                                     delete m_pImages;
280                                     m_pImages = NULL;
281 
282                                     ::rtl::OUString aErrorMessage = getErrorLineString();
283                                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute image:maskmode must be 'maskcolor' or 'maskbitmap'!" ));
284                                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
285                                 }
286                             }
287                             break;
288 
289                             case IMG_ATTRIBUTE_HIGHCONTRASTURL:
290                             {
291                                 m_pImages->aHighContrastURL = xAttribs->getValueByIndex( n );
292                             }
293                             break;
294 
295                             case IMG_ATTRIBUTE_HIGHCONTRASTMASKURL:
296                             {
297                                 m_pImages->aHighContrastMaskURL = xAttribs->getValueByIndex( n );
298                             }
299                             break;
300 
301                                           default:
302                                               break;
303                         }
304                     }
305                 } // for
306 
307                 if ( m_pImages->aURL.Len() == 0 )
308                 {
309                     delete m_pImages;
310                     m_pImages = NULL;
311 
312                     ::rtl::OUString aErrorMessage = getErrorLineString();
313                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute xlink:href must have a value!" ));
314                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
315                 }
316             }
317             break;
318 
319             case IMG_ELEMENT_ENTRY:
320             {
321                 // Check that image:entry is embedded into image:images!
322                 if ( !m_bImagesStartFound )
323                 {
324                     delete m_pImages;
325                     m_pImages = NULL;
326 
327                     ::rtl::OUString aErrorMessage = getErrorLineString();
328                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:entry' must be embedded into element 'image:images'!" ));
329                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
330                 }
331 
332                 if ( !m_pImages->pImageItemList )
333                     m_pImages->pImageItemList = new ImageItemListDescriptor;
334 
335                 m_bImageStartFound = sal_True;
336 
337                 // Create new image item descriptor
338                 ImageItemDescriptor* pItem = new ImageItemDescriptor;
339                 pItem->nIndex = -1;
340 
341                 // Read attributes for this image definition
342                 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
343                 {
344                     pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
345                     if ( pImageEntry != m_aImageMap.end() )
346                     {
347                         switch ( pImageEntry->second )
348                         {
349                             case IMG_ATTRIBUTE_COMMAND:
350                             {
351                                 pItem->aCommandURL  = xAttribs->getValueByIndex( n );
352                             }
353                             break;
354 
355                             case IMG_ATTRIBUTE_BITMAPINDEX:
356                             {
357                                 pItem->nIndex       = xAttribs->getValueByIndex( n ).toInt32();
358                             }
359                             break;
360 
361                                           default:
362                                               break;
363                         }
364                     }
365                 }
366 
367                 // Check required attribute "bitmap-index"
368                 if ( pItem->nIndex < 0 )
369                 {
370                     delete pItem;
371                     delete m_pImages;
372                     m_pImages = NULL;
373 
374                     ::rtl::OUString aErrorMessage = getErrorLineString();
375                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:bitmap-index' must have a value >= 0!" ));
376                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
377                 }
378 
379                 // Check required attribute "command"
380                 if ( pItem->aCommandURL.Len() == 0 )
381                 {
382                     delete pItem;
383                     delete m_pImages;
384                     m_pImages = NULL;
385 
386                     ::rtl::OUString aErrorMessage = getErrorLineString();
387                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" ));
388                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
389                 }
390 
391                 if ( m_pImages )
392                     m_pImages->pImageItemList->Insert( pItem, m_pImages->pImageItemList->Count() );
393             }
394             break;
395 
396             case IMG_ELEMENT_EXTERNALIMAGES:
397             {
398                 // Check that image:externalimages is embedded into image:imagecontainer
399                 if ( !m_bImageContainerStartFound )
400                 {
401                     delete m_pImages;
402                     m_pImages = NULL;
403 
404                     ::rtl::OUString aErrorMessage = getErrorLineString();
405                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' must be embedded into element 'image:imagecontainer'!" ));
406                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
407                 }
408 
409                 // Check that image:externalentry is NOT embedded into image:externalentry
410                 if ( m_bExternalImagesStartFound )
411                 {
412                     delete m_pImages;
413                     m_pImages = NULL;
414 
415                     ::rtl::OUString aErrorMessage = getErrorLineString();
416                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' cannot be embedded into 'image:externalimages'!" ));
417                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
418                 }
419 
420                 // Create unique external image container
421                 m_bExternalImagesStartFound = sal_True;
422                 m_pExternalImages = new ExternalImageItemListDescriptor;
423             }
424             break;
425 
426             case IMG_ELEMENT_EXTERNALENTRY:
427             {
428                 if ( !m_bExternalImagesStartFound )
429                 {
430                     delete m_pImages;
431                     delete m_pExternalImages;
432                     m_pImages = NULL;
433                     m_pExternalImages = NULL;
434 
435                     ::rtl::OUString aErrorMessage = getErrorLineString();
436                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' must be embedded into 'image:externalimages'!" ));
437                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
438                 }
439 
440                 if ( m_bExternalImageStartFound )
441                 {
442                     delete m_pImages;
443                     delete m_pExternalImages;
444                     m_pImages = NULL;
445                     m_pExternalImages = NULL;
446 
447                     ::rtl::OUString aErrorMessage = getErrorLineString();
448                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' cannot be embedded into 'image:externalentry'!" ));
449                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
450                 }
451 
452                 m_bExternalImageStartFound = sal_True;
453 
454                 ExternalImageItemDescriptor* pItem = new ExternalImageItemDescriptor;
455 
456                 // Read attributes for this external image definition
457                 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
458                 {
459                     pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
460                     if ( pImageEntry != m_aImageMap.end() )
461                     {
462                         switch ( pImageEntry->second )
463                         {
464                             case IMG_ATTRIBUTE_COMMAND:
465                             {
466                                 pItem->aCommandURL  = xAttribs->getValueByIndex( n );
467                             }
468                             break;
469 
470                             case IMG_ATTRIBUTE_HREF:
471                             {
472                                 pItem->aURL         = xAttribs->getValueByIndex( n );
473                             }
474                             break;
475 
476                                           default:
477                                               break;
478                         }
479                     }
480                 }
481 
482                 // Check required attribute "command"
483                 if ( pItem->aCommandURL.Len() == 0 )
484                 {
485                     delete pItem;
486                     delete m_pImages;
487                     delete m_pExternalImages;
488                     m_pImages = NULL;
489                     m_pExternalImages = NULL;
490 
491                     ::rtl::OUString aErrorMessage = getErrorLineString();
492                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" ));
493                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
494                 }
495 
496                 // Check required attribute "href"
497                 if ( pItem->aURL.Len() == 0 )
498                 {
499                     delete pItem;
500                     delete m_pImages;
501                     delete m_pExternalImages;
502                     m_pImages = NULL;
503                     m_pExternalImages = NULL;
504 
505                     ::rtl::OUString aErrorMessage = getErrorLineString();
506                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'xlink:href' must have a value!" ));
507                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
508                 }
509 
510                 if ( m_pExternalImages )
511                     m_pExternalImages->Insert( pItem, m_pExternalImages->Count() );
512             }
513             break;
514 
515                   default:
516                       break;
517         }
518     }
519 }
520 
endElement(const::rtl::OUString & aName)521 void SAL_CALL OReadImagesDocumentHandler::endElement(const ::rtl::OUString& aName)
522 {
523     ResetableGuard aGuard( m_aLock );
524 
525     ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ;
526     if ( pImageEntry != m_aImageMap.end() )
527     {
528         switch ( pImageEntry->second )
529         {
530             case IMG_ELEMENT_IMAGECONTAINER:
531             {
532                 m_bImageContainerEndFound = sal_True;
533             }
534             break;
535 
536             case IMG_ELEMENT_IMAGES:
537             {
538                 if ( m_pImages )
539                 {
540                     if ( m_aImageList.pImageList )
541                         m_aImageList.pImageList->Insert( m_pImages, m_aImageList.pImageList->Count() );
542                     m_pImages = NULL;
543                 }
544                 m_bImagesStartFound = sal_False;
545             }
546             break;
547 
548             case IMG_ELEMENT_ENTRY:
549             {
550                 m_bImageStartFound = sal_False;
551             }
552             break;
553 
554             case IMG_ELEMENT_EXTERNALIMAGES:
555             {
556                 if ( m_pExternalImages && !m_aImageList.pExternalImageList )
557                 {
558                     if ( !m_aImageList.pExternalImageList )
559                         m_aImageList.pExternalImageList = m_pExternalImages;
560                 }
561 
562                 m_bExternalImagesStartFound = sal_False;
563                 m_pExternalImages = NULL;
564             }
565             break;
566 
567             case IMG_ELEMENT_EXTERNALENTRY:
568             {
569                 m_bExternalImageStartFound = sal_False;
570             }
571             break;
572 
573                   default:
574                       break;
575         }
576     }
577 }
578 
characters(const::rtl::OUString &)579 void SAL_CALL OReadImagesDocumentHandler::characters(const ::rtl::OUString&)
580 {
581 }
582 
ignorableWhitespace(const::rtl::OUString &)583 void SAL_CALL OReadImagesDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
584 {
585 }
586 
processingInstruction(const::rtl::OUString &,const::rtl::OUString &)587 void SAL_CALL OReadImagesDocumentHandler::processingInstruction(
588     const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
589 {
590 }
591 
setDocumentLocator(const Reference<XLocator> & xLocator)592 void SAL_CALL OReadImagesDocumentHandler::setDocumentLocator(
593     const Reference< XLocator > &xLocator)
594 {
595     ResetableGuard aGuard( m_aLock );
596 
597     m_xLocator = xLocator;
598 }
599 
getErrorLineString()600 ::rtl::OUString OReadImagesDocumentHandler::getErrorLineString()
601 {
602     ResetableGuard aGuard( m_aLock );
603 
604     char buffer[32];
605 
606     if ( m_xLocator.is() )
607     {
608         snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
609         return ::rtl::OUString::createFromAscii( buffer );
610     }
611     else
612         return ::rtl::OUString();
613 }
614 
615 
616 //_________________________________________________________________________________________________________________
617 //  OWriteImagesDocumentHandler
618 //_________________________________________________________________________________________________________________
619 
OWriteImagesDocumentHandler(const ImageListsDescriptor & aItems,Reference<XDocumentHandler> rWriteDocumentHandler)620 OWriteImagesDocumentHandler::OWriteImagesDocumentHandler(
621     const ImageListsDescriptor& aItems,
622     Reference< XDocumentHandler > rWriteDocumentHandler ) :
623     ThreadHelpBase( &Application::GetSolarMutex() ),
624     m_aImageListsItems( aItems ),
625     m_xWriteDocumentHandler( rWriteDocumentHandler )
626 {
627     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
628     m_xEmptyList            = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
629     m_aAttributeType        = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
630     m_aXMLImageNS           = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE_PREFIX ));
631     m_aXMLXlinkNS           = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
632     m_aAttributeXlinkType   = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE ));
633     m_aAttributeValueSimple = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE_VALUE ));
634 }
635 
~OWriteImagesDocumentHandler()636 OWriteImagesDocumentHandler::~OWriteImagesDocumentHandler()
637 {
638 }
639 
WriteImagesDocument()640 void OWriteImagesDocumentHandler::WriteImagesDocument()
641 {
642     ResetableGuard aGuard( m_aLock );
643 
644     m_xWriteDocumentHandler->startDocument();
645 
646     // write DOCTYPE line!
647     Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
648     if ( xExtendedDocHandler.is() )
649     {
650         xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMAGES_DOCTYPE )) );
651         m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
652     }
653 
654     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
655     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
656 
657     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_IMAGE )),
658                          m_aAttributeType,
659                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE )) );
660 
661     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
662                          m_aAttributeType,
663                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
664 
665     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )), pList );
666     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
667 
668     if ( m_aImageListsItems.pImageList )
669     {
670         ImageListDescriptor* pImageList = m_aImageListsItems.pImageList;
671 
672         for ( sal_uInt16 i = 0; i < m_aImageListsItems.pImageList->Count(); i++ )
673         {
674             const ImageListItemDescriptor* pImageItems = (*pImageList)[i];
675             WriteImageList( pImageItems );
676         }
677     }
678 
679     if ( m_aImageListsItems.pExternalImageList )
680     {
681         WriteExternalImageList( m_aImageListsItems.pExternalImageList );
682     }
683 
684     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
685     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )) );
686     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
687     m_xWriteDocumentHandler->endDocument();
688 }
689 
690 //_________________________________________________________________________________________________________________
691 //  protected member functions
692 //_________________________________________________________________________________________________________________
693 
WriteImageList(const ImageListItemDescriptor * pImageList)694 void OWriteImagesDocumentHandler::WriteImageList( const ImageListItemDescriptor* pImageList )
695 {
696     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
697     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
698 
699     // save required attributes
700     pList->AddAttribute( m_aAttributeXlinkType,
701                          m_aAttributeType,
702                          m_aAttributeValueSimple );
703 
704     pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )),
705                          m_aAttributeType,
706                          pImageList->aURL );
707 
708     if ( pImageList->nMaskMode == ImageMaskMode_Bitmap )
709     {
710         pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )),
711                              m_aAttributeType,
712                              ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )) );
713 
714         pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKURL )),
715                              m_aAttributeType,
716                              pImageList->aMaskURL );
717 
718         if ( pImageList->aHighContrastMaskURL.Len() > 0 )
719         {
720             pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTMASKURL )),
721                                  m_aAttributeType,
722                                  pImageList->aHighContrastMaskURL );
723         }
724     }
725     else
726     {
727         ::rtl::OUStringBuffer   aColorStrBuffer( 8 );
728         sal_Int64       nValue = pImageList->aMaskColor.GetRGBColor();
729 
730         aColorStrBuffer.appendAscii( "#" );
731         aColorStrBuffer.append( ::rtl::OUString::valueOf( nValue, 16 ));
732 
733         pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKCOLOR )),
734                              m_aAttributeType,
735                              aColorStrBuffer.makeStringAndClear() );
736 
737         pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )),
738                              m_aAttributeType,
739                              ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )) );
740     }
741 
742     if ( pImageList->aHighContrastURL.Len() > 0 )
743     {
744         pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTURL )),
745                              m_aAttributeType,
746                              pImageList->aHighContrastURL );
747     }
748 
749     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )), xList );
750     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
751 
752     ImageItemListDescriptor* pImageItemList = pImageList->pImageItemList;
753     if ( pImageItemList )
754     {
755         for ( sal_uInt16 i = 0; i < pImageItemList->Count(); i++ )
756             WriteImage( (*pImageItemList)[i] );
757     }
758 
759     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )) );
760     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
761 }
762 
WriteImage(const ImageItemDescriptor * pImage)763 void OWriteImagesDocumentHandler::WriteImage( const ImageItemDescriptor* pImage )
764 {
765     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
766     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
767 
768     pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BITMAPINDEX )),
769                          m_aAttributeType,
770                          ::rtl::OUString::valueOf( (sal_Int32)pImage->nIndex ) );
771 
772     pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )),
773                          m_aAttributeType,
774                          pImage->aCommandURL );
775 
776     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )), xList );
777     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
778 
779     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )) );
780     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
781 }
782 
WriteExternalImageList(const ExternalImageItemListDescriptor * pExternalImageList)783 void OWriteImagesDocumentHandler::WriteExternalImageList( const ExternalImageItemListDescriptor* pExternalImageList )
784 {
785     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )), m_xEmptyList );
786     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
787 
788     for ( sal_uInt16 i = 0; i < pExternalImageList->Count(); i++ )
789     {
790         ExternalImageItemDescriptor* pItem = (*pExternalImageList)[i];
791         WriteExternalImage( pItem );
792     }
793 
794     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
795     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )) );
796     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
797 }
798 
WriteExternalImage(const ExternalImageItemDescriptor * pExternalImage)799 void OWriteImagesDocumentHandler::WriteExternalImage( const ExternalImageItemDescriptor* pExternalImage )
800 {
801     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
802     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
803 
804     // save required attributes
805     pList->AddAttribute( m_aAttributeXlinkType,
806                          m_aAttributeType,
807                          m_aAttributeValueSimple );
808 
809     if ( pExternalImage->aURL.Len() > 0 )
810     {
811         pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )),
812                              m_aAttributeType,
813                              pExternalImage->aURL );
814     }
815 
816     if ( pExternalImage->aCommandURL.Len() > 0 )
817     {
818         pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )),
819                              m_aAttributeType,
820                              pExternalImage->aCommandURL );
821     }
822 
823     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )), xList );
824     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
825 
826     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )) );
827     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
828 }
829 
830 } // namespace framework
831