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