xref: /trunk/main/framework/source/fwe/xml/toolboxdocumenthandler.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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