xref: /trunk/main/framework/source/fwe/xml/menudocumenthandler.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #include <stdio.h>
28 
29 //_________________________________________________________________________________________________________________
30 //  my own includes
31 //_________________________________________________________________________________________________________________
32 #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 {
201 }
202 
processingInstruction(const::rtl::OUString &,const::rtl::OUString &)203 void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction(
204     const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
205 {
206 }
207 
setDocumentLocator(const Reference<XLocator> & xLocator)208 void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
209     const Reference< XLocator > &xLocator)
210 {
211     m_xLocator = xLocator;
212 }
213 
getErrorLineString()214 ::rtl::OUString ReadMenuDocumentHandlerBase::getErrorLineString()
215 {
216     char buffer[32];
217 
218     if ( m_xLocator.is() )
219     {
220         snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
221         return ::rtl::OUString::createFromAscii( buffer );
222     }
223     else
224         return ::rtl::OUString();
225 }
226 
initPropertyCommon(Sequence<PropertyValue> & rProps,const rtl::OUString & rCommandURL,const rtl::OUString & rHelpId,const rtl::OUString & rLabel,sal_Int16 nItemStyleBits)227 void ReadMenuDocumentHandlerBase::initPropertyCommon(
228     Sequence< PropertyValue > &rProps, const rtl::OUString &rCommandURL,
229     const rtl::OUString &rHelpId, const rtl::OUString &rLabel, sal_Int16 nItemStyleBits )
230 {
231     rProps[0].Name = m_aCommandURL;
232     rProps[1].Name = m_aHelpURL;
233     rProps[2].Name = m_aContainer;
234     rProps[3].Name = m_aLabel;
235     rProps[4].Name = m_aStyle;
236     rProps[5].Name = m_aType;
237 
238     // Common values
239     rProps[0].Value <<= rCommandURL.intern();
240     rProps[1].Value <<= rHelpId;
241     rProps[2].Value <<= Reference< XIndexContainer >();
242     rProps[3].Value <<= rLabel;
243     rProps[4].Value <<= nItemStyleBits;
244     rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
245 }
246 
247 // -----------------------------------------------------------------------------
248 
OReadMenuDocumentHandler(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & xServiceFactory,const Reference<XIndexContainer> & rMenuBarContainer)249 OReadMenuDocumentHandler::OReadMenuDocumentHandler(
250     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
251     const Reference< XIndexContainer >& rMenuBarContainer )
252 :   m_nElementDepth( 0 ),
253     m_bMenuBarMode( sal_False ),
254     m_xMenuBarContainer( rMenuBarContainer ),
255     m_xContainerFactory( rMenuBarContainer, UNO_QUERY ),
256     mxServiceFactory(xServiceFactory)
257 {
258 }
259 
260 // #110897#
getServiceFactory()261 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuDocumentHandler::getServiceFactory()
262 {
263     // #110897#
264     return mxServiceFactory;
265 }
266 
~OReadMenuDocumentHandler()267 OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
268 {
269 }
270 
271 
startDocument(void)272 void SAL_CALL OReadMenuDocumentHandler::startDocument(void)
273 {
274 }
275 
276 
endDocument(void)277 void SAL_CALL OReadMenuDocumentHandler::endDocument(void)
278 {
279     if ( m_nElementDepth > 0 )
280     {
281         ::rtl::OUString aErrorMessage = getErrorLineString();
282         aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" ));
283         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
284     }
285 }
286 
287 
startElement(const::rtl::OUString & aName,const Reference<XAttributeList> & xAttrList)288 void SAL_CALL OReadMenuDocumentHandler::startElement(
289     const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
290 {
291     if ( m_bMenuBarMode )
292     {
293         ++m_nElementDepth;
294         m_xReader->startElement( aName, xAttrList );
295     }
296     else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
297     {
298         ++m_nElementDepth;
299         m_bMenuBarMode = sal_True;
300 
301         // #110897# m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory ));
302         m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( getServiceFactory(), m_xMenuBarContainer, m_xContainerFactory ));
303 
304         m_xReader->startDocument();
305     }
306 }
307 
308 
characters(const rtl::OUString &)309 void SAL_CALL OReadMenuDocumentHandler::characters(const rtl::OUString&)
310 {
311 }
312 
313 
endElement(const::rtl::OUString & aName)314 void SAL_CALL OReadMenuDocumentHandler::endElement( const ::rtl::OUString& aName )
315 {
316     if ( m_bMenuBarMode )
317     {
318         --m_nElementDepth;
319         m_xReader->endElement( aName );
320         if ( 0 == m_nElementDepth )
321         {
322             m_xReader->endDocument();
323             m_xReader = Reference< XDocumentHandler >();
324             m_bMenuBarMode = sal_False;
325             if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
326             {
327                 ::rtl::OUString aErrorMessage = getErrorLineString();
328                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menubar expected!" ));
329                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
330             }
331         }
332     }
333 }
334 
335 
336 // -----------------------------------------------------------------------------
337 
338 
339 // #110897#
OReadMenuBarHandler(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & xServiceFactory,const Reference<XIndexContainer> & rMenuBarContainer,const Reference<XSingleComponentFactory> & rFactory)340 OReadMenuBarHandler::OReadMenuBarHandler(
341     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
342     const Reference< XIndexContainer >& rMenuBarContainer,
343     const Reference< XSingleComponentFactory >& rFactory )
344 :   m_nElementDepth( 0 ),
345     m_bMenuMode( sal_False ),
346     m_xMenuBarContainer( rMenuBarContainer ),
347     m_xContainerFactory( rFactory ),
348     mxServiceFactory( xServiceFactory )
349 {
350 }
351 
352 // #110897#
getServiceFactory()353 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuBarHandler::getServiceFactory()
354 {
355     // #110897#
356     return mxServiceFactory;
357 }
358 
~OReadMenuBarHandler()359 OReadMenuBarHandler::~OReadMenuBarHandler()
360 {
361 }
362 
363 
startDocument(void)364 void SAL_CALL OReadMenuBarHandler::startDocument(void)
365 {
366 }
367 
368 
endDocument(void)369 void SAL_CALL OReadMenuBarHandler::endDocument(void)
370 {
371 }
372 
373 
startElement(const::rtl::OUString & rName,const Reference<XAttributeList> & xAttrList)374 void SAL_CALL OReadMenuBarHandler::startElement(
375     const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
376 {
377     if ( m_bMenuMode )
378     {
379         ++m_nElementDepth;
380         m_xReader->startElement( rName, xAttrList );
381     }
382     else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
383     {
384         ++m_nElementDepth;
385 
386         ::rtl::OUString aHelpId;
387         ::rtl::OUString aCommandId;
388         ::rtl::OUString aLabel;
389         sal_Int16 nItemBits(0);
390 
391         m_bMenuMode = sal_True;
392 
393         // Container must be factory to create sub container
394         Reference< XComponentContext > xComponentContext;
395         Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
396         xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
397             xComponentContext;
398 
399         Reference< XIndexContainer > xSubItemContainer;
400         if ( m_xContainerFactory.is() )
401             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
402 
403         if ( xSubItemContainer.is() )
404         {
405             // read attributes for menu
406             for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
407             {
408                 ::rtl::OUString aName = xAttrList->getNameByIndex( i );
409                 ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
410                 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
411                     aCommandId = aValue;
412                 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
413                     aLabel = aValue;
414                 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
415                     aHelpId = aValue;
416                 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
417                 {
418                     ::rtl::OUString aTemp( aValue );
419                     sal_Int32 nIndex = 0;
420                     do
421                     {
422                         ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
423                         if ( aToken.getLength() > 0 )
424                         {
425                             if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
426                                 nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
427                             else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
428                                 nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
429                             else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
430                                 nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
431                         }
432                     }
433                     while ( nIndex >= 0 );
434                 }
435             }
436 
437             if ( aCommandId.getLength() > 0 )
438             {
439                 Sequence< PropertyValue > aSubMenuProp( 6 );
440                 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
441                 aSubMenuProp[2].Value <<= xSubItemContainer;
442 
443                 m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) );
444             }
445             else
446             {
447                 ::rtl::OUString aErrorMessage = getErrorLineString();
448                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
449                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
450             }
451 
452             m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
453             m_xReader->startDocument();
454         }
455     }
456     else
457     {
458         ::rtl::OUString aErrorMessage = getErrorLineString();
459         aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "element menu expected!" ));
460         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
461     }
462 }
463 
464 
characters(const rtl::OUString &)465 void SAL_CALL OReadMenuBarHandler::characters(const rtl::OUString&)
466 {
467 }
468 
469 
endElement(const::rtl::OUString & aName)470 void OReadMenuBarHandler::endElement( const ::rtl::OUString& aName )
471 {
472     if ( m_bMenuMode )
473     {
474         --m_nElementDepth;
475         if ( 0 == m_nElementDepth )
476         {
477             m_xReader->endDocument();
478             m_xReader = Reference< XDocumentHandler >();
479             m_bMenuMode = sal_False;
480             if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
481             {
482                 ::rtl::OUString aErrorMessage = getErrorLineString();
483                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
484                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
485             }
486         }
487         else
488             m_xReader->endElement( aName );
489     }
490 }
491 
492 
493 // -----------------------------------------------------------------------------
494 
495 
OReadMenuHandler(const Reference<XIndexContainer> & rMenuContainer,const Reference<XSingleComponentFactory> & rFactory)496 OReadMenuHandler::OReadMenuHandler(
497     const Reference< XIndexContainer >& rMenuContainer,
498     const Reference< XSingleComponentFactory >& rFactory ) :
499     m_nElementDepth( 0 ),
500     m_bMenuPopupMode( sal_False ),
501     m_xMenuContainer( rMenuContainer ),
502     m_xContainerFactory( rFactory )
503 {
504 }
505 
506 
~OReadMenuHandler()507 OReadMenuHandler::~OReadMenuHandler()
508 {
509 }
510 
511 
startDocument(void)512 void SAL_CALL OReadMenuHandler::startDocument(void)
513 {
514 }
515 
516 
endDocument(void)517 void SAL_CALL OReadMenuHandler::endDocument(void)
518 {
519 }
520 
521 
startElement(const::rtl::OUString & aName,const Reference<XAttributeList> & xAttrList)522 void SAL_CALL OReadMenuHandler::startElement(
523     const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
524 {
525     if ( m_bMenuPopupMode )
526     {
527         ++m_nElementDepth;
528         m_xReader->startElement( aName, xAttrList );
529     }
530     else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
531     {
532         ++m_nElementDepth;
533         m_bMenuPopupMode = sal_True;
534         m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
535         m_xReader->startDocument();
536     }
537     else
538     {
539         ::rtl::OUString aErrorMessage = getErrorLineString();
540         aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
541         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
542     }
543 }
544 
545 
characters(const rtl::OUString &)546 void SAL_CALL OReadMenuHandler::characters(const rtl::OUString&)
547 {
548 }
549 
550 
endElement(const::rtl::OUString & aName)551 void SAL_CALL OReadMenuHandler::endElement( const ::rtl::OUString& aName )
552 {
553     if ( m_bMenuPopupMode )
554     {
555         --m_nElementDepth;
556         if ( 0 == m_nElementDepth )
557         {
558             m_xReader->endDocument();
559             m_xReader = Reference< XDocumentHandler >();
560             m_bMenuPopupMode = sal_False;
561             if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
562             {
563                 ::rtl::OUString aErrorMessage = getErrorLineString();
564                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menupopup expected!" ));
565                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
566             }
567         }
568         else
569             m_xReader->endElement( aName );
570     }
571 }
572 
573 
574 // -----------------------------------------------------------------------------
575 
576 
OReadMenuPopupHandler(const Reference<XIndexContainer> & rMenuContainer,const Reference<XSingleComponentFactory> & rFactory)577 OReadMenuPopupHandler::OReadMenuPopupHandler(
578     const Reference< XIndexContainer >& rMenuContainer,
579     const Reference< XSingleComponentFactory >& rFactory ) :
580     m_nElementDepth( 0 ),
581     m_bMenuMode( sal_False ),
582     m_xMenuContainer( rMenuContainer ),
583     m_xContainerFactory( rFactory ),
584     m_nNextElementExpected( ELEM_CLOSE_NONE )
585 {
586 }
587 
588 
~OReadMenuPopupHandler()589 OReadMenuPopupHandler::~OReadMenuPopupHandler()
590 {
591 }
592 
593 
startDocument(void)594 void SAL_CALL OReadMenuPopupHandler::startDocument(void)
595 {
596 }
597 
598 
endDocument(void)599 void SAL_CALL OReadMenuPopupHandler::endDocument(void)
600 {
601 }
602 
startElement(const::rtl::OUString & rName,const Reference<XAttributeList> & xAttrList)603 void SAL_CALL OReadMenuPopupHandler::startElement(
604     const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
605 {
606     ++m_nElementDepth;
607 
608     if ( m_bMenuMode )
609         m_xReader->startElement( rName, xAttrList );
610     else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
611     {
612         ::rtl::OUString aHelpId;
613         ::rtl::OUString aCommandId;
614         ::rtl::OUString aLabel;
615         sal_Int16 nItemBits(0);
616 
617         m_bMenuMode = sal_True;
618 
619         // Container must be factory to create sub container
620         if ( !m_xComponentContext.is() )
621         {
622             const Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
623             m_xComponentContext.set(xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
624         }
625 
626         Reference< XIndexContainer > xSubItemContainer;
627         if ( m_xContainerFactory.is() )
628             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
629 
630         // read attributes for menu
631         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
632         {
633             ::rtl::OUString aName = xAttrList->getNameByIndex( i );
634             ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
635             if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
636                 aCommandId = aValue;
637             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
638                 aLabel = aValue;
639             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
640                 aHelpId = aValue;
641             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
642             {
643                 ::rtl::OUString aTemp( aValue );
644                 sal_Int32 nIndex = 0;
645                 do
646                 {
647                     ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
648                     if ( aToken.getLength() > 0 )
649                     {
650                         if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
651                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
652                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
653                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
654                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
655                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
656                     }
657                 }
658                 while ( nIndex >= 0 );
659             }
660 
661         }
662 
663         if ( aCommandId.getLength() > 0 )
664         {
665             Sequence< PropertyValue > aSubMenuProp( 6 );
666             initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
667             aSubMenuProp[2].Value <<= xSubItemContainer;
668 
669             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) );
670         }
671         else
672         {
673             ::rtl::OUString aErrorMessage = getErrorLineString();
674             aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
675             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
676         }
677 
678         m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
679         m_xReader->startDocument();
680     }
681     else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
682     {
683         ::rtl::OUString aHelpId;
684         ::rtl::OUString aCommandId;
685         ::rtl::OUString aLabel;
686         sal_Int16 nItemBits(0);
687         // read attributes for menu item
688         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
689         {
690             ::rtl::OUString aName = xAttrList->getNameByIndex( i );
691             ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
692             if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
693                 aCommandId = aValue;
694             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
695                 aLabel = aValue;
696             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
697                 aHelpId = aValue;
698             else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
699             {
700                 ::rtl::OUString aTemp( aValue );
701                 sal_Int32 nIndex = 0;
702                 do
703                 {
704                     ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
705                     if ( aToken.getLength() > 0 )
706                     {
707                         if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
708                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
709                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
710                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
711                         else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
712                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
713                     }
714                 }
715                 while ( nIndex >= 0 );
716             }
717 
718         }
719 
720         if ( aCommandId.getLength() > 0 )
721         {
722             Sequence< PropertyValue > aMenuItem( 6 );
723             initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
724             aMenuItem[2].Value <<= Reference< XIndexContainer >();
725 
726             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
727         }
728 
729         m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
730     }
731     else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
732     {
733         Sequence< PropertyValue > aMenuSeparator( 1 );
734         aMenuSeparator[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ));
735         aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
736 
737         m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
738 
739         m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR;
740     }
741     else
742     {
743         ::rtl::OUString aErrorMessage = getErrorLineString();
744         aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
745         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
746     }
747 }
748 
749 
characters(const rtl::OUString &)750 void SAL_CALL OReadMenuPopupHandler::characters(const rtl::OUString&)
751 {
752 }
753 
754 
endElement(const::rtl::OUString & aName)755 void SAL_CALL OReadMenuPopupHandler::endElement( const ::rtl::OUString& aName )
756 {
757     --m_nElementDepth;
758     if ( m_bMenuMode )
759     {
760         if ( 0 == m_nElementDepth )
761         {
762             m_xReader->endDocument();
763             m_xReader = Reference< XDocumentHandler >();
764             m_bMenuMode = sal_False;
765             if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
766             {
767                 ::rtl::OUString aErrorMessage = getErrorLineString();
768                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
769                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
770             }
771         }
772         else
773             m_xReader->endElement( aName );
774     }
775     else
776     {
777         if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
778         {
779             if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
780             {
781                 ::rtl::OUString aErrorMessage = getErrorLineString();
782                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuitem expected!" ));
783                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
784             }
785         }
786         else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
787         {
788             if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
789             {
790                 ::rtl::OUString aErrorMessage = getErrorLineString();
791                 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuseparator expected!" ));
792                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
793             }
794         }
795 
796         m_nNextElementExpected = ELEM_CLOSE_NONE;
797     }
798 }
799 
800 
801 // --------------------------------- Write XML ---------------------------------
802 
803 
OWriteMenuDocumentHandler(const Reference<XIndexAccess> & rMenuBarContainer,const Reference<XDocumentHandler> & rDocumentHandler)804 OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
805     const Reference< XIndexAccess >& rMenuBarContainer,
806     const Reference< XDocumentHandler >& rDocumentHandler ) :
807     m_xMenuBarContainer( rMenuBarContainer ),
808     m_xWriteDocumentHandler( rDocumentHandler )
809 {
810     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
811     m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
812     m_aAttributeType =  ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
813 }
814 
815 
~OWriteMenuDocumentHandler()816 OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
817 {
818 }
819 
820 
WriteMenuDocument()821 void OWriteMenuDocumentHandler::WriteMenuDocument()
822 {
823     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
824     Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
825 
826     m_xWriteDocumentHandler->startDocument();
827 
828     // write DOCTYPE line!
829     Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
830     if ( xExtendedDocHandler.is() )
831     {
832         xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MENUBAR_DOCTYPE )) );
833         m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
834     }
835 
836     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_MENU )),
837                          m_aAttributeType,
838                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU )) );
839 
840     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
841                          m_aAttributeType,
842                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "menubar" )) );
843 
844     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )), pList );
845     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
846 
847     WriteMenu( m_xMenuBarContainer );
848 
849     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
850     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )) );
851     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
852     m_xWriteDocumentHandler->endDocument();
853 }
854 
855 
WriteMenu(const Reference<XIndexAccess> & rMenuContainer)856 void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
857 {
858     sal_Int32   nItemCount = rMenuContainer->getCount();
859     sal_Bool    bSeparator = sal_False;
860     Any         aAny;
861 
862     for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
863     {
864         Sequence< PropertyValue > aProps;
865         aAny = rMenuContainer->getByIndex( nItemPos );
866         if ( aAny >>= aProps )
867         {
868             ::rtl::OUString     aCommandURL;
869             ::rtl::OUString     aLabel;
870             ::rtl::OUString     aHelpURL;
871             sal_Int16   nType( ::com::sun::star::ui::ItemType::DEFAULT );
872             sal_Int16   nItemBits( 0 );
873             Reference< XIndexAccess > xSubMenu;
874 
875             ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits );
876             if ( xSubMenu.is() )
877             {
878                 if ( aCommandURL.equalsAscii( ADDDIRECT_CMD ) ||
879                     aCommandURL.equalsAscii( AUTOPILOTMENU_CMD ))
880                 {
881                     WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
882                     bSeparator = sal_False;
883                 }
884                 else if (( aCommandURL.getLength() > 0 ) && !AddonPopupMenu::IsCommandURLPrefix ( aCommandURL ))
885                 {
886                     ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList;
887                     Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY );
888 
889                     pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
890                                              m_aAttributeType,
891                                              aCommandURL );
892 
893                     if ( !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
894                         pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
895                                                  m_aAttributeType,
896                                                  aLabel );
897 
898                     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
899                     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )), xListMenu );
900                     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
901                     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )), m_xEmptyList );
902                     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
903 
904                     WriteMenu( xSubMenu );
905 
906                     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
907                     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )) );
908                     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
909                     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )) );
910                     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
911                     bSeparator = sal_False;
912                 }
913             }
914             else
915             {
916                 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
917                 {
918                     if ( aCommandURL.getLength() > 0 )
919                     {
920                         bSeparator = sal_False;
921                         WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
922                     }
923                 }
924                 else if ( !bSeparator )
925                 {
926                     // Don't write two separators together
927                     WriteMenuSeparator();
928                     bSeparator = sal_True;
929                 }
930             }
931         }
932     }
933 }
934 
935 
WriteMenuItem(const::rtl::OUString & aCommandURL,const::rtl::OUString & aLabel,const::rtl::OUString & aHelpURL,sal_Int16 nStyle)936 void OWriteMenuDocumentHandler::WriteMenuItem( const ::rtl::OUString& aCommandURL, const ::rtl::OUString& aLabel, const ::rtl::OUString& aHelpURL, sal_Int16 nStyle )
937 {
938     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
939     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
940 
941     pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
942                          m_aAttributeType,
943                          aCommandURL );
944 
945     if ( aHelpURL.getLength() > 0 )
946     {
947         pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID )),
948                              m_aAttributeType,
949                              aHelpURL );
950     }
951 
952     if (( aLabel.getLength() > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
953     {
954         pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
955                              m_aAttributeType,
956                              aLabel );
957     }
958     if (( nStyle > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
959     {
960         rtl::OUString aValue;
961         MenuStyleItem* pStyle = MenuItemStyles;
962 
963         for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle )
964         {
965             if ( nStyle & pStyle->nBit )
966             {
967                 if ( aValue.getLength() )
968                     aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("+") ) );
969                 aValue += rtl::OUString::createFromAscii( pStyle->attrName );
970             }
971         }
972         pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_STYLE )),
973                              m_aAttributeType,
974                              aValue );
975     }
976 
977     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
978     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )), xList );
979     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
980     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )) );
981 }
982 
983 
WriteMenuSeparator()984 void OWriteMenuDocumentHandler::WriteMenuSeparator()
985 {
986     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
987     m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )), m_xEmptyList );
988     m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
989     m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )) );
990 }
991 
992 } // namespace framework
993