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 #include <xml/menudocumenthandler.hxx>
37 #include <framework/menuconfiguration.hxx>
38 #include <framework/addonmenu.hxx>
39 
40 //_________________________________________________________________________________________________________________
41 //	interface includes
42 //_________________________________________________________________________________________________________________
43 
44 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
45 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
46 #include <com/sun/star/ui/ItemType.hpp>
47 #include <com/sun/star/ui/ItemStyle.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 
51 //_________________________________________________________________________________________________________________
52 //	other includes
53 //_________________________________________________________________________________________________________________
54 #include <comphelper/processfactory.hxx>
55 #include <rtl/logfile.hxx>
56 #include <comphelper/attributelist.hxx>
57 
58 //_________________________________________________________________________________________________________________
59 //	defines
60 //_________________________________________________________________________________________________________________
61 
62 #define XMLNS_MENU				    "http://openoffice.org/2001/menu"
63 #define XMLNS_PREFIX			    "menu:"
64 
65 #define ELEMENT_MENUBAR			    "http://openoffice.org/2001/menu^menubar"
66 #define ELEMENT_MENU			    "http://openoffice.org/2001/menu^menu"
67 #define ELEMENT_MENUPOPUP		    "http://openoffice.org/2001/menu^menupopup"
68 #define ELEMENT_MENUITEM		    "http://openoffice.org/2001/menu^menuitem"
69 #define ELEMENT_MENUSEPARATOR	    "http://openoffice.org/2001/menu^menuseparator"
70 
71 #define ELEMENT_NS_MENUBAR			"menu:menubar"
72 #define ELEMENT_NS_MENU				"menu:menu"
73 #define ELEMENT_NS_MENUPOPUP		"menu:menupopup"
74 #define ELEMENT_NS_MENUITEM			"menu:menuitem"
75 #define ELEMENT_NS_MENUSEPARATOR	"menu:menuseparator"
76 
77 #define ATTRIBUTE_ID			    "http://openoffice.org/2001/menu^id"
78 #define ATTRIBUTE_LABEL			    "http://openoffice.org/2001/menu^label"
79 #define ATTRIBUTE_HELPID		    "http://openoffice.org/2001/menu^helpid"
80 #define ATTRIBUTE_LINEBREAK		    "http://openoffice.org/2001/menu^linebreak"
81 #define ATTRIBUTE_STYLE		    "http://openoffice.org/2001/menu^style"
82 
83 #define ATTRIBUTE_NS_ID			    "menu:id"
84 #define ATTRIBUTE_NS_LABEL		    "menu:label"
85 #define ATTRIBUTE_NS_HELPID		    "menu:helpid"
86 #define ATTRIBUTE_NS_LINEBREAK	    "menu:linebreak"
87 #define ATTRIBUTE_NS_STYLE		    "menu:style"
88 
89 #define ATTRIBUTE_XMLNS_MENU	    "xmlns:menu"
90 
91 #define ATTRIBUTE_TYPE_CDATA	    "CDATA"
92 
93 #define MENUBAR_DOCTYPE			    "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">"
94 
95 #define ATTRIBUTE_ITEMSTYLE_TEXT    "text"
96 #define ATTRIBUTE_ITEMSTYLE_IMAGE    "image"
97 #define ATTRIBUTE_ITEMSTYLE_RADIO    "radio"
98 
99 // Property names of a menu/menu item ItemDescriptor
100 static const char ITEM_DESCRIPTOR_COMMANDURL[]  = "CommandURL";
101 static const char ITEM_DESCRIPTOR_HELPURL[]     = "HelpURL";
102 static const char ITEM_DESCRIPTOR_CONTAINER[]   = "ItemDescriptorContainer";
103 static const char ITEM_DESCRIPTOR_LABEL[]       = "Label";
104 static const char ITEM_DESCRIPTOR_TYPE[]        = "Type";
105 static const char ITEM_DESCRIPTOR_STYLE[]       = "Style";
106 
107 // special popup menus (filled during runtime) must be saved as an empty popup menu or menuitem!!!
108 static const sal_Int32 CMD_PROTOCOL_SIZE        = 5;
109 static const char CMD_PROTOCOL[]                = ".uno:";
110 static const char ADDDIRECT_CMD[]               = ".uno:AddDirect" ;
111 static const char AUTOPILOTMENU_CMD[]           = ".uno:AutoPilotMenu" ;
112 static const char FILEMENU_CMD[]                = ".uno:Picklist" ;
113 static const char WINDOWMENU_CMD[]              = ".uno:WindowList" ;
114 
115 //_________________________________________________________________________________________________________________
116 //	using namespaces
117 //_________________________________________________________________________________________________________________
118 
119 using namespace ::com::sun::star::uno;
120 using namespace ::com::sun::star::lang;
121 using namespace ::com::sun::star::beans;
122 using namespace ::com::sun::star::xml::sax;
123 using namespace ::com::sun::star::container;
124 using namespace ::com::sun::star::ui;
125 
126 namespace framework
127 {
128 
129 struct MenuStyleItem
130 {
131     sal_Int16 nBit;
132     const char* attrName;
133 };
134 
135 MenuStyleItem MenuItemStyles[ ] = {
136     { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE },
137     { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT },
138     { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO }
139 };
140 
141 
142 sal_Int32 nMenuStyleItemEntries = sizeof( MenuItemStyles ) / sizeof( MenuItemStyles[ 0 ] );
143 
144 static void ExtractMenuParameters( const Sequence< PropertyValue > rProp,
145                                    ::rtl::OUString&                       rCommandURL,
146                                    ::rtl::OUString&                       rLabel,
147                                    ::rtl::OUString&                       rHelpURL,
148                                    Reference< XIndexAccess >&      rSubMenu,
149                                    sal_Int16&                      rType,
150                                    sal_Int16&                      rStyle )
151 {
152     for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
153     {
154         if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
155         {
156             rProp[i].Value >>= rCommandURL;
157             rCommandURL = rCommandURL.intern();
158         }
159         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
160         {
161             rProp[i].Value >>= rHelpURL;
162         }
163         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_CONTAINER ))
164         {
165             rProp[i].Value >>= rSubMenu;
166         }
167         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
168         {
169             rProp[i].Value >>= rLabel;
170         }
171         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
172         {
173             rProp[i].Value >>= rType;
174         }
175         else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
176         {
177             rProp[i].Value >>= rStyle;
178         }
179     }
180 }
181 
182 
183 // -----------------------------------------------------------------------------
184 // Base class implementation
185 
186 ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() :
187 	m_xLocator( 0 ),
188 	m_xReader( 0 ),
189 	m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )),
190 	m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )),
191 	m_aContainer( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER )),
192 	m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )),
193     m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL )),
194     m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE ))
195 {
196 }
197 
198 ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
199 {
200 }
201 
202 void SAL_CALL ReadMenuDocumentHandlerBase::ignorableWhitespace(
203 	const ::rtl::OUString& )
204 throw( SAXException, RuntimeException )
205 {
206 }
207 
208 void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction(
209 	const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
210 throw( SAXException, RuntimeException )
211 {
212 }
213 
214 void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
215 	const Reference< XLocator > &xLocator)
216 throw(	SAXException, RuntimeException )
217 {
218 	m_xLocator = xLocator;
219 }
220 
221 ::rtl::OUString ReadMenuDocumentHandlerBase::getErrorLineString()
222 {
223 	char buffer[32];
224 
225 	if ( m_xLocator.is() )
226 	{
227 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
228 		return ::rtl::OUString::createFromAscii( buffer );
229 	}
230 	else
231 		return ::rtl::OUString();
232 }
233 
234 void ReadMenuDocumentHandlerBase::initPropertyCommon(
235 	Sequence< PropertyValue > &rProps, const rtl::OUString &rCommandURL,
236     const rtl::OUString &rHelpId, const rtl::OUString &rLabel, sal_Int16 nItemStyleBits )
237 {
238 	rProps[0].Name = m_aCommandURL;
239 	rProps[1].Name = m_aHelpURL;
240 	rProps[2].Name = m_aContainer;
241 	rProps[3].Name = m_aLabel;
242     rProps[4].Name = m_aStyle;
243     rProps[5].Name = m_aType;
244 
245 	// Common values
246 	rProps[0].Value <<= rCommandURL.intern();
247 	rProps[1].Value <<= rHelpId;
248 	rProps[2].Value <<= Reference< XIndexContainer >();
249 	rProps[3].Value <<= rLabel;
250     rProps[4].Value <<= nItemStyleBits;
251     rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
252 }
253 
254 // -----------------------------------------------------------------------------
255 
256 OReadMenuDocumentHandler::OReadMenuDocumentHandler(
257 	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
258 	const Reference< XIndexContainer >& rMenuBarContainer )
259 :	m_nElementDepth( 0 ),
260 	m_bMenuBarMode( sal_False ),
261 	m_xMenuBarContainer( rMenuBarContainer ),
262       m_xContainerFactory( rMenuBarContainer, UNO_QUERY ),
263 	mxServiceFactory(xServiceFactory)
264 {
265 }
266 
267 // #110897#
268 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuDocumentHandler::getServiceFactory()
269 {
270 	// #110897#
271 	return mxServiceFactory;
272 }
273 
274 OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
275 {
276 }
277 
278 
279 void SAL_CALL OReadMenuDocumentHandler::startDocument(void)
280 	throw ( SAXException, RuntimeException )
281 {
282 }
283 
284 
285 void SAL_CALL OReadMenuDocumentHandler::endDocument(void)
286 	throw( SAXException, RuntimeException )
287 {
288 	if ( m_nElementDepth > 0 )
289 	{
290 		::rtl::OUString aErrorMessage = getErrorLineString();
291 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" ));
292 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
293 	}
294 }
295 
296 
297 void SAL_CALL OReadMenuDocumentHandler::startElement(
298 	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
299 throw( SAXException, RuntimeException )
300 {
301 	if ( m_bMenuBarMode )
302 	{
303 		++m_nElementDepth;
304 		m_xReader->startElement( aName, xAttrList );
305 	}
306 	else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
307 	{
308 		++m_nElementDepth;
309 		m_bMenuBarMode = sal_True;
310 
311 		// #110897# m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory ));
312 		m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( getServiceFactory(), m_xMenuBarContainer, m_xContainerFactory ));
313 
314 		m_xReader->startDocument();
315 	}
316 }
317 
318 
319 void SAL_CALL OReadMenuDocumentHandler::characters(const rtl::OUString&)
320 throw(	SAXException, RuntimeException )
321 {
322 }
323 
324 
325 void SAL_CALL OReadMenuDocumentHandler::endElement( const ::rtl::OUString& aName )
326 	throw( SAXException, RuntimeException )
327 {
328 	if ( m_bMenuBarMode )
329 	{
330 		--m_nElementDepth;
331 		m_xReader->endElement( aName );
332 		if ( 0 == m_nElementDepth )
333 		{
334 			m_xReader->endDocument();
335 			m_xReader = Reference< XDocumentHandler >();
336 			m_bMenuBarMode = sal_False;
337 			if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
338 			{
339 				::rtl::OUString aErrorMessage = getErrorLineString();
340 				aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menubar expected!" ));
341 				throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
342 			}
343 		}
344 	}
345 }
346 
347 
348 // -----------------------------------------------------------------------------
349 
350 
351 // #110897#
352 OReadMenuBarHandler::OReadMenuBarHandler(
353 	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
354     const Reference< XIndexContainer >& rMenuBarContainer,
355     const Reference< XSingleComponentFactory >& rFactory          )
356 :	m_nElementDepth( 0 ),
357 	m_bMenuMode( sal_False ),
358 	m_xMenuBarContainer( rMenuBarContainer ),
359       m_xContainerFactory( rFactory ),
360 	mxServiceFactory( xServiceFactory )
361 {
362 }
363 
364 // #110897#
365 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuBarHandler::getServiceFactory()
366 {
367 	// #110897#
368 	return mxServiceFactory;
369 }
370 
371 OReadMenuBarHandler::~OReadMenuBarHandler()
372 {
373 }
374 
375 
376 void SAL_CALL OReadMenuBarHandler::startDocument(void)
377 	throw ( SAXException, RuntimeException )
378 {
379 }
380 
381 
382 void SAL_CALL OReadMenuBarHandler::endDocument(void)
383 	throw( SAXException, RuntimeException )
384 {
385 }
386 
387 
388 void SAL_CALL OReadMenuBarHandler::startElement(
389 	const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
390 throw( SAXException, RuntimeException )
391 {
392 	if ( m_bMenuMode )
393 	{
394 		++m_nElementDepth;
395 		m_xReader->startElement( rName, xAttrList );
396 	}
397 	else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
398 	{
399 		++m_nElementDepth;
400 
401 		::rtl::OUString aHelpId;
402 		::rtl::OUString aCommandId;
403 		::rtl::OUString aLabel;
404         sal_Int16 nItemBits(0);
405 
406 		m_bMenuMode = sal_True;
407 
408         // Container must be factory to create sub container
409         Reference< XComponentContext > xComponentContext;
410         Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
411         xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
412             xComponentContext;
413 
414         Reference< XIndexContainer > xSubItemContainer;
415         if ( m_xContainerFactory.is() )
416             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
417 
418 		if ( xSubItemContainer.is() )
419         {
420             // read attributes for menu
421 		    for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
422 		    {
423 			    ::rtl::OUString aName = xAttrList->getNameByIndex( i );
424 			    ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
425 			    if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
426 				    aCommandId = aValue;
427 			    else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
428 				    aLabel = aValue;
429 			    else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
430 				    aHelpId = aValue;
431                 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
432                 {
433                     ::rtl::OUString aTemp( aValue );
434                     sal_Int32 nIndex = 0;
435                     do
436                     {
437                         ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
438                         if ( aToken.getLength() > 0 )
439                         {
440                             if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
441                                 nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
442                             else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
443                                 nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
444                             else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
445                                 nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
446                         }
447                     }
448                     while ( nIndex >= 0 );
449                 }
450 		    }
451 
452 		    if ( aCommandId.getLength() > 0 )
453 		    {
454                 Sequence< PropertyValue > aSubMenuProp( 6 );
455                 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
456 				aSubMenuProp[2].Value <<= xSubItemContainer;
457 
458                 m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) );
459 		    }
460 		    else
461 		    {
462 			    ::rtl::OUString aErrorMessage = getErrorLineString();
463 			    aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
464 			    throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
465 		    }
466 
467 		    m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
468 		    m_xReader->startDocument();
469         }
470 	}
471 	else
472 	{
473 		::rtl::OUString aErrorMessage = getErrorLineString();
474 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "element menu expected!" ));
475 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
476 	}
477 }
478 
479 
480 void SAL_CALL OReadMenuBarHandler::characters(const rtl::OUString&)
481 throw(	SAXException, RuntimeException )
482 {
483 }
484 
485 
486 void OReadMenuBarHandler::endElement( const ::rtl::OUString& aName )
487 	throw( SAXException, RuntimeException )
488 {
489 	if ( m_bMenuMode )
490 	{
491 		--m_nElementDepth;
492 		if ( 0 == m_nElementDepth )
493 		{
494 			m_xReader->endDocument();
495 			m_xReader = Reference< XDocumentHandler >();
496 			m_bMenuMode = sal_False;
497 			if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
498 			{
499 				::rtl::OUString aErrorMessage = getErrorLineString();
500 				aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
501 				throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
502 			}
503 		}
504 		else
505 			m_xReader->endElement( aName );
506 	}
507 }
508 
509 
510 // -----------------------------------------------------------------------------
511 
512 
513 OReadMenuHandler::OReadMenuHandler(
514     const Reference< XIndexContainer >& rMenuContainer,
515     const Reference< XSingleComponentFactory >& rFactory          ) :
516     m_nElementDepth( 0 ),
517     m_bMenuPopupMode( sal_False ),
518     m_xMenuContainer( rMenuContainer ),
519     m_xContainerFactory( rFactory )
520 {
521 }
522 
523 
524 OReadMenuHandler::~OReadMenuHandler()
525 {
526 }
527 
528 
529 void SAL_CALL OReadMenuHandler::startDocument(void)
530 	throw ( SAXException, RuntimeException )
531 {
532 }
533 
534 
535 void SAL_CALL OReadMenuHandler::endDocument(void)
536 	throw( SAXException, RuntimeException)
537 {
538 }
539 
540 
541 void SAL_CALL OReadMenuHandler::startElement(
542 	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
543 throw( SAXException, RuntimeException )
544 {
545 	if ( m_bMenuPopupMode )
546 	{
547 		++m_nElementDepth;
548 		m_xReader->startElement( aName, xAttrList );
549 	}
550 	else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
551 	{
552 		++m_nElementDepth;
553 		m_bMenuPopupMode = sal_True;
554 		m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
555 		m_xReader->startDocument();
556 	}
557 	else
558 	{
559 		::rtl::OUString aErrorMessage = getErrorLineString();
560 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
561 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
562 	}
563 }
564 
565 
566 void SAL_CALL OReadMenuHandler::characters(const rtl::OUString&)
567 throw(	SAXException, RuntimeException )
568 {
569 }
570 
571 
572 void SAL_CALL OReadMenuHandler::endElement( const ::rtl::OUString& aName )
573 	throw( SAXException, RuntimeException )
574 {
575 	if ( m_bMenuPopupMode )
576 	{
577 		--m_nElementDepth;
578 		if ( 0 == m_nElementDepth )
579 		{
580 			m_xReader->endDocument();
581 			m_xReader = Reference< XDocumentHandler >();
582 			m_bMenuPopupMode = sal_False;
583 			if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
584 			{
585 				::rtl::OUString aErrorMessage = getErrorLineString();
586 				aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menupopup expected!" ));
587 				throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
588 			}
589 		}
590 		else
591 			m_xReader->endElement( aName );
592 	}
593 }
594 
595 
596 // -----------------------------------------------------------------------------
597 
598 
599 OReadMenuPopupHandler::OReadMenuPopupHandler(
600     const Reference< XIndexContainer >& rMenuContainer,
601     const Reference< XSingleComponentFactory >& rFactory          ) :
602     m_nElementDepth( 0 ),
603     m_bMenuMode( sal_False ),
604     m_xMenuContainer( rMenuContainer ),
605     m_xContainerFactory( rFactory ),
606     m_nNextElementExpected( ELEM_CLOSE_NONE )
607 {
608 }
609 
610 
611 OReadMenuPopupHandler::~OReadMenuPopupHandler()
612 {
613 }
614 
615 
616 void SAL_CALL OReadMenuPopupHandler::startDocument(void)
617 	throw ( SAXException, RuntimeException )
618 {
619 }
620 
621 
622 void SAL_CALL OReadMenuPopupHandler::endDocument(void)
623 	throw( SAXException, RuntimeException)
624 {
625 }
626 
627 void SAL_CALL OReadMenuPopupHandler::startElement(
628 	const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
629 throw( SAXException, RuntimeException )
630 {
631 	++m_nElementDepth;
632 
633 	if ( m_bMenuMode )
634 		m_xReader->startElement( rName, xAttrList );
635 	else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
636 	{
637 		::rtl::OUString aHelpId;
638 		::rtl::OUString aCommandId;
639 		::rtl::OUString aLabel;
640         sal_Int16 nItemBits(0);
641 
642 		m_bMenuMode = sal_True;
643 
644         // Container must be factory to create sub container
645         if ( !m_xComponentContext.is() )
646         {
647             const Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
648             m_xComponentContext.set(xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
649         }
650 
651         Reference< XIndexContainer > xSubItemContainer;
652         if ( m_xContainerFactory.is() )
653             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
654 
655         // read attributes for menu
656 		for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
657 		{
658 			::rtl::OUString aName = xAttrList->getNameByIndex( i );
659 			::rtl::OUString aValue = xAttrList->getValueByIndex( i );
660 			if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
661 				aCommandId = aValue;
662 			else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
663 				aLabel = aValue;
664 			else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
665 				aHelpId = aValue;
666             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
667             {
668                 ::rtl::OUString aTemp( aValue );
669                 sal_Int32 nIndex = 0;
670                 do
671                 {
672                     ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
673                     if ( aToken.getLength() > 0 )
674                     {
675                         if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
676                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
677                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
678                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
679                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
680                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
681                     }
682                 }
683                 while ( nIndex >= 0 );
684             }
685 
686 		}
687 
688 		if ( aCommandId.getLength() > 0 )
689 		{
690             Sequence< PropertyValue > aSubMenuProp( 6 );
691             initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
692 			aSubMenuProp[2].Value <<= xSubItemContainer;
693 
694             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) );
695 		}
696 		else
697 		{
698 			::rtl::OUString aErrorMessage = getErrorLineString();
699 			aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
700 			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
701 		}
702 
703 		m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
704 		m_xReader->startDocument();
705 	}
706 	else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
707 	{
708 		::rtl::OUString aHelpId;
709 		::rtl::OUString aCommandId;
710 		::rtl::OUString aLabel;
711         sal_Int16 nItemBits(0);
712 		// read attributes for menu item
713 		for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
714 		{
715 			::rtl::OUString aName = xAttrList->getNameByIndex( i );
716 			::rtl::OUString aValue = xAttrList->getValueByIndex( i );
717 			if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
718 				aCommandId = aValue;
719 			else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
720 				aLabel = aValue;
721 			else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
722 				aHelpId = aValue;
723             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
724             {
725                 ::rtl::OUString aTemp( aValue );
726                 sal_Int32 nIndex = 0;
727                 do
728                 {
729                     ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
730                     if ( aToken.getLength() > 0 )
731                     {
732                         if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
733                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
734                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
735                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
736                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
737                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
738                     }
739                 }
740                 while ( nIndex >= 0 );
741             }
742 
743 		}
744 
745 		if ( aCommandId.getLength() > 0 )
746 		{
747             Sequence< PropertyValue > aMenuItem( 6 );
748             initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
749 			aMenuItem[2].Value <<= Reference< XIndexContainer >();
750 
751             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
752 		}
753 
754 		m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
755 	}
756 	else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
757 	{
758         Sequence< PropertyValue > aMenuSeparator( 1 );
759         aMenuSeparator[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ));
760         aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
761 
762         m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
763 
764         m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR;
765 	}
766 	else
767 	{
768 		::rtl::OUString aErrorMessage = getErrorLineString();
769 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
770 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
771 	}
772 }
773 
774 
775 void SAL_CALL OReadMenuPopupHandler::characters(const rtl::OUString&)
776 throw(	SAXException, RuntimeException )
777 {
778 }
779 
780 
781 void SAL_CALL OReadMenuPopupHandler::endElement( const ::rtl::OUString& aName )
782 	throw( SAXException, RuntimeException )
783 {
784 	--m_nElementDepth;
785 	if ( m_bMenuMode )
786 	{
787 		if ( 0 == m_nElementDepth )
788 		{
789 			m_xReader->endDocument();
790 			m_xReader = Reference< XDocumentHandler >();
791 			m_bMenuMode = sal_False;
792 			if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
793 			{
794 				::rtl::OUString aErrorMessage = getErrorLineString();
795 				aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
796 				throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
797 			}
798 		}
799 		else
800 			m_xReader->endElement( aName );
801 	}
802 	else
803 	{
804 		if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
805 		{
806 			if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
807 			{
808 				::rtl::OUString aErrorMessage = getErrorLineString();
809 				aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuitem expected!" ));
810 				throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
811 			}
812 		}
813 		else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
814 		{
815 			if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
816 			{
817 				::rtl::OUString aErrorMessage = getErrorLineString();
818 				aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuseparator expected!" ));
819 				throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
820 			}
821 		}
822 
823 		m_nNextElementExpected = ELEM_CLOSE_NONE;
824 	}
825 }
826 
827 
828 // --------------------------------- Write XML ---------------------------------
829 
830 
831 OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
832     const Reference< XIndexAccess >& rMenuBarContainer,
833     const Reference< XDocumentHandler >& rDocumentHandler ) :
834 	m_xMenuBarContainer( rMenuBarContainer ),
835 	m_xWriteDocumentHandler( rDocumentHandler )
836 {
837 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
838 	m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
839 	m_aAttributeType = 	::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
840 }
841 
842 
843 OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
844 {
845 }
846 
847 
848 void OWriteMenuDocumentHandler::WriteMenuDocument()
849 throw ( SAXException, RuntimeException )
850 {
851 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
852 	Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
853 
854 	m_xWriteDocumentHandler->startDocument();
855 
856 	// write DOCTYPE line!
857 	Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
858 	if ( xExtendedDocHandler.is() )
859 	{
860 		xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MENUBAR_DOCTYPE )) );
861 		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
862 	}
863 
864 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_MENU )),
865 						 m_aAttributeType,
866 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU )) );
867 
868 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
869 						 m_aAttributeType,
870 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "menubar" )) );
871 
872 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )), pList );
873 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
874 
875 	WriteMenu( m_xMenuBarContainer );
876 
877 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
878 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )) );
879 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
880 	m_xWriteDocumentHandler->endDocument();
881 }
882 
883 
884 void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
885 throw ( SAXException, RuntimeException )
886 {
887 	sal_Int32  nItemCount = rMenuContainer->getCount();
888 	sal_Bool   bSeparator = sal_False;
889     Any        aAny;
890 
891 	for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
892 	{
893         Sequence< PropertyValue > aProps;
894         aAny = rMenuContainer->getByIndex( nItemPos );
895         if ( aAny >>= aProps )
896         {
897             ::rtl::OUString    aCommandURL;
898             ::rtl::OUString    aLabel;
899             ::rtl::OUString    aHelpURL;
900             sal_Int16   nType( ::com::sun::star::ui::ItemType::DEFAULT );
901             sal_Int16   nItemBits( 0 );
902             Reference< XIndexAccess > xSubMenu;
903 
904             ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits );
905             if ( xSubMenu.is() )
906 		    {
907                 if ( aCommandURL.equalsAscii( ADDDIRECT_CMD ) ||
908                     aCommandURL.equalsAscii( AUTOPILOTMENU_CMD ))
909                 {
910                     WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
911                     bSeparator = sal_False;
912                 }
913 			    else if (( aCommandURL.getLength() > 0 ) && !AddonPopupMenu::IsCommandURLPrefix ( aCommandURL ))
914 			    {
915 				    ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList;
916 				    Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY );
917 
918                     pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
919                                             m_aAttributeType,
920                                             aCommandURL );
921 
922 				    if ( !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
923                         pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
924 						    					 m_aAttributeType,
925 							    				 aLabel );
926 
927 				    m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
928 				    m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )), xListMenu );
929 				    m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
930 				    m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )), m_xEmptyList );
931 				    m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
932 
933 				    WriteMenu( xSubMenu );
934 
935 				    m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
936 				    m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )) );
937 				    m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
938 				    m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )) );
939 				    m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
940 				    bSeparator = sal_False;
941 			    }
942 		    }
943 		    else
944 		    {
945                 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
946                 {
947                     if ( aCommandURL.getLength() > 0 )
948                     {
949                         bSeparator = sal_False;
950                         WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
951                     }
952 			    }
953 			    else if ( !bSeparator )
954 			    {
955                     // Don't write two separators together
956 				    WriteMenuSeparator();
957 				    bSeparator = sal_True;
958 			    }
959 		    }
960         }
961 	}
962 }
963 
964 
965 void OWriteMenuDocumentHandler::WriteMenuItem( const ::rtl::OUString& aCommandURL, const ::rtl::OUString& aLabel, const ::rtl::OUString& aHelpURL, sal_Int16 nStyle )
966 {
967 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
968 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
969 
970     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
971                                 m_aAttributeType,
972                                 aCommandURL );
973 
974 	if ( aHelpURL.getLength() > 0 )
975 	{
976 		pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID )),
977 							 m_aAttributeType,
978 							 aHelpURL );
979 	}
980 
981     if (( aLabel.getLength() > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
982     {
983         pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
984 							    m_aAttributeType,
985 							    aLabel );
986     }
987     if (( nStyle > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
988     {
989         rtl::OUString aValue;
990         MenuStyleItem* pStyle = MenuItemStyles;
991 
992         for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle )
993         {
994             if ( nStyle & pStyle->nBit )
995             {
996                 if ( aValue.getLength() )
997                     aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("+") ) );
998                 aValue += rtl::OUString::createFromAscii( pStyle->attrName );
999             }
1000         }
1001         pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_STYLE )),
1002                                 m_aAttributeType,
1003                                 aValue );
1004     }
1005 
1006 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
1007 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )), xList );
1008 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
1009 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )) );
1010 }
1011 
1012 
1013 void OWriteMenuDocumentHandler::WriteMenuSeparator()
1014 {
1015 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
1016 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )), m_xEmptyList );
1017 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
1018 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )) );
1019 }
1020 
1021 } // namespace framework
1022 
1023