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/toolboxdocumenthandler.hxx>
39 #include <macros/debug.hxx>
40 #include <xml/toolboxconfigurationdefines.hxx>
41 
42 //_________________________________________________________________________________________________________________
43 //	interface includes
44 //_________________________________________________________________________________________________________________
45 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
46 #include <com/sun/star/ui/ItemType.hpp>
47 #include <com/sun/star/ui/ItemStyle.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 
50 //_________________________________________________________________________________________________________________
51 //	other includes
52 //_________________________________________________________________________________________________________________
53 
54 #include <sal/config.h>
55 #include <vcl/svapp.hxx>
56 #include <vcl/toolbox.hxx>
57 #include <rtl/ustrbuf.hxx>
58 
59 #include <comphelper/attributelist.hxx>
60 
61 //_________________________________________________________________________________________________________________
62 //	namespace
63 //_________________________________________________________________________________________________________________
64 
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::container;
68 using namespace ::com::sun::star::xml::sax;
69 
70 
71 #define TOOLBAR_DOCTYPE				"<!DOCTYPE toolbar:toolbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"toolbar.dtd\">"
72 
73 namespace framework
74 {
75 
76 // Property names of a menu/menu item ItemDescriptor
77 static const char ITEM_DESCRIPTOR_COMMANDURL[]  = "CommandURL";
78 static const char ITEM_DESCRIPTOR_HELPURL[]     = "HelpURL";
79 static const char ITEM_DESCRIPTOR_TOOLTIP[]     = "Tooltip";
80 static const char ITEM_DESCRIPTOR_LABEL[]       = "Label";
81 static const char ITEM_DESCRIPTOR_TYPE[]        = "Type";
82 static const char ITEM_DESCRIPTOR_STYLE[]       = "Style";
83 static const char ITEM_DESCRIPTOR_VISIBLE[]     = "IsVisible";
84 static const char ITEM_DESCRIPTOR_WIDTH[]       = "Width";
85 
86 static void ExtractToolbarParameters( const Sequence< PropertyValue > rProp,
87                                       ::rtl::OUString&                       rCommandURL,
88                                       ::rtl::OUString&                       rLabel,
89                                       ::rtl::OUString&                       rHelpURL,
90                                       ::rtl::OUString&                       rTooltip,
91                                       sal_Int16&                      rStyle,
92                                       sal_Int16&                      rWidth,
93                                       sal_Bool&                       rVisible,
94                                       sal_Int16&                      rType )
95 {
96     for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
97     {
98         if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
99         {
100             rProp[i].Value >>= rCommandURL;
101             rCommandURL = rCommandURL.intern();
102         }
103         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
104             rProp[i].Value >>= rHelpURL;
105         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TOOLTIP ))
106             rProp[i].Value >>= rTooltip;
107         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
108             rProp[i].Value >>= rLabel;
109         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
110             rProp[i].Value >>= rType;
111         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_VISIBLE ))
112             rProp[i].Value >>= rVisible;
113         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH ))
114             rProp[i].Value >>= rWidth;
115         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
116             rProp[i].Value >>= rStyle;
117     }
118 }
119 
120 struct ToolboxStyleItem
121 {
122     sal_Int16 nBit;
123     const char* attrName;
124 };
125 
126 ToolboxStyleItem Styles[ ] = {
127     { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO },
128     { ::com::sun::star::ui::ItemStyle::ALIGN_LEFT, ATTRIBUTE_ITEMSTYLE_LEFT },
129     { ::com::sun::star::ui::ItemStyle::AUTO_SIZE, ATTRIBUTE_ITEMSTYLE_AUTO },
130     { ::com::sun::star::ui::ItemStyle::REPEAT, ATTRIBUTE_ITEMSTYLE_REPEAT },
131     { ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY, ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY },
132     { ::com::sun::star::ui::ItemStyle::DROP_DOWN, ATTRIBUTE_ITEMSTYLE_DROPDOWN },
133     { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE },
134     { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT },
135 };
136 
137 sal_Int32 nStyleItemEntries = sizeof( Styles ) / sizeof( Styles[ 0 ] );
138 
139 struct ToolBarEntryProperty
140 {
141 	OReadToolBoxDocumentHandler::ToolBox_XML_Namespace	nNamespace;
142 	char												aEntryName[20];
143 };
144 
145 ToolBarEntryProperty ToolBoxEntries[OReadToolBoxDocumentHandler::TB_XML_ENTRY_COUNT] =
146 {
147 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBAR				},
148 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARITEM			},
149 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARSPACE		},
150 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARBREAK		},
151 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARSEPARATOR	},
152 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_TEXT				},
153 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_BITMAP			},
154 	{ OReadToolBoxDocumentHandler::TB_NS_XLINK,		ATTRIBUTE_URL				},
155 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_ITEMBITS			},
156 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_VISIBLE			},
157 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_WIDTH				},
158 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_USER				},
159 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_HELPID			},
160 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_ITEMSTYLE			},
161     { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,   ATTRIBUTE_UINAME            },
162     { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_TOOLTIP			},
163 };
164 
165 OReadToolBoxDocumentHandler::OReadToolBoxDocumentHandler( const Reference< XIndexContainer >& rItemContainer ) :
166 	ThreadHelpBase( &Application::GetSolarMutex() ),
167     m_rItemContainer( rItemContainer ),
168     m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )),
169     m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )),
170     m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )),
171     m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )),
172     m_aTooltip( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TOOLTIP )),
173     m_aIsVisible( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_VISIBLE )),
174     m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ))
175  {
176 	::rtl::OUString aNamespaceToolBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR ));
177 	::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
178 	::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
179 
180 	// create hash map
181 	for ( int i = 0; i < (int)TB_XML_ENTRY_COUNT; i++ )
182 	{
183 		if ( ToolBoxEntries[i].nNamespace == TB_NS_TOOLBAR )
184 		{
185 			::rtl::OUString temp( aNamespaceToolBar );
186 			temp += aSeparator;
187 			temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName );
188 			m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) );
189 		}
190 		else
191 		{
192 			::rtl::OUString temp( aNamespaceXLink );
193 			temp += aSeparator;
194 			temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName );
195 			m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) );
196 		}
197 	}
198 
199 	// pre-calculate a hash code for all style strings to speed up xml read process
200 	m_nHashCode_Style_Radio		    = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_RADIO ).hashCode();
201 	m_nHashCode_Style_Auto		    = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_AUTO ).hashCode();
202 	m_nHashCode_Style_Left		    = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_LEFT ).hashCode();
203 	m_nHashCode_Style_AutoSize	    = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_AUTOSIZE ).hashCode();
204 	m_nHashCode_Style_DropDown	    = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_DROPDOWN ).hashCode();
205 	m_nHashCode_Style_Repeat	    = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_REPEAT ).hashCode();
206     m_nHashCode_Style_DropDownOnly  = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY ).hashCode();
207     m_nHashCode_Style_Text  = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_TEXT ).hashCode();
208     m_nHashCode_Style_Image  = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_IMAGE ).hashCode();
209 
210 	m_bToolBarStartFound			= sal_False;
211 	m_bToolBarEndFound				= sal_False;
212 	m_bToolBarItemStartFound		= sal_False;
213 	m_bToolBarSpaceStartFound		= sal_False;
214 	m_bToolBarBreakStartFound		= sal_False;
215 	m_bToolBarSeparatorStartFound	= sal_False;
216 }
217 
218 OReadToolBoxDocumentHandler::~OReadToolBoxDocumentHandler()
219 {
220 }
221 
222 // XDocumentHandler
223 void SAL_CALL OReadToolBoxDocumentHandler::startDocument(void)
224 throw (	SAXException, RuntimeException )
225 {
226 }
227 
228 void SAL_CALL OReadToolBoxDocumentHandler::endDocument(void)
229 throw(	SAXException, RuntimeException )
230 {
231 	ResetableGuard aGuard( m_aLock );
232 
233 	if (( m_bToolBarStartFound && !m_bToolBarEndFound ) ||
234 		( !m_bToolBarStartFound && m_bToolBarEndFound )		)
235 	{
236 		::rtl::OUString aErrorMessage = getErrorLineString();
237 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'toolbar' found!" ));
238 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
239 	}
240 }
241 
242 void SAL_CALL OReadToolBoxDocumentHandler::startElement(
243 	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
244 throw(	SAXException, RuntimeException )
245 {
246 	ResetableGuard aGuard( m_aLock );
247 
248 	ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
249 	if ( pToolBoxEntry != m_aToolBoxMap.end() )
250 	{
251 		switch ( pToolBoxEntry->second )
252 		{
253 			case TB_ELEMENT_TOOLBAR:
254 			{
255 				if ( m_bToolBarStartFound )
256 				{
257 				    ::rtl::OUString aErrorMessage = getErrorLineString();
258 				    aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbar' cannot be embeded into 'toolbar:toolbar'!" ));
259 				    throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
260 				}
261                         else
262                         {
263                             // Check if we have a UI name set in our XML file
264                             ::rtl::OUString aUIName;
265                             for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
266 			          {
267 				        pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
268 				        if ( pToolBoxEntry != m_aToolBoxMap.end() )
269 				        {
270                                     switch ( pToolBoxEntry->second )
271                                     {
272                                         case TB_ATTRIBUTE_UINAME:
273 				                    aUIName = xAttribs->getValueByIndex( n );
274                                             break;
275                                         default:
276                                             break;
277                                     }
278                                 }
279                             }
280 
281                             if ( aUIName.getLength() > 0 )
282                             {
283                                 // Try to set UI name as a container property
284                                 Reference< XPropertySet > xPropSet( m_rItemContainer, UNO_QUERY );
285                                 if ( xPropSet.is() )
286                                 {
287                                     try
288                                     {
289                                         xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), makeAny( aUIName ) );
290                                     }
291                                     catch ( UnknownPropertyException& )
292                                     {
293                                     }
294                                 }
295                             }
296                         }
297 
298 				m_bToolBarStartFound = sal_True;
299 			}
300 			break;
301 
302 			case TB_ELEMENT_TOOLBARITEM:
303 			{
304 				if ( !m_bToolBarStartFound )
305 				{
306 					::rtl::OUString aErrorMessage = getErrorLineString();
307 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbaritem' must be embeded into element 'toolbar:toolbar'!" ));
308 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
309 				}
310 
311 				if ( m_bToolBarSeparatorStartFound ||
312 					 m_bToolBarBreakStartFound ||
313 					 m_bToolBarSpaceStartFound ||
314 					 m_bToolBarItemStartFound )
315 				{
316 					::rtl::OUString aErrorMessage = getErrorLineString();
317 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbaritem is not a container!" ));
318 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
319 				}
320 
321 				::rtl::OUString aAttribute;
322 				sal_Bool bAttributeURL	= sal_False;
323 
324 				m_bToolBarItemStartFound = sal_True;
325                 ::rtl::OUString        aLabel;
326                 ::rtl::OUString        aCommandURL;
327                 ::rtl::OUString        aHelpURL;
328                 ::rtl::OUString        aTooltip;
329                 ::rtl::OUString        aBitmapName;
330                 sal_uInt16      nItemBits( 0 );
331                 sal_uInt16      nWidth( 0 );
332                 sal_uInt16      nUserDef( 0 );
333                 sal_Bool        bVisible( sal_True );
334 
335 				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
336 				{
337 					pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
338 					if ( pToolBoxEntry != m_aToolBoxMap.end() )
339 					{
340 						switch ( pToolBoxEntry->second )
341 						{
342 							case TB_ATTRIBUTE_TEXT:
343 							{
344 								aLabel = xAttribs->getValueByIndex( n );
345 							}
346 							break;
347 
348 							case TB_ATTRIBUTE_BITMAP:
349 							{
350 								aBitmapName = xAttribs->getValueByIndex( n );
351 							}
352 							break;
353 
354 							case TB_ATTRIBUTE_URL:
355 							{
356 								bAttributeURL	= sal_True;
357 								aCommandURL		= xAttribs->getValueByIndex( n ).intern();
358 							}
359 							break;
360 
361 							case TB_ATTRIBUTE_ITEMBITS:
362 							{
363 								nItemBits = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
364 							}
365 							break;
366 
367 							case TB_ATTRIBUTE_VISIBLE:
368 							{
369 								if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
370 									bVisible = sal_True;
371 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
372 									bVisible = sal_False;
373 								else
374 								{
375 									::rtl::OUString aErrorMessage = getErrorLineString();
376 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute toolbar:visible must have value 'true' or 'false'!" ));
377 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
378 								}
379 							}
380 							break;
381 
382 							case TB_ATTRIBUTE_WIDTH:
383 							{
384 								nWidth = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
385 							}
386 							break;
387 
388 							case TB_ATTRIBUTE_USER:
389 							{
390 								nUserDef = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
391 							}
392 							break;
393 
394 							case TB_ATTRIBUTE_HELPID:
395 							{
396 								aHelpURL = xAttribs->getValueByIndex( n );
397 							}
398 							break;
399 
400                             case TB_ATTRIBUTE_TOOLTIP:
401                             {
402                                 aTooltip = xAttribs->getValueByIndex( n );
403                             }
404                             break;
405 
406 							case TB_ATTRIBUTE_STYLE:
407 							{
408 								// read space seperated item style list
409 								::rtl::OUString aTemp = xAttribs->getValueByIndex( n );
410 								sal_Int32 nIndex = 0;
411 
412 								do
413 								{
414 									::rtl::OUString aToken	= aTemp.getToken( 0, ' ', nIndex );
415 									if ( aToken.getLength() > 0 )
416 									{
417 										sal_Int32 nHashCode = aToken.hashCode();
418 										if ( nHashCode == m_nHashCode_Style_Radio )
419                                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
420 										else if ( nHashCode == m_nHashCode_Style_Left )
421                                             nItemBits |= ::com::sun::star::ui::ItemStyle::ALIGN_LEFT;
422 										else if ( nHashCode == m_nHashCode_Style_AutoSize )
423                                             nItemBits |= ::com::sun::star::ui::ItemStyle::AUTO_SIZE;
424 										else if ( nHashCode == m_nHashCode_Style_DropDown )
425                                             nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
426 										else if ( nHashCode == m_nHashCode_Style_Repeat )
427                                             nItemBits |= ::com::sun::star::ui::ItemStyle::REPEAT;
428                                         else if ( nHashCode == m_nHashCode_Style_DropDownOnly )
429                                             nItemBits |= ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY;
430                                         else if ( nHashCode == m_nHashCode_Style_DropDown )
431                                             nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
432                                         else if ( nHashCode == m_nHashCode_Style_Text )
433                                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
434                                         else if ( nHashCode == m_nHashCode_Style_Image )
435                                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
436 									}
437 								}
438 								while ( nIndex >= 0 );
439 							}
440 							break;
441 
442                                           default:
443                                               break;
444 						}
445 					}
446 				} // for
447 
448 				if ( !bAttributeURL )
449 				{
450 					::rtl::OUString aErrorMessage = getErrorLineString();
451 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute toolbar:url must have a value!" ));
452 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
453 				}
454 
455 		        if ( aCommandURL.getLength() > 0 )
456 		        {
457                     Sequence< PropertyValue > aToolbarItemProp( 7 );
458                     aToolbarItemProp[0].Name = m_aCommandURL;
459                     aToolbarItemProp[1].Name = m_aHelpURL;
460                     aToolbarItemProp[2].Name = m_aLabel;
461                     aToolbarItemProp[3].Name = m_aType;
462                     aToolbarItemProp[4].Name = m_aStyle;
463                     aToolbarItemProp[5].Name = m_aIsVisible;
464                     aToolbarItemProp[6].Name = m_aTooltip;
465 
466                     aToolbarItemProp[0].Value <<= aCommandURL;
467                     aToolbarItemProp[1].Value <<= aHelpURL;
468                     aToolbarItemProp[2].Value <<= aLabel;
469                     aToolbarItemProp[3].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT );
470                     aToolbarItemProp[4].Value <<= nItemBits;
471                     aToolbarItemProp[5].Value <<= bVisible;
472                     aToolbarItemProp[6].Value <<= aTooltip;
473 
474                     m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
475 		        }
476 			}
477 			break;
478 
479 			case TB_ELEMENT_TOOLBARSPACE:
480 			{
481 				if ( m_bToolBarSeparatorStartFound ||
482 					 m_bToolBarBreakStartFound ||
483 					 m_bToolBarSpaceStartFound ||
484 					 m_bToolBarItemStartFound )
485 				{
486 					::rtl::OUString aErrorMessage = getErrorLineString();
487 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarspace is not a container!" ));
488 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
489 				}
490 
491 				m_bToolBarSpaceStartFound = sal_True;
492 
493                 Sequence< PropertyValue > aToolbarItemProp( 2 );
494                 aToolbarItemProp[0].Name = m_aCommandURL;
495                 aToolbarItemProp[1].Name = m_aType;
496 
497                 aToolbarItemProp[0].Value <<= rtl::OUString();
498                 aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_SPACE;
499 
500 				m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
501 			}
502 			break;
503 
504 			case TB_ELEMENT_TOOLBARBREAK:
505 			{
506 				if ( m_bToolBarSeparatorStartFound ||
507 					 m_bToolBarBreakStartFound ||
508 					 m_bToolBarSpaceStartFound ||
509 					 m_bToolBarItemStartFound )
510 				{
511 					::rtl::OUString aErrorMessage = getErrorLineString();
512 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarbreak is not a container!" ));
513 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
514 				}
515 
516 				m_bToolBarBreakStartFound = sal_True;
517 
518                 Sequence< PropertyValue > aToolbarItemProp( 2 );
519                 aToolbarItemProp[0].Name = m_aCommandURL;
520                 aToolbarItemProp[1].Name = m_aType;
521 
522                 aToolbarItemProp[0].Value <<= rtl::OUString();
523                 aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK;
524 
525 				m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
526 			}
527 			break;
528 
529 			case TB_ELEMENT_TOOLBARSEPARATOR:
530 			{
531 				if ( m_bToolBarSeparatorStartFound ||
532 					 m_bToolBarBreakStartFound ||
533 					 m_bToolBarSpaceStartFound ||
534 					 m_bToolBarItemStartFound )
535 				{
536 					::rtl::OUString aErrorMessage = getErrorLineString();
537 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarseparator is not a container!" ));
538 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
539 				}
540 
541 				m_bToolBarSeparatorStartFound = sal_True;
542 
543                 Sequence< PropertyValue > aToolbarItemProp( 2 );
544                 aToolbarItemProp[0].Name = m_aCommandURL;
545                 aToolbarItemProp[1].Name = m_aType;
546 
547                 aToolbarItemProp[0].Value <<= rtl::OUString();
548                 aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
549 
550 				m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
551 			}
552 			break;
553 
554                   default:
555                       break;
556 		}
557 	}
558 }
559 
560 void SAL_CALL OReadToolBoxDocumentHandler::endElement(const ::rtl::OUString& aName)
561 throw(	SAXException, RuntimeException )
562 {
563 	ResetableGuard aGuard( m_aLock );
564 
565 	ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
566 	if ( pToolBoxEntry != m_aToolBoxMap.end() )
567 	{
568 		switch ( pToolBoxEntry->second )
569 		{
570 			case TB_ELEMENT_TOOLBAR:
571 			{
572 				if ( !m_bToolBarStartFound )
573 				{
574 					::rtl::OUString aErrorMessage = getErrorLineString();
575 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar' found, but no start element 'toolbar'" ));
576 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
577 				}
578 
579 				m_bToolBarStartFound = sal_False;
580 			}
581 			break;
582 
583 			case TB_ELEMENT_TOOLBARITEM:
584 			{
585 				if ( !m_bToolBarItemStartFound )
586 				{
587 					::rtl::OUString aErrorMessage = getErrorLineString();
588 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbaritem' found, but no start element 'toolbar:toolbaritem'" ));
589 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
590 				}
591 
592 				m_bToolBarItemStartFound = sal_False;
593 			}
594 			break;
595 
596 			case TB_ELEMENT_TOOLBARBREAK:
597 			{
598 				if ( !m_bToolBarBreakStartFound )
599 				{
600 					::rtl::OUString aErrorMessage = getErrorLineString();
601 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarbreak' found, but no start element 'toolbar:toolbarbreak'" ));
602 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
603 				}
604 
605 				m_bToolBarBreakStartFound = sal_False;
606 			}
607 			break;
608 
609 			case TB_ELEMENT_TOOLBARSPACE:
610 			{
611 				if ( !m_bToolBarSpaceStartFound )
612 				{
613 					::rtl::OUString aErrorMessage = getErrorLineString();
614 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarspace' found, but no start element 'toolbar:toolbarspace'" ));
615 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
616 				}
617 
618 				m_bToolBarSpaceStartFound = sal_False;
619 			}
620 			break;
621 
622 			case TB_ELEMENT_TOOLBARSEPARATOR:
623 			{
624 				if ( !m_bToolBarSeparatorStartFound )
625 				{
626 					::rtl::OUString aErrorMessage = getErrorLineString();
627 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarseparator' found, but no start element 'toolbar:toolbarseparator'" ));
628 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
629 				}
630 
631 				m_bToolBarSeparatorStartFound = sal_False;
632 			}
633 			break;
634 
635                   default:
636                       break;
637 		}
638 	}
639 }
640 
641 void SAL_CALL OReadToolBoxDocumentHandler::characters(const ::rtl::OUString&)
642 throw(	SAXException, RuntimeException )
643 {
644 }
645 
646 void SAL_CALL OReadToolBoxDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
647 throw(	SAXException, RuntimeException )
648 {
649 }
650 
651 void SAL_CALL OReadToolBoxDocumentHandler::processingInstruction(
652 	const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
653 throw(	SAXException, RuntimeException )
654 {
655 }
656 
657 void SAL_CALL OReadToolBoxDocumentHandler::setDocumentLocator(
658 	const Reference< XLocator > &xLocator)
659 throw(	SAXException, RuntimeException )
660 {
661 	ResetableGuard aGuard( m_aLock );
662 
663 	m_xLocator = xLocator;
664 }
665 
666 ::rtl::OUString OReadToolBoxDocumentHandler::getErrorLineString()
667 {
668 	ResetableGuard aGuard( m_aLock );
669 
670 	char buffer[32];
671 
672 	if ( m_xLocator.is() )
673 	{
674 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
675 		return ::rtl::OUString::createFromAscii( buffer );
676 	}
677 	else
678 		return ::rtl::OUString();
679 }
680 
681 
682 //_________________________________________________________________________________________________________________
683 //	OWriteToolBoxDocumentHandler
684 //_________________________________________________________________________________________________________________
685 
686 OWriteToolBoxDocumentHandler::OWriteToolBoxDocumentHandler(
687     const Reference< XIndexAccess >& rItemAccess,
688     Reference< XDocumentHandler >& rWriteDocumentHandler ) :
689 	ThreadHelpBase( &Application::GetSolarMutex() ),
690 	m_xWriteDocumentHandler( rWriteDocumentHandler ),
691 	m_rItemAccess( rItemAccess )
692 {
693     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
694 	m_xEmptyList		= Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
695 	m_aAttributeType	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
696 	m_aXMLXlinkNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
697 	m_aXMLToolbarNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR_PREFIX ));
698 }
699 
700 OWriteToolBoxDocumentHandler::~OWriteToolBoxDocumentHandler()
701 {
702 }
703 
704 void OWriteToolBoxDocumentHandler::WriteToolBoxDocument() throw
705 ( SAXException, RuntimeException )
706 {
707     ResetableGuard aGuard( m_aLock );
708 
709 	m_xWriteDocumentHandler->startDocument();
710 
711 	// write DOCTYPE line!
712 	Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
713 	if ( xExtendedDocHandler.is() )
714 	{
715 		xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( TOOLBAR_DOCTYPE )) );
716 		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
717 	}
718 
719     ::rtl::OUString aUIName;
720     Reference< XPropertySet > xPropSet( m_rItemAccess, UNO_QUERY );
721     if ( xPropSet.is() )
722     {
723         try
724         {
725             xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
726         }
727         catch ( UnknownPropertyException& )
728         {
729         }
730     }
731 
732     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
733 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
734 
735 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_TOOLBAR )),
736 						 m_aAttributeType,
737 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR )) );
738 
739 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
740 						 m_aAttributeType,
741 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
742 
743     if ( aUIName.getLength() > 0 )
744         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_UINAME )),
745                              m_aAttributeType,
746                              aUIName );
747 
748 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )), pList );
749 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
750 
751 	sal_Int32  nItemCount = m_rItemAccess->getCount();
752     Any        aAny;
753 
754 	for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
755 	{
756         Sequence< PropertyValue > aProps;
757         aAny = m_rItemAccess->getByIndex( nItemPos );
758         if ( aAny >>= aProps )
759         {
760             ::rtl::OUString    aCommandURL;
761             ::rtl::OUString    aLabel;
762             ::rtl::OUString    aHelpURL;
763             ::rtl::OUString    aTooltip;
764             sal_Bool    bVisible( sal_True );
765             sal_Int16   nType( ::com::sun::star::ui::ItemType::DEFAULT );
766             sal_Int16   nWidth( 0 );
767             sal_Int16   nStyle( 0 );
768 
769             ExtractToolbarParameters( aProps, aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible, nType );
770             if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
771                 WriteToolBoxItem( aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible );
772             else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE )
773 				WriteToolBoxSpace();
774             else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE )
775 				WriteToolBoxSeparator();
776             else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK )
777 				WriteToolBoxBreak();
778 		}
779 	}
780 
781 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
782 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )) );
783 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
784 	m_xWriteDocumentHandler->endDocument();
785 }
786 
787 //_________________________________________________________________________________________________________________
788 //	protected member functions
789 //_________________________________________________________________________________________________________________
790 
791 void OWriteToolBoxDocumentHandler::WriteToolBoxItem(
792     const ::rtl::OUString& rCommandURL,
793     const ::rtl::OUString& rLabel,
794     const ::rtl::OUString& rHelpURL,
795     const ::rtl::OUString& rTooltip,
796     sal_Int16       nStyle,
797     sal_Int16       nWidth,
798     sal_Bool        bVisible )
799 throw ( SAXException, RuntimeException )
800 {
801     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
802 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
803 
804 	if ( m_aAttributeURL.getLength() == 0 )
805 	{
806 		m_aAttributeURL = m_aXMLXlinkNS;
807 		m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL ));
808 	}
809 
810     // save required attribute (URL)
811 	pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL );
812 
813 	if ( rLabel.getLength() > 0 )
814 	{
815 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TEXT )),
816 							 m_aAttributeType,
817 							 rLabel );
818 	}
819 
820 	if ( bVisible == sal_False )
821 	{
822 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_VISIBLE )),
823 							 m_aAttributeType,
824 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) );
825 	}
826 
827 	if ( rHelpURL.getLength() > 0 )
828 	{
829 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HELPID )),
830 							 m_aAttributeType,
831 							 rHelpURL );
832 	}
833 
834     if ( rTooltip.getLength() > 0 )
835     {
836         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TOOLTIP )),
837                              m_aAttributeType,
838                              rTooltip );
839     }
840 
841     if ( nStyle > 0 )
842     {
843         rtl::OUString aValue;
844         ToolboxStyleItem* pStyle = Styles;
845 
846         for ( sal_Int32 nIndex = 0; nIndex < nStyleItemEntries; ++nIndex, ++pStyle )
847         {
848             if ( nStyle & pStyle->nBit )
849             {
850                 if ( aValue.getLength() )
851                     aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ) );
852                 aValue += rtl::OUString::createFromAscii( pStyle->attrName );
853             }
854         }
855         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE )),
856                              m_aAttributeType,
857                              aValue );
858     }
859 
860     if ( nWidth > 0 )
861     {
862 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )),
863 							 m_aAttributeType,
864                              ::rtl::OUString::valueOf( sal_Int32( nWidth )) );
865     }
866 
867 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
868 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )), xList );
869 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
870 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )) );
871 }
872 
873 void OWriteToolBoxDocumentHandler::WriteToolBoxSpace() throw
874 ( SAXException, RuntimeException )
875 {
876     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
877 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )), m_xEmptyList );
878 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
879 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )) );
880 }
881 
882 void OWriteToolBoxDocumentHandler::WriteToolBoxBreak() throw
883 ( SAXException, RuntimeException )
884 {
885 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
886 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )), m_xEmptyList );
887 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
888 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )) );
889 }
890 
891 void OWriteToolBoxDocumentHandler::WriteToolBoxSeparator() throw
892 ( SAXException, RuntimeException )
893 {
894     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
895 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )), m_xEmptyList );
896 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
897 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )) );
898 }
899 
900 } // namespace framework
901 
902