xref: /AOO41X/main/framework/source/fwe/xml/toolboxdocumenthandler.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
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 throw ( SAXException, RuntimeException )
221 {
222 }
223 
endDocument(void)224 void SAL_CALL OReadToolBoxDocumentHandler::endDocument(void)
225 throw(  SAXException, RuntimeException )
226 {
227     ResetableGuard aGuard( m_aLock );
228 
229     if (( m_bToolBarStartFound && !m_bToolBarEndFound ) ||
230         ( !m_bToolBarStartFound && m_bToolBarEndFound )     )
231     {
232         ::rtl::OUString aErrorMessage = getErrorLineString();
233         aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'toolbar' found!" ));
234         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
235     }
236 }
237 
startElement(const::rtl::OUString & aName,const Reference<XAttributeList> & xAttribs)238 void SAL_CALL OReadToolBoxDocumentHandler::startElement(
239     const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
240 throw(  SAXException, RuntimeException )
241 {
242     ResetableGuard aGuard( m_aLock );
243 
244     ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
245     if ( pToolBoxEntry != m_aToolBoxMap.end() )
246     {
247         switch ( pToolBoxEntry->second )
248         {
249             case TB_ELEMENT_TOOLBAR:
250             {
251                 if ( m_bToolBarStartFound )
252                 {
253                     ::rtl::OUString aErrorMessage = getErrorLineString();
254                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbar' cannot be embeded into 'toolbar:toolbar'!" ));
255                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
256                 }
257                         else
258                         {
259                             // Check if we have a UI name set in our XML file
260                             ::rtl::OUString aUIName;
261                             for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
262                       {
263                         pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
264                         if ( pToolBoxEntry != m_aToolBoxMap.end() )
265                         {
266                                     switch ( pToolBoxEntry->second )
267                                     {
268                                         case TB_ATTRIBUTE_UINAME:
269                                     aUIName = xAttribs->getValueByIndex( n );
270                                             break;
271                                         default:
272                                             break;
273                                     }
274                                 }
275                             }
276 
277                             if ( aUIName.getLength() > 0 )
278                             {
279                                 // Try to set UI name as a container property
280                                 Reference< XPropertySet > xPropSet( m_rItemContainer, UNO_QUERY );
281                                 if ( xPropSet.is() )
282                                 {
283                                     try
284                                     {
285                                         xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), makeAny( aUIName ) );
286                                     }
287                                     catch ( UnknownPropertyException& )
288                                     {
289                                     }
290                                 }
291                             }
292                         }
293 
294                 m_bToolBarStartFound = sal_True;
295             }
296             break;
297 
298             case TB_ELEMENT_TOOLBARITEM:
299             {
300                 if ( !m_bToolBarStartFound )
301                 {
302                     ::rtl::OUString aErrorMessage = getErrorLineString();
303                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbaritem' must be embeded into element 'toolbar:toolbar'!" ));
304                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
305                 }
306 
307                 if ( m_bToolBarSeparatorStartFound ||
308                      m_bToolBarBreakStartFound ||
309                      m_bToolBarSpaceStartFound ||
310                      m_bToolBarItemStartFound )
311                 {
312                     ::rtl::OUString aErrorMessage = getErrorLineString();
313                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbaritem is not a container!" ));
314                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
315                 }
316 
317                 ::rtl::OUString aAttribute;
318                 sal_Bool bAttributeURL  = sal_False;
319 
320                 m_bToolBarItemStartFound = sal_True;
321                 ::rtl::OUString        aLabel;
322                 ::rtl::OUString        aCommandURL;
323                 ::rtl::OUString        aHelpURL;
324                 ::rtl::OUString        aTooltip;
325                 ::rtl::OUString        aBitmapName;
326                 sal_uInt16      nItemBits( 0 );
327                 sal_uInt16      nWidth( 0 );
328                 sal_uInt16      nUserDef( 0 );
329                 sal_Bool        bVisible( sal_True );
330 
331                 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
332                 {
333                     pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
334                     if ( pToolBoxEntry != m_aToolBoxMap.end() )
335                     {
336                         switch ( pToolBoxEntry->second )
337                         {
338                             case TB_ATTRIBUTE_TEXT:
339                             {
340                                 aLabel = xAttribs->getValueByIndex( n );
341                             }
342                             break;
343 
344                             case TB_ATTRIBUTE_BITMAP:
345                             {
346                                 aBitmapName = xAttribs->getValueByIndex( n );
347                             }
348                             break;
349 
350                             case TB_ATTRIBUTE_URL:
351                             {
352                                 bAttributeURL   = sal_True;
353                                 aCommandURL     = xAttribs->getValueByIndex( n ).intern();
354                             }
355                             break;
356 
357                             case TB_ATTRIBUTE_ITEMBITS:
358                             {
359                                 nItemBits = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
360                             }
361                             break;
362 
363                             case TB_ATTRIBUTE_VISIBLE:
364                             {
365                                 if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
366                                     bVisible = sal_True;
367                                 else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
368                                     bVisible = sal_False;
369                                 else
370                                 {
371                                     ::rtl::OUString aErrorMessage = getErrorLineString();
372                                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute toolbar:visible must have value 'true' or 'false'!" ));
373                                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
374                                 }
375                             }
376                             break;
377 
378                             case TB_ATTRIBUTE_WIDTH:
379                             {
380                                 nWidth = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
381                             }
382                             break;
383 
384                             case TB_ATTRIBUTE_USER:
385                             {
386                                 nUserDef = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
387                             }
388                             break;
389 
390                             case TB_ATTRIBUTE_HELPID:
391                             {
392                                 aHelpURL = xAttribs->getValueByIndex( n );
393                             }
394                             break;
395 
396                             case TB_ATTRIBUTE_TOOLTIP:
397                             {
398                                 aTooltip = xAttribs->getValueByIndex( n );
399                             }
400                             break;
401 
402                             case TB_ATTRIBUTE_STYLE:
403                             {
404                                 // read space seperated item style list
405                                 ::rtl::OUString aTemp = xAttribs->getValueByIndex( n );
406                                 sal_Int32 nIndex = 0;
407 
408                                 do
409                                 {
410                                     ::rtl::OUString aToken  = aTemp.getToken( 0, ' ', nIndex );
411                                     if ( aToken.getLength() > 0 )
412                                     {
413                                         sal_Int32 nHashCode = aToken.hashCode();
414                                         if ( nHashCode == m_nHashCode_Style_Radio )
415                                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
416                                         else if ( nHashCode == m_nHashCode_Style_Left )
417                                             nItemBits |= ::com::sun::star::ui::ItemStyle::ALIGN_LEFT;
418                                         else if ( nHashCode == m_nHashCode_Style_AutoSize )
419                                             nItemBits |= ::com::sun::star::ui::ItemStyle::AUTO_SIZE;
420                                         else if ( nHashCode == m_nHashCode_Style_DropDown )
421                                             nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
422                                         else if ( nHashCode == m_nHashCode_Style_Repeat )
423                                             nItemBits |= ::com::sun::star::ui::ItemStyle::REPEAT;
424                                         else if ( nHashCode == m_nHashCode_Style_DropDownOnly )
425                                             nItemBits |= ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY;
426                                         else if ( nHashCode == m_nHashCode_Style_DropDown )
427                                             nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
428                                         else if ( nHashCode == m_nHashCode_Style_Text )
429                                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
430                                         else if ( nHashCode == m_nHashCode_Style_Image )
431                                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
432                                     }
433                                 }
434                                 while ( nIndex >= 0 );
435                             }
436                             break;
437 
438                                           default:
439                                               break;
440                         }
441                     }
442                 } // for
443 
444                 if ( !bAttributeURL )
445                 {
446                     ::rtl::OUString aErrorMessage = getErrorLineString();
447                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute toolbar:url must have a value!" ));
448                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
449                 }
450 
451                 if ( aCommandURL.getLength() > 0 )
452                 {
453                     Sequence< PropertyValue > aToolbarItemProp( 7 );
454                     aToolbarItemProp[0].Name = m_aCommandURL;
455                     aToolbarItemProp[1].Name = m_aHelpURL;
456                     aToolbarItemProp[2].Name = m_aLabel;
457                     aToolbarItemProp[3].Name = m_aType;
458                     aToolbarItemProp[4].Name = m_aStyle;
459                     aToolbarItemProp[5].Name = m_aIsVisible;
460                     aToolbarItemProp[6].Name = m_aTooltip;
461 
462                     aToolbarItemProp[0].Value <<= aCommandURL;
463                     aToolbarItemProp[1].Value <<= aHelpURL;
464                     aToolbarItemProp[2].Value <<= aLabel;
465                     aToolbarItemProp[3].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT );
466                     aToolbarItemProp[4].Value <<= nItemBits;
467                     aToolbarItemProp[5].Value <<= bVisible;
468                     aToolbarItemProp[6].Value <<= aTooltip;
469 
470                     m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
471                 }
472             }
473             break;
474 
475             case TB_ELEMENT_TOOLBARSPACE:
476             {
477                 if ( m_bToolBarSeparatorStartFound ||
478                      m_bToolBarBreakStartFound ||
479                      m_bToolBarSpaceStartFound ||
480                      m_bToolBarItemStartFound )
481                 {
482                     ::rtl::OUString aErrorMessage = getErrorLineString();
483                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarspace is not a container!" ));
484                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
485                 }
486 
487                 m_bToolBarSpaceStartFound = sal_True;
488 
489                 Sequence< PropertyValue > aToolbarItemProp( 2 );
490                 aToolbarItemProp[0].Name = m_aCommandURL;
491                 aToolbarItemProp[1].Name = m_aType;
492 
493                 aToolbarItemProp[0].Value <<= rtl::OUString();
494                 aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_SPACE;
495 
496                 m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
497             }
498             break;
499 
500             case TB_ELEMENT_TOOLBARBREAK:
501             {
502                 if ( m_bToolBarSeparatorStartFound ||
503                      m_bToolBarBreakStartFound ||
504                      m_bToolBarSpaceStartFound ||
505                      m_bToolBarItemStartFound )
506                 {
507                     ::rtl::OUString aErrorMessage = getErrorLineString();
508                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarbreak is not a container!" ));
509                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
510                 }
511 
512                 m_bToolBarBreakStartFound = sal_True;
513 
514                 Sequence< PropertyValue > aToolbarItemProp( 2 );
515                 aToolbarItemProp[0].Name = m_aCommandURL;
516                 aToolbarItemProp[1].Name = m_aType;
517 
518                 aToolbarItemProp[0].Value <<= rtl::OUString();
519                 aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK;
520 
521                 m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
522             }
523             break;
524 
525             case TB_ELEMENT_TOOLBARSEPARATOR:
526             {
527                 if ( m_bToolBarSeparatorStartFound ||
528                      m_bToolBarBreakStartFound ||
529                      m_bToolBarSpaceStartFound ||
530                      m_bToolBarItemStartFound )
531                 {
532                     ::rtl::OUString aErrorMessage = getErrorLineString();
533                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarseparator is not a container!" ));
534                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
535                 }
536 
537                 m_bToolBarSeparatorStartFound = sal_True;
538 
539                 Sequence< PropertyValue > aToolbarItemProp( 2 );
540                 aToolbarItemProp[0].Name = m_aCommandURL;
541                 aToolbarItemProp[1].Name = m_aType;
542 
543                 aToolbarItemProp[0].Value <<= rtl::OUString();
544                 aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
545 
546                 m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
547             }
548             break;
549 
550                   default:
551                       break;
552         }
553     }
554 }
555 
endElement(const::rtl::OUString & aName)556 void SAL_CALL OReadToolBoxDocumentHandler::endElement(const ::rtl::OUString& aName)
557 throw(  SAXException, RuntimeException )
558 {
559     ResetableGuard aGuard( m_aLock );
560 
561     ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
562     if ( pToolBoxEntry != m_aToolBoxMap.end() )
563     {
564         switch ( pToolBoxEntry->second )
565         {
566             case TB_ELEMENT_TOOLBAR:
567             {
568                 if ( !m_bToolBarStartFound )
569                 {
570                     ::rtl::OUString aErrorMessage = getErrorLineString();
571                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar' found, but no start element 'toolbar'" ));
572                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
573                 }
574 
575                 m_bToolBarStartFound = sal_False;
576             }
577             break;
578 
579             case TB_ELEMENT_TOOLBARITEM:
580             {
581                 if ( !m_bToolBarItemStartFound )
582                 {
583                     ::rtl::OUString aErrorMessage = getErrorLineString();
584                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbaritem' found, but no start element 'toolbar:toolbaritem'" ));
585                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
586                 }
587 
588                 m_bToolBarItemStartFound = sal_False;
589             }
590             break;
591 
592             case TB_ELEMENT_TOOLBARBREAK:
593             {
594                 if ( !m_bToolBarBreakStartFound )
595                 {
596                     ::rtl::OUString aErrorMessage = getErrorLineString();
597                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarbreak' found, but no start element 'toolbar:toolbarbreak'" ));
598                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
599                 }
600 
601                 m_bToolBarBreakStartFound = sal_False;
602             }
603             break;
604 
605             case TB_ELEMENT_TOOLBARSPACE:
606             {
607                 if ( !m_bToolBarSpaceStartFound )
608                 {
609                     ::rtl::OUString aErrorMessage = getErrorLineString();
610                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarspace' found, but no start element 'toolbar:toolbarspace'" ));
611                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
612                 }
613 
614                 m_bToolBarSpaceStartFound = sal_False;
615             }
616             break;
617 
618             case TB_ELEMENT_TOOLBARSEPARATOR:
619             {
620                 if ( !m_bToolBarSeparatorStartFound )
621                 {
622                     ::rtl::OUString aErrorMessage = getErrorLineString();
623                     aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarseparator' found, but no start element 'toolbar:toolbarseparator'" ));
624                     throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
625                 }
626 
627                 m_bToolBarSeparatorStartFound = sal_False;
628             }
629             break;
630 
631                   default:
632                       break;
633         }
634     }
635 }
636 
characters(const::rtl::OUString &)637 void SAL_CALL OReadToolBoxDocumentHandler::characters(const ::rtl::OUString&)
638 throw(  SAXException, RuntimeException )
639 {
640 }
641 
ignorableWhitespace(const::rtl::OUString &)642 void SAL_CALL OReadToolBoxDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
643 throw(  SAXException, RuntimeException )
644 {
645 }
646 
processingInstruction(const::rtl::OUString &,const::rtl::OUString &)647 void SAL_CALL OReadToolBoxDocumentHandler::processingInstruction(
648     const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
649 throw(  SAXException, RuntimeException )
650 {
651 }
652 
setDocumentLocator(const Reference<XLocator> & xLocator)653 void SAL_CALL OReadToolBoxDocumentHandler::setDocumentLocator(
654     const Reference< XLocator > &xLocator)
655 throw(  SAXException, RuntimeException )
656 {
657     ResetableGuard aGuard( m_aLock );
658 
659     m_xLocator = xLocator;
660 }
661 
getErrorLineString()662 ::rtl::OUString OReadToolBoxDocumentHandler::getErrorLineString()
663 {
664     ResetableGuard aGuard( m_aLock );
665 
666     char buffer[32];
667 
668     if ( m_xLocator.is() )
669     {
670         snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
671         return ::rtl::OUString::createFromAscii( buffer );
672     }
673     else
674         return ::rtl::OUString();
675 }
676 
677 
678 //_________________________________________________________________________________________________________________
679 //  OWriteToolBoxDocumentHandler
680 //_________________________________________________________________________________________________________________
681 
OWriteToolBoxDocumentHandler(const Reference<XIndexAccess> & rItemAccess,Reference<XDocumentHandler> & rWriteDocumentHandler)682 OWriteToolBoxDocumentHandler::OWriteToolBoxDocumentHandler(
683     const Reference< XIndexAccess >& rItemAccess,
684     Reference< XDocumentHandler >& rWriteDocumentHandler ) :
685     ThreadHelpBase( &Application::GetSolarMutex() ),
686     m_xWriteDocumentHandler( rWriteDocumentHandler ),
687     m_rItemAccess( rItemAccess )
688 {
689     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
690     m_xEmptyList        = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
691     m_aAttributeType    = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
692     m_aXMLXlinkNS       = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
693     m_aXMLToolbarNS     = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR_PREFIX ));
694 }
695 
~OWriteToolBoxDocumentHandler()696 OWriteToolBoxDocumentHandler::~OWriteToolBoxDocumentHandler()
697 {
698 }
699 
WriteToolBoxDocument()700 void OWriteToolBoxDocumentHandler::WriteToolBoxDocument() throw
701 ( SAXException, RuntimeException )
702 {
703     ResetableGuard aGuard( m_aLock );
704 
705     m_xWriteDocumentHandler->startDocument();
706 
707     // write DOCTYPE line!
708     Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
709     if ( xExtendedDocHandler.is() )
710     {
711         xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( TOOLBAR_DOCTYPE )) );
712         m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
713     }
714 
715     ::rtl::OUString aUIName;
716     Reference< XPropertySet > xPropSet( m_rItemAccess, UNO_QUERY );
717     if ( xPropSet.is() )
718     {
719         try
720         {
721             xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
722         }
723         catch ( UnknownPropertyException& )
724         {
725         }
726     }
727 
728     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
729     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
730 
731     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_TOOLBAR )),
732                          m_aAttributeType,
733                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR )) );
734 
735     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
736                          m_aAttributeType,
737                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
738 
739     if ( aUIName.getLength() > 0 )
740         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_UINAME )),
741                              m_aAttributeType,
742                              aUIName );
743 
744     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )), pList );
745     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
746 
747     sal_Int32  nItemCount = m_rItemAccess->getCount();
748     Any        aAny;
749 
750     for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
751     {
752         Sequence< PropertyValue > aProps;
753         aAny = m_rItemAccess->getByIndex( nItemPos );
754         if ( aAny >>= aProps )
755         {
756             ::rtl::OUString    aCommandURL;
757             ::rtl::OUString    aLabel;
758             ::rtl::OUString    aHelpURL;
759             ::rtl::OUString    aTooltip;
760             sal_Bool    bVisible( sal_True );
761             sal_Int16   nType( ::com::sun::star::ui::ItemType::DEFAULT );
762             sal_Int16   nWidth( 0 );
763             sal_Int16   nStyle( 0 );
764 
765             ExtractToolbarParameters( aProps, aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible, nType );
766             if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
767                 WriteToolBoxItem( aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible );
768             else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE )
769                 WriteToolBoxSpace();
770             else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE )
771                 WriteToolBoxSeparator();
772             else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK )
773                 WriteToolBoxBreak();
774         }
775     }
776 
777     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
778     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )) );
779     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
780     m_xWriteDocumentHandler->endDocument();
781 }
782 
783 //_________________________________________________________________________________________________________________
784 //  protected member functions
785 //_________________________________________________________________________________________________________________
786 
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)787 void OWriteToolBoxDocumentHandler::WriteToolBoxItem(
788     const ::rtl::OUString& rCommandURL,
789     const ::rtl::OUString& rLabel,
790     const ::rtl::OUString& rHelpURL,
791     const ::rtl::OUString& rTooltip,
792     sal_Int16       nStyle,
793     sal_Int16       nWidth,
794     sal_Bool        bVisible )
795 throw ( SAXException, RuntimeException )
796 {
797     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
798     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
799 
800     if ( m_aAttributeURL.getLength() == 0 )
801     {
802         m_aAttributeURL = m_aXMLXlinkNS;
803         m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL ));
804     }
805 
806     // save required attribute (URL)
807     pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL );
808 
809     if ( rLabel.getLength() > 0 )
810     {
811         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TEXT )),
812                              m_aAttributeType,
813                              rLabel );
814     }
815 
816     if ( bVisible == sal_False )
817     {
818         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_VISIBLE )),
819                              m_aAttributeType,
820                              ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) );
821     }
822 
823     if ( rHelpURL.getLength() > 0 )
824     {
825         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HELPID )),
826                              m_aAttributeType,
827                              rHelpURL );
828     }
829 
830     if ( rTooltip.getLength() > 0 )
831     {
832         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TOOLTIP )),
833                              m_aAttributeType,
834                              rTooltip );
835     }
836 
837     if ( nStyle > 0 )
838     {
839         rtl::OUString aValue;
840         ToolboxStyleItem* pStyle = Styles;
841 
842         for ( sal_Int32 nIndex = 0; nIndex < nStyleItemEntries; ++nIndex, ++pStyle )
843         {
844             if ( nStyle & pStyle->nBit )
845             {
846                 if ( aValue.getLength() )
847                     aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ) );
848                 aValue += rtl::OUString::createFromAscii( pStyle->attrName );
849             }
850         }
851         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE )),
852                              m_aAttributeType,
853                              aValue );
854     }
855 
856     if ( nWidth > 0 )
857     {
858         pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )),
859                              m_aAttributeType,
860                              ::rtl::OUString::valueOf( sal_Int32( nWidth )) );
861     }
862 
863     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
864     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )), xList );
865     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
866     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )) );
867 }
868 
WriteToolBoxSpace()869 void OWriteToolBoxDocumentHandler::WriteToolBoxSpace() throw
870 ( SAXException, RuntimeException )
871 {
872     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
873     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )), m_xEmptyList );
874     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
875     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )) );
876 }
877 
WriteToolBoxBreak()878 void OWriteToolBoxDocumentHandler::WriteToolBoxBreak() throw
879 ( SAXException, RuntimeException )
880 {
881     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
882     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )), m_xEmptyList );
883     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
884     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )) );
885 }
886 
WriteToolBoxSeparator()887 void OWriteToolBoxDocumentHandler::WriteToolBoxSeparator() throw
888 ( SAXException, RuntimeException )
889 {
890     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
891     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )), m_xEmptyList );
892     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
893     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )) );
894 }
895 
896 } // namespace framework
897 
898