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