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