1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 #include <stdio.h>
32 
33 //_________________________________________________________________________________________________________________
34 //	my own includes
35 //_________________________________________________________________________________________________________________
36 
37 #include <threadhelp/resetableguard.hxx>
38 #include <xml/statusbardocumenthandler.hxx>
39 #include <macros/debug.hxx>
40 
41 //_________________________________________________________________________________________________________________
42 //	interface includes
43 //_________________________________________________________________________________________________________________
44 
45 #ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_
46 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
47 #endif
48 #include <com/sun/star/ui/ItemStyle.hpp>
49 #include <com/sun/star/ui/ItemType.hpp>
50 #include <com/sun/star/beans/PropertyValue.hpp>
51 
52 //_________________________________________________________________________________________________________________
53 //	other includes
54 //_________________________________________________________________________________________________________________
55 #include <vcl/svapp.hxx>
56 #include <vcl/status.hxx>
57 
58 #include <comphelper/attributelist.hxx>
59 
60 //_________________________________________________________________________________________________________________
61 //	namespace
62 //_________________________________________________________________________________________________________________
63 
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::beans;
66 using namespace ::com::sun::star::xml::sax;
67 using namespace ::com::sun::star::ui;
68 using namespace ::com::sun::star::container;
69 
70 #define XMLNS_STATUSBAR				"http://openoffice.org/2001/statusbar"
71 #define XMLNS_XLINK					"http://www.w3.org/1999/xlink"
72 #define XMLNS_STATUSBAR_PREFIX		"statusbar:"
73 #define XMLNS_XLINK_PREFIX			"xlink:"
74 
75 #define XMLNS_FILTER_SEPARATOR		"^"
76 
77 #define ELEMENT_STATUSBAR			"statusbar"
78 #define ELEMENT_STATUSBARITEM		"statusbaritem"
79 
80 #define ATTRIBUTE_ALIGN				"align"
81 #define ATTRIBUTE_STYLE				"style"
82 #define ATTRIBUTE_URL				"href"
83 #define ATTRIBUTE_WIDTH				"width"
84 #define ATTRIBUTE_OFFSET			"offset"
85 #define ATTRIBUTE_AUTOSIZE			"autosize"
86 #define ATTRIBUTE_OWNERDRAW			"ownerdraw"
87 #define ATTRIBUTE_HELPURL           "helpid"
88 
89 #define ELEMENT_NS_STATUSBAR		"statusbar:statusbar"
90 #define ELEMENT_NS_STATUSBARITEM	"statusbar:statusbaritem"
91 
92 #define ATTRIBUTE_XMLNS_STATUSBAR	"xmlns:statusbar"
93 #define ATTRIBUTE_XMLNS_XLINK		"xmlns:xlink"
94 
95 #define ATTRIBUTE_TYPE_CDATA		"CDATA"
96 
97 #define ATTRIBUTE_BOOLEAN_TRUE		"true"
98 #define ATTRIBUTE_BOOLEAN_FALSE		"false"
99 
100 #define ATTRIBUTE_ALIGN_LEFT		"left"
101 #define ATTRIBUTE_ALIGN_RIGHT		"right"
102 #define ATTRIBUTE_ALIGN_CENTER		"center"
103 
104 #define ATTRIBUTE_STYLE_IN			"in"
105 #define ATTRIBUTE_STYLE_OUT			"out"
106 #define ATTRIBUTE_STYLE_FLAT		"flat"
107 
108 #define STATUSBAR_DOCTYPE			"<!DOCTYPE statusbar:statusbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"statusbar.dtd\">"
109 
110 namespace framework
111 {
112 
113 // Property names of a menu/menu item ItemDescriptor
114 static const char ITEM_DESCRIPTOR_COMMANDURL[]  = "CommandURL";
115 static const char ITEM_DESCRIPTOR_HELPURL[]     = "HelpURL";
116 static const char ITEM_DESCRIPTOR_OFFSET[]      = "Offset";
117 static const char ITEM_DESCRIPTOR_STYLE[]       = "Style";
118 static const char ITEM_DESCRIPTOR_WIDTH[]       = "Width";
119 static const char ITEM_DESCRIPTOR_TYPE[]        = "Type";
120 
121 static void ExtractStatusbarItemParameters(
122     const Sequence< PropertyValue > rProp,
123     ::rtl::OUString&                       rCommandURL,
124     ::rtl::OUString&                       rHelpURL,
125     sal_Int16&                      rOffset,
126     sal_Int16&                      rStyle,
127     sal_Int16&                      rWidth )
128 {
129     for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
130     {
131         if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
132         {
133             rProp[i].Value >>= rCommandURL;
134             rCommandURL = rCommandURL.intern();
135         }
136         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
137         {
138             rProp[i].Value >>= rHelpURL;
139         }
140         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_OFFSET ))
141         {
142             rProp[i].Value >>= rOffset;
143         }
144         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
145         {
146             rProp[i].Value >>= rStyle;
147         }
148         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH ))
149         {
150             rProp[i].Value >>= rWidth;
151         }
152     }
153 }
154 
155 struct StatusBarEntryProperty
156 {
157 	OReadStatusBarDocumentHandler::StatusBar_XML_Namespace	nNamespace;
158 	char													aEntryName[20];
159 };
160 
161 StatusBarEntryProperty StatusBarEntries[OReadStatusBarDocumentHandler::SB_XML_ENTRY_COUNT] =
162 {
163 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ELEMENT_STATUSBAR		},
164 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ELEMENT_STATUSBARITEM	},
165 	{ OReadStatusBarDocumentHandler::SB_NS_XLINK,		ATTRIBUTE_URL			},
166 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ATTRIBUTE_ALIGN			},
167 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ATTRIBUTE_STYLE			},
168 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ATTRIBUTE_AUTOSIZE		},
169 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ATTRIBUTE_OWNERDRAW		},
170 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ATTRIBUTE_WIDTH			},
171 	{ OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,	ATTRIBUTE_OFFSET		},
172     { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR,   ATTRIBUTE_HELPURL       }
173 };
174 
175 
176 OReadStatusBarDocumentHandler::OReadStatusBarDocumentHandler(
177     const Reference< XIndexContainer >& rStatusBarItems ) :
178 	ThreadHelpBase( &Application::GetSolarMutex() ),
179     m_aStatusBarItems( rStatusBarItems )
180 {
181 	::rtl::OUString aNamespaceStatusBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR ));
182 	::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
183 	::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
184 
185 	// create hash map
186 	for ( int i = 0; i < (int)SB_XML_ENTRY_COUNT; i++ )
187 	{
188 		if ( StatusBarEntries[i].nNamespace == SB_NS_STATUSBAR )
189 		{
190 			::rtl::OUString temp( aNamespaceStatusBar );
191 			temp += aSeparator;
192 			temp += ::rtl::OUString::createFromAscii( StatusBarEntries[i].aEntryName );
193 			m_aStatusBarMap.insert( StatusBarHashMap::value_type( temp, (StatusBar_XML_Entry)i ) );
194 		}
195 		else
196 		{
197 			::rtl::OUString temp( aNamespaceXLink );
198 			temp += aSeparator;
199 			temp += ::rtl::OUString::createFromAscii( StatusBarEntries[i].aEntryName );
200 			m_aStatusBarMap.insert( StatusBarHashMap::value_type( temp, (StatusBar_XML_Entry)i ) );
201 		}
202 	}
203 
204 	m_bStatusBarStartFound			= sal_False;
205 	m_bStatusBarEndFound			= sal_False;
206 	m_bStatusBarItemStartFound		= sal_False;
207 }
208 
209 OReadStatusBarDocumentHandler::~OReadStatusBarDocumentHandler()
210 {
211 }
212 
213 // XDocumentHandler
214 void SAL_CALL OReadStatusBarDocumentHandler::startDocument(void)
215 throw (	SAXException, RuntimeException )
216 {
217 }
218 
219 void SAL_CALL OReadStatusBarDocumentHandler::endDocument(void)
220 throw(	SAXException, RuntimeException )
221 {
222 	ResetableGuard aGuard( m_aLock );
223 
224 	if (( m_bStatusBarStartFound && !m_bStatusBarEndFound ) ||
225 		( !m_bStatusBarStartFound && m_bStatusBarEndFound )		)
226 	{
227 		::rtl::OUString aErrorMessage = getErrorLineString();
228 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'statusbar' found!" ));
229 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
230 	}
231 }
232 
233 void SAL_CALL OReadStatusBarDocumentHandler::startElement(
234 	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
235 throw(	SAXException, RuntimeException )
236 {
237 	ResetableGuard aGuard( m_aLock );
238 
239 	StatusBarHashMap::const_iterator pStatusBarEntry = m_aStatusBarMap.find( aName ) ;
240 	if ( pStatusBarEntry != m_aStatusBarMap.end() )
241 	{
242 		switch ( pStatusBarEntry->second )
243 		{
244 			case SB_ELEMENT_STATUSBAR:
245 			{
246 				if ( m_bStatusBarStartFound )
247 				{
248 					::rtl::OUString aErrorMessage = getErrorLineString();
249 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'statusbar:statusbar' cannot be embeded into 'statusbar:statusbar'!" ));
250 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
251 				}
252 
253 				m_bStatusBarStartFound = sal_True;
254 			}
255 			break;
256 
257 			case SB_ELEMENT_STATUSBARITEM:
258 			{
259 				if ( !m_bStatusBarStartFound )
260 				{
261 					::rtl::OUString aErrorMessage = getErrorLineString();
262 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'statusbar:statusbaritem' must be embeded into element 'statusbar:statusbar'!" ));
263 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
264 				}
265 
266 				if ( m_bStatusBarItemStartFound )
267 				{
268 					::rtl::OUString aErrorMessage = getErrorLineString();
269 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element statusbar:statusbaritem is not a container!" ));
270 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
271 				}
272 
273 				::rtl::OUString    aCommandURL;
274                 ::rtl::OUString    aHelpURL;
275                 sal_Int16   nItemBits( ItemStyle::ALIGN_CENTER|ItemStyle::DRAW_IN3D );
276                 sal_Int16   nWidth( 0 );
277                 sal_Int16   nOffset( STATUSBAR_OFFSET );
278 				sal_Bool    bCommandURL( sal_False );
279 
280 				m_bStatusBarItemStartFound = sal_True;
281 				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
282 				{
283 					pStatusBarEntry = m_aStatusBarMap.find( xAttribs->getNameByIndex( n ) );
284 					if ( pStatusBarEntry != m_aStatusBarMap.end() )
285 					{
286 						switch ( pStatusBarEntry->second )
287 						{
288 							case SB_ATTRIBUTE_URL:
289 							{
290 								bCommandURL	= sal_True;
291 								aCommandURL = xAttribs->getValueByIndex( n );
292 							}
293 							break;
294 
295 							case SB_ATTRIBUTE_ALIGN:
296 							{
297 								if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_LEFT )) )
298 								{
299                                     nItemBits |= ItemStyle::ALIGN_LEFT;
300 									nItemBits &= ~ItemStyle::ALIGN_CENTER;
301 								}
302 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_CENTER )) )
303 								{
304 									nItemBits |= ItemStyle::ALIGN_CENTER;
305 									nItemBits &= ~ItemStyle::ALIGN_LEFT;
306 								}
307 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_RIGHT )) )
308 								{
309 									nItemBits |= ItemStyle::ALIGN_RIGHT;
310 								}
311 								else
312 								{
313 									::rtl::OUString aErrorMessage = getErrorLineString();
314 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:align must have one value of 'left','right' or 'center'!" ));
315 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
316 								}
317 							}
318 							break;
319 
320 							case SB_ATTRIBUTE_STYLE:
321 							{
322 								if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_IN )) )
323 								{
324 									nItemBits |= ItemStyle::DRAW_IN3D;
325 									nItemBits &= ~ItemStyle::DRAW_OUT3D;
326 								}
327 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_OUT )) )
328 								{
329 									nItemBits |= ItemStyle::DRAW_OUT3D;
330 									nItemBits &= ~ItemStyle::DRAW_IN3D;
331 								}
332 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_FLAT )) )
333 								{
334 									nItemBits |= ItemStyle::DRAW_FLAT;
335 								}
336 								else
337 								{
338 									::rtl::OUString aErrorMessage = getErrorLineString();
339 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:autosize must have value 'true' or 'false'!" ));
340 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
341 								}
342 							}
343 							break;
344 
345 							case SB_ATTRIBUTE_AUTOSIZE:
346 							{
347 								if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
348 									nItemBits |= ItemStyle::AUTO_SIZE;
349 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
350 									nItemBits &= ~ItemStyle::AUTO_SIZE;
351 								else
352 								{
353 									::rtl::OUString aErrorMessage = getErrorLineString();
354 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:autosize must have value 'true' or 'false'!" ));
355 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
356 								}
357 							}
358 							break;
359 
360 							case SB_ATTRIBUTE_OWNERDRAW:
361 							{
362 								if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
363 									nItemBits |= ItemStyle::OWNER_DRAW;
364 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
365 									nItemBits &= ~ItemStyle::OWNER_DRAW;
366 								else
367 								{
368 									::rtl::OUString aErrorMessage = getErrorLineString();
369 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:ownerdraw must have value 'true' or 'false'!" ));
370 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
371 								}
372 							}
373 							break;
374 
375 							case SB_ATTRIBUTE_WIDTH:
376 							{
377 								nWidth = (sal_Int16)(xAttribs->getValueByIndex( n ).toInt32());
378 							}
379 							break;
380 
381 							case SB_ATTRIBUTE_OFFSET:
382 							{
383 								nOffset = (sal_Int16)(xAttribs->getValueByIndex( n ).toInt32());
384 							}
385 							break;
386 
387                                           case SB_ATTRIBUTE_HELPURL:
388                                           {
389                                                 aHelpURL = xAttribs->getValueByIndex( n );
390                                           }
391                                           break;
392 
393                                           default:
394                                               break;
395 						}
396 					}
397 				} // for
398 
399 				if ( !bCommandURL )
400 				{
401 					::rtl::OUString aErrorMessage = getErrorLineString();
402 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute statusbar:url must have a value!" ));
403 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
404 				}
405                         else
406                         {
407                             Sequence< PropertyValue > aStatusbarItemProp( 6 );
408                             aStatusbarItemProp[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ));
409                             aStatusbarItemProp[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL ));
410                             aStatusbarItemProp[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_OFFSET ));
411                             aStatusbarItemProp[3].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE ));
412                             aStatusbarItemProp[4].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_WIDTH ));
413                             aStatusbarItemProp[5].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ));
414 
415                             aStatusbarItemProp[0].Value <<= aCommandURL;
416                             aStatusbarItemProp[1].Value <<= aHelpURL;
417                             aStatusbarItemProp[2].Value <<= nOffset;
418                             aStatusbarItemProp[3].Value <<= nItemBits;
419                             aStatusbarItemProp[4].Value <<= nWidth;
420                             aStatusbarItemProp[5].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT );
421 
422                             m_aStatusBarItems->insertByIndex( m_aStatusBarItems->getCount(), makeAny( aStatusbarItemProp ) );
423                        }
424 			}
425 			break;
426 
427                   default:
428                       break;
429 		}
430 	}
431 }
432 
433 void SAL_CALL OReadStatusBarDocumentHandler::endElement(const ::rtl::OUString& aName)
434 throw(	SAXException, RuntimeException )
435 {
436 	ResetableGuard aGuard( m_aLock );
437 
438 	StatusBarHashMap::const_iterator pStatusBarEntry = m_aStatusBarMap.find( aName ) ;
439 	if ( pStatusBarEntry != m_aStatusBarMap.end() )
440 	{
441 		switch ( pStatusBarEntry->second )
442 		{
443 			case SB_ELEMENT_STATUSBAR:
444 			{
445 				if ( !m_bStatusBarStartFound )
446 				{
447 					::rtl::OUString aErrorMessage = getErrorLineString();
448 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'statusbar' found, but no start element 'statusbar'" ));
449 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
450 				}
451 
452 				m_bStatusBarStartFound = sal_False;
453 			}
454 			break;
455 
456 			case SB_ELEMENT_STATUSBARITEM:
457 			{
458 				if ( !m_bStatusBarItemStartFound )
459 				{
460 					::rtl::OUString aErrorMessage = getErrorLineString();
461 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'statusbar:statusbaritem' found, but no start element 'statusbar:statusbaritem'" ));
462 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
463 				}
464 
465 				m_bStatusBarItemStartFound = sal_False;
466 			}
467 			break;
468 
469                   default:
470                       break;
471 		}
472 	}
473 }
474 
475 void SAL_CALL OReadStatusBarDocumentHandler::characters(const ::rtl::OUString&)
476 throw(	SAXException, RuntimeException )
477 {
478 }
479 
480 void SAL_CALL OReadStatusBarDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
481 throw(	SAXException, RuntimeException )
482 {
483 }
484 
485 void SAL_CALL OReadStatusBarDocumentHandler::processingInstruction(
486 	const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
487 throw(	SAXException, RuntimeException )
488 {
489 }
490 
491 void SAL_CALL OReadStatusBarDocumentHandler::setDocumentLocator(
492 	const Reference< XLocator > &xLocator)
493 throw(	SAXException, RuntimeException )
494 {
495 	ResetableGuard aGuard( m_aLock );
496 
497 	m_xLocator = xLocator;
498 }
499 
500 ::rtl::OUString OReadStatusBarDocumentHandler::getErrorLineString()
501 {
502 	ResetableGuard aGuard( m_aLock );
503 
504 	char buffer[32];
505 
506 	if ( m_xLocator.is() )
507 	{
508 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
509 		return ::rtl::OUString::createFromAscii( buffer );
510 	}
511 	else
512 		return ::rtl::OUString();
513 }
514 
515 
516 //_________________________________________________________________________________________________________________
517 //	OWriteStatusBarDocumentHandler
518 //_________________________________________________________________________________________________________________
519 
520 OWriteStatusBarDocumentHandler::OWriteStatusBarDocumentHandler(
521     const Reference< XIndexAccess >& aStatusBarItems,
522     const Reference< XDocumentHandler >& rWriteDocumentHandler ) :
523     ThreadHelpBase( &Application::GetSolarMutex() ),
524 	m_aStatusBarItems( aStatusBarItems ),
525 	m_xWriteDocumentHandler( rWriteDocumentHandler )
526 {
527 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
528 	m_xEmptyList		= Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
529 	m_aAttributeType	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
530 	m_aXMLXlinkNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
531 	m_aXMLStatusBarNS	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR_PREFIX ));
532 }
533 
534 OWriteStatusBarDocumentHandler::~OWriteStatusBarDocumentHandler()
535 {
536 }
537 
538 void OWriteStatusBarDocumentHandler::WriteStatusBarDocument() throw
539 ( SAXException, RuntimeException )
540 {
541 	ResetableGuard aGuard( m_aLock );
542 
543 	m_xWriteDocumentHandler->startDocument();
544 
545 	// write DOCTYPE line!
546 	Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
547 	if ( xExtendedDocHandler.is() )
548 	{
549 		xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATUSBAR_DOCTYPE )) );
550 		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
551 	}
552 
553 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
554 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
555 
556 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_STATUSBAR )),
557 						 m_aAttributeType,
558 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR )) );
559 
560 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
561 						 m_aAttributeType,
562 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
563 
564 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBAR )), pList );
565 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
566 
567 	sal_Int32  nItemCount = m_aStatusBarItems->getCount();
568     Any        aAny;
569 
570 	for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
571 	{
572         Sequence< PropertyValue > aProps;
573         aAny = m_aStatusBarItems->getByIndex( nItemPos );
574         if ( aAny >>= aProps )
575         {
576             ::rtl::OUString    aCommandURL;
577             ::rtl::OUString    aHelpURL;
578             sal_Int16   nStyle( ItemStyle::ALIGN_CENTER|ItemStyle::DRAW_IN3D );
579             sal_Int16   nWidth( 0 );
580             sal_Int16   nOffset( STATUSBAR_OFFSET );
581 
582             ExtractStatusbarItemParameters(
583                 aProps,
584                 aCommandURL,
585                 aHelpURL,
586                 nOffset,
587                 nStyle,
588                 nWidth );
589 
590             if ( aCommandURL.getLength() > 0 )
591                 WriteStatusBarItem( aCommandURL, aHelpURL, nOffset, nStyle, nWidth );
592         }
593     }
594 
595 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
596 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBAR )) );
597 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
598 	m_xWriteDocumentHandler->endDocument();
599 }
600 
601 //_________________________________________________________________________________________________________________
602 //	protected member functions
603 //_________________________________________________________________________________________________________________
604 
605 void OWriteStatusBarDocumentHandler::WriteStatusBarItem(
606     const rtl::OUString& rCommandURL,
607     const rtl::OUString& /*rHelpURL*/,
608     sal_Int16            nOffset,
609     sal_Int16            nStyle,
610     sal_Int16            nWidth )
611 throw ( SAXException, RuntimeException )
612 {
613 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
614 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
615 
616 	if ( m_aAttributeURL.getLength() == 0 )
617 	{
618 		m_aAttributeURL = m_aXMLXlinkNS;
619 		m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL ));
620 	}
621 
622     // save required attribute (URL)
623 	pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL );
624 
625 	// alignment
626 	if ( nStyle & ItemStyle::ALIGN_RIGHT )
627 	{
628 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )),
629 							 m_aAttributeType,
630 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_RIGHT )) );
631 	}
632 	else if ( nStyle & ItemStyle::ALIGN_CENTER )
633 	{
634 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )),
635 							 m_aAttributeType,
636 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_CENTER )) );
637 	}
638 	else
639 	{
640 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )),
641 							 m_aAttributeType,
642 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_LEFT )) );
643 	}
644 
645 	// style ( SIB_IN is default )
646 	if ( nStyle & ItemStyle::DRAW_FLAT )
647 	{
648 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE )),
649 							 m_aAttributeType,
650 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE_FLAT )) );
651 	}
652 	else if ( nStyle & ItemStyle::DRAW_OUT3D )
653 	{
654 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE )),
655 							 m_aAttributeType,
656 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE_OUT )) );
657 	}
658 
659 	// autosize (default sal_False)
660 	if ( nStyle & ItemStyle::AUTO_SIZE )
661 	{
662 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_AUTOSIZE )),
663 							 m_aAttributeType,
664 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) );
665 	}
666 
667 	// ownerdraw (default sal_False)
668 	if ( nStyle & ItemStyle::OWNER_DRAW )
669 	{
670 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_OWNERDRAW )),
671 							 m_aAttributeType,
672 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) );
673 	}
674 
675 	// width (default 0)
676 	if ( nWidth > 0 )
677 	{
678 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )),
679 							 m_aAttributeType,
680 							 ::rtl::OUString::valueOf( (sal_Int32)nWidth ) );
681 	}
682 
683 	// offset (default STATUSBAR_OFFSET)
684 	if ( nOffset != STATUSBAR_OFFSET )
685 	{
686 		pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_OFFSET )),
687 							 m_aAttributeType,
688 							 ::rtl::OUString::valueOf( (sal_Int32)nOffset ) );
689 	}
690 
691 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
692 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBARITEM )), xList );
693 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
694 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBARITEM )) );
695 }
696 
697 } // namespace framework
698 
699