merge the formfield patch from ooo-build
[ooovba.git] / framework / source / xml / menudocumenthandler.cxx
blob66addd127470ffd214aeab18d1abab45e90cba0b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: menudocumenthandler.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 #include <stdio.h>
36 //_________________________________________________________________________________________________________________
37 // my own includes
38 //_________________________________________________________________________________________________________________
39 #include <xml/menudocumenthandler.hxx>
40 #include <xml/menuconfiguration.hxx>
41 #include <classes/addonmenu.hxx>
43 //_________________________________________________________________________________________________________________
44 // interface includes
45 //_________________________________________________________________________________________________________________
47 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
48 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
49 #include <com/sun/star/ui/ItemType.hpp>
50 #include <com/sun/star/beans/PropertyValue.hpp>
51 #include <com/sun/star/beans/XPropertySet.hpp>
53 //_________________________________________________________________________________________________________________
54 // other includes
55 //_________________________________________________________________________________________________________________
56 #include <comphelper/processfactory.hxx>
57 #include <rtl/logfile.hxx>
58 #include <comphelper/attributelist.hxx>
60 //_________________________________________________________________________________________________________________
61 // defines
62 //_________________________________________________________________________________________________________________
64 #define XMLNS_MENU "http://openoffice.org/2001/menu"
65 #define XMLNS_PREFIX "menu:"
67 #define ELEMENT_MENUBAR "http://openoffice.org/2001/menu^menubar"
68 #define ELEMENT_MENU "http://openoffice.org/2001/menu^menu"
69 #define ELEMENT_MENUPOPUP "http://openoffice.org/2001/menu^menupopup"
70 #define ELEMENT_MENUITEM "http://openoffice.org/2001/menu^menuitem"
71 #define ELEMENT_MENUSEPARATOR "http://openoffice.org/2001/menu^menuseparator"
73 #define ELEMENT_NS_MENUBAR "menu:menubar"
74 #define ELEMENT_NS_MENU "menu:menu"
75 #define ELEMENT_NS_MENUPOPUP "menu:menupopup"
76 #define ELEMENT_NS_MENUITEM "menu:menuitem"
77 #define ELEMENT_NS_MENUSEPARATOR "menu:menuseparator"
79 #define ATTRIBUTE_ID "http://openoffice.org/2001/menu^id"
80 #define ATTRIBUTE_LABEL "http://openoffice.org/2001/menu^label"
81 #define ATTRIBUTE_HELPID "http://openoffice.org/2001/menu^helpid"
82 #define ATTRIBUTE_LINEBREAK "http://openoffice.org/2001/menu^linebreak"
84 #define ATTRIBUTE_NS_ID "menu:id"
85 #define ATTRIBUTE_NS_LABEL "menu:label"
86 #define ATTRIBUTE_NS_HELPID "menu:helpid"
87 #define ATTRIBUTE_NS_LINEBREAK "menu:linebreak"
89 #define ATTRIBUTE_XMLNS_MENU "xmlns:menu"
91 #define ATTRIBUTE_TYPE_CDATA "CDATA"
93 #define MENUBAR_DOCTYPE "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">"
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";
102 // special popup menus (filled during runtime) must be saved as an empty popup menu or menuitem!!!
103 static const sal_Int32 CMD_PROTOCOL_SIZE = 5;
104 static const char CMD_PROTOCOL[] = ".uno:";
105 static const char ADDDIRECT_CMD[] = ".uno:AddDirect" ;
106 static const char AUTOPILOTMENU_CMD[] = ".uno:AutoPilotMenu" ;
107 static const char FILEMENU_CMD[] = ".uno:Picklist" ;
108 static const char WINDOWMENU_CMD[] = ".uno:WindowList" ;
110 //_________________________________________________________________________________________________________________
111 // using namespaces
112 //_________________________________________________________________________________________________________________
114 using namespace ::com::sun::star::uno;
115 using namespace ::com::sun::star::lang;
116 using namespace ::com::sun::star::beans;
117 using namespace ::com::sun::star::xml::sax;
118 using namespace ::com::sun::star::container;
119 using namespace ::com::sun::star::ui;
121 namespace framework
124 static void ExtractMenuParameters( const Sequence< PropertyValue > rProp,
125 ::rtl::OUString& rCommandURL,
126 ::rtl::OUString& rLabel,
127 ::rtl::OUString& rHelpURL,
128 Reference< XIndexAccess >& rSubMenu,
129 sal_Int16& rType )
131 for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
133 if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
135 rProp[i].Value >>= rCommandURL;
136 rCommandURL = rCommandURL.intern();
138 else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
140 rProp[i].Value >>= rHelpURL;
142 else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_CONTAINER ))
144 rProp[i].Value >>= rSubMenu;
146 else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
148 rProp[i].Value >>= rLabel;
150 else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
152 rProp[i].Value >>= rType;
158 // -----------------------------------------------------------------------------
159 // Base class implementation
161 ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() :
162 m_xLocator( 0 ),
163 m_xReader( 0 ),
164 m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )),
165 m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )),
166 m_aContainer( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER )),
167 m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )),
168 m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ))
172 ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
176 void SAL_CALL ReadMenuDocumentHandlerBase::ignorableWhitespace(
177 const ::rtl::OUString& )
178 throw( SAXException, RuntimeException )
182 void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction(
183 const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
184 throw( SAXException, RuntimeException )
188 void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
189 const Reference< XLocator > &xLocator)
190 throw( SAXException, RuntimeException )
192 m_xLocator = xLocator;
195 ::rtl::OUString ReadMenuDocumentHandlerBase::getErrorLineString()
197 char buffer[32];
199 if ( m_xLocator.is() )
201 snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
202 return ::rtl::OUString::createFromAscii( buffer );
204 else
205 return ::rtl::OUString();
208 void ReadMenuDocumentHandlerBase::initPropertyCommon(
209 Sequence< PropertyValue > &rProps, const rtl::OUString &rCommandURL,
210 const rtl::OUString &rHelpId, const rtl::OUString &rLabel)
212 rProps[0].Name = m_aCommandURL;
213 rProps[1].Name = m_aHelpURL;
214 rProps[2].Name = m_aContainer;
215 rProps[3].Name = m_aLabel;
216 rProps[4].Name = m_aType;
218 // Common values
219 rProps[0].Value <<= rCommandURL.intern();
220 rProps[1].Value <<= rHelpId;
221 rProps[2].Value <<= Reference< XIndexContainer >();
222 rProps[3].Value <<= rLabel;
223 rProps[4].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
226 // -----------------------------------------------------------------------------
228 OReadMenuDocumentHandler::OReadMenuDocumentHandler(
229 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
230 const Reference< XIndexContainer >& rMenuBarContainer )
231 : m_nElementDepth( 0 ),
232 m_bMenuBarMode( sal_False ),
233 m_xMenuBarContainer( rMenuBarContainer ),
234 m_xContainerFactory( rMenuBarContainer, UNO_QUERY ),
235 mxServiceFactory(xServiceFactory)
239 // #110897#
240 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuDocumentHandler::getServiceFactory()
242 // #110897#
243 return mxServiceFactory;
246 OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
251 void SAL_CALL OReadMenuDocumentHandler::startDocument(void)
252 throw ( SAXException, RuntimeException )
257 void SAL_CALL OReadMenuDocumentHandler::endDocument(void)
258 throw( SAXException, RuntimeException )
260 if ( m_nElementDepth > 0 )
262 ::rtl::OUString aErrorMessage = getErrorLineString();
263 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" ));
264 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
269 void SAL_CALL OReadMenuDocumentHandler::startElement(
270 const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
271 throw( SAXException, RuntimeException )
273 if ( m_bMenuBarMode )
275 ++m_nElementDepth;
276 m_xReader->startElement( aName, xAttrList );
278 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
280 ++m_nElementDepth;
281 m_bMenuBarMode = sal_True;
283 // #110897# m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory ));
284 m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( getServiceFactory(), m_xMenuBarContainer, m_xContainerFactory ));
286 m_xReader->startDocument();
291 void SAL_CALL OReadMenuDocumentHandler::characters(const rtl::OUString&)
292 throw( SAXException, RuntimeException )
297 void SAL_CALL OReadMenuDocumentHandler::endElement( const ::rtl::OUString& aName )
298 throw( SAXException, RuntimeException )
300 if ( m_bMenuBarMode )
302 --m_nElementDepth;
303 m_xReader->endElement( aName );
304 if ( 0 == m_nElementDepth )
306 m_xReader->endDocument();
307 m_xReader = Reference< XDocumentHandler >();
308 m_bMenuBarMode = sal_False;
309 if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
311 ::rtl::OUString aErrorMessage = getErrorLineString();
312 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menubar expected!" ));
313 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
320 // -----------------------------------------------------------------------------
323 // #110897#
324 OReadMenuBarHandler::OReadMenuBarHandler(
325 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
326 const Reference< XIndexContainer >& rMenuBarContainer,
327 const Reference< XSingleComponentFactory >& rFactory )
328 : m_nElementDepth( 0 ),
329 m_bMenuMode( sal_False ),
330 m_xMenuBarContainer( rMenuBarContainer ),
331 m_xContainerFactory( rFactory ),
332 mxServiceFactory( xServiceFactory )
336 // #110897#
337 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuBarHandler::getServiceFactory()
339 // #110897#
340 return mxServiceFactory;
343 OReadMenuBarHandler::~OReadMenuBarHandler()
348 void SAL_CALL OReadMenuBarHandler::startDocument(void)
349 throw ( SAXException, RuntimeException )
354 void SAL_CALL OReadMenuBarHandler::endDocument(void)
355 throw( SAXException, RuntimeException )
360 void SAL_CALL OReadMenuBarHandler::startElement(
361 const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
362 throw( SAXException, RuntimeException )
364 if ( m_bMenuMode )
366 ++m_nElementDepth;
367 m_xReader->startElement( rName, xAttrList );
369 else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
371 ++m_nElementDepth;
373 ::rtl::OUString aHelpId;
374 ::rtl::OUString aCommandId;
375 ::rtl::OUString aLabel;
377 m_bMenuMode = sal_True;
379 // Container must be factory to create sub container
380 Reference< XComponentContext > xComponentContext;
381 Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
382 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
383 xComponentContext;
385 Reference< XIndexContainer > xSubItemContainer;
386 if ( m_xContainerFactory.is() )
387 xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
389 if ( xSubItemContainer.is() )
391 // read attributes for menu
392 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
394 ::rtl::OUString aName = xAttrList->getNameByIndex( i );
395 ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
396 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
397 aCommandId = aValue;
398 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
399 aLabel = aValue;
400 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
401 aHelpId = aValue;
404 if ( aCommandId.getLength() > 0 )
406 Sequence< PropertyValue > aSubMenuProp( 5 );
407 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel );
408 aSubMenuProp[2].Value <<= xSubItemContainer;
410 m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) );
412 else
414 ::rtl::OUString aErrorMessage = getErrorLineString();
415 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
416 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
419 m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
420 m_xReader->startDocument();
423 else
425 ::rtl::OUString aErrorMessage = getErrorLineString();
426 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "element menu expected!" ));
427 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
432 void SAL_CALL OReadMenuBarHandler::characters(const rtl::OUString&)
433 throw( SAXException, RuntimeException )
438 void OReadMenuBarHandler::endElement( const ::rtl::OUString& aName )
439 throw( SAXException, RuntimeException )
441 if ( m_bMenuMode )
443 --m_nElementDepth;
444 if ( 0 == m_nElementDepth )
446 m_xReader->endDocument();
447 m_xReader = Reference< XDocumentHandler >();
448 m_bMenuMode = sal_False;
449 if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
451 ::rtl::OUString aErrorMessage = getErrorLineString();
452 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
453 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
456 else
457 m_xReader->endElement( aName );
462 // -----------------------------------------------------------------------------
465 OReadMenuHandler::OReadMenuHandler(
466 const Reference< XIndexContainer >& rMenuContainer,
467 const Reference< XSingleComponentFactory >& rFactory ) :
468 m_nElementDepth( 0 ),
469 m_bMenuPopupMode( sal_False ),
470 m_xMenuContainer( rMenuContainer ),
471 m_xContainerFactory( rFactory )
476 OReadMenuHandler::~OReadMenuHandler()
481 void SAL_CALL OReadMenuHandler::startDocument(void)
482 throw ( SAXException, RuntimeException )
487 void SAL_CALL OReadMenuHandler::endDocument(void)
488 throw( SAXException, RuntimeException)
493 void SAL_CALL OReadMenuHandler::startElement(
494 const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
495 throw( SAXException, RuntimeException )
497 if ( m_bMenuPopupMode )
499 ++m_nElementDepth;
500 m_xReader->startElement( aName, xAttrList );
502 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
504 ++m_nElementDepth;
505 m_bMenuPopupMode = sal_True;
506 m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
507 m_xReader->startDocument();
509 else
511 ::rtl::OUString aErrorMessage = getErrorLineString();
512 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
513 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
518 void SAL_CALL OReadMenuHandler::characters(const rtl::OUString&)
519 throw( SAXException, RuntimeException )
524 void SAL_CALL OReadMenuHandler::endElement( const ::rtl::OUString& aName )
525 throw( SAXException, RuntimeException )
527 if ( m_bMenuPopupMode )
529 --m_nElementDepth;
530 if ( 0 == m_nElementDepth )
532 m_xReader->endDocument();
533 m_xReader = Reference< XDocumentHandler >();
534 m_bMenuPopupMode = sal_False;
535 if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
537 ::rtl::OUString aErrorMessage = getErrorLineString();
538 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menupopup expected!" ));
539 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
542 else
543 m_xReader->endElement( aName );
548 // -----------------------------------------------------------------------------
551 OReadMenuPopupHandler::OReadMenuPopupHandler(
552 const Reference< XIndexContainer >& rMenuContainer,
553 const Reference< XSingleComponentFactory >& rFactory ) :
554 m_nElementDepth( 0 ),
555 m_bMenuMode( sal_False ),
556 m_xMenuContainer( rMenuContainer ),
557 m_xContainerFactory( rFactory ),
558 m_nNextElementExpected( ELEM_CLOSE_NONE )
563 OReadMenuPopupHandler::~OReadMenuPopupHandler()
568 void SAL_CALL OReadMenuPopupHandler::startDocument(void)
569 throw ( SAXException, RuntimeException )
574 void SAL_CALL OReadMenuPopupHandler::endDocument(void)
575 throw( SAXException, RuntimeException)
579 void SAL_CALL OReadMenuPopupHandler::startElement(
580 const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
581 throw( SAXException, RuntimeException )
583 ++m_nElementDepth;
585 if ( m_bMenuMode )
586 m_xReader->startElement( rName, xAttrList );
587 else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
589 ::rtl::OUString aHelpId;
590 ::rtl::OUString aCommandId;
591 ::rtl::OUString aLabel;
593 m_bMenuMode = sal_True;
595 // Container must be factory to create sub container
596 if ( !m_xComponentContext.is() )
598 const Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
599 m_xComponentContext.set(xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
602 Reference< XIndexContainer > xSubItemContainer;
603 if ( m_xContainerFactory.is() )
604 xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
606 // read attributes for menu
607 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
609 ::rtl::OUString aName = xAttrList->getNameByIndex( i );
610 ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
611 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
612 aCommandId = aValue;
613 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
614 aLabel = aValue;
615 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
616 aHelpId = aValue;
619 if ( aCommandId.getLength() > 0 )
621 Sequence< PropertyValue > aSubMenuProp( 5 );
622 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel );
623 aSubMenuProp[2].Value <<= xSubItemContainer;
625 m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) );
627 else
629 ::rtl::OUString aErrorMessage = getErrorLineString();
630 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
631 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
634 m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
635 m_xReader->startDocument();
637 else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
639 ::rtl::OUString aHelpId;
640 ::rtl::OUString aCommandId;
641 ::rtl::OUString aLabel;
643 // read attributes for menu item
644 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
646 ::rtl::OUString aName = xAttrList->getNameByIndex( i );
647 ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
648 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
649 aCommandId = aValue;
650 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
651 aLabel = aValue;
652 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
653 aHelpId = aValue;
656 if ( aCommandId.getLength() > 0 )
658 Sequence< PropertyValue > aMenuItem( 5 );
659 initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel );
660 aMenuItem[2].Value <<= Reference< XIndexContainer >();
662 m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
665 m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
667 else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
669 Sequence< PropertyValue > aMenuSeparator( 1 );
670 aMenuSeparator[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ));
671 aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
673 m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
675 m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR;
677 else
679 ::rtl::OUString aErrorMessage = getErrorLineString();
680 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
681 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
686 void SAL_CALL OReadMenuPopupHandler::characters(const rtl::OUString&)
687 throw( SAXException, RuntimeException )
692 void SAL_CALL OReadMenuPopupHandler::endElement( const ::rtl::OUString& aName )
693 throw( SAXException, RuntimeException )
695 --m_nElementDepth;
696 if ( m_bMenuMode )
698 if ( 0 == m_nElementDepth )
700 m_xReader->endDocument();
701 m_xReader = Reference< XDocumentHandler >();
702 m_bMenuMode = sal_False;
703 if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
705 ::rtl::OUString aErrorMessage = getErrorLineString();
706 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
707 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
710 else
711 m_xReader->endElement( aName );
713 else
715 if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
717 if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
719 ::rtl::OUString aErrorMessage = getErrorLineString();
720 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuitem expected!" ));
721 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
724 else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
726 if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
728 ::rtl::OUString aErrorMessage = getErrorLineString();
729 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuseparator expected!" ));
730 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
734 m_nNextElementExpected = ELEM_CLOSE_NONE;
739 // --------------------------------- Write XML ---------------------------------
742 OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
743 const Reference< XIndexAccess >& rMenuBarContainer,
744 const Reference< XDocumentHandler >& rDocumentHandler ) :
745 m_xMenuBarContainer( rMenuBarContainer ),
746 m_xWriteDocumentHandler( rDocumentHandler )
748 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
749 m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
750 m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
754 OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
759 void OWriteMenuDocumentHandler::WriteMenuDocument()
760 throw ( SAXException, RuntimeException )
762 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
763 Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
765 m_xWriteDocumentHandler->startDocument();
767 // write DOCTYPE line!
768 Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
769 if ( xExtendedDocHandler.is() )
771 xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MENUBAR_DOCTYPE )) );
772 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
775 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_MENU )),
776 m_aAttributeType,
777 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU )) );
779 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
780 m_aAttributeType,
781 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "menubar" )) );
783 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )), pList );
784 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
786 WriteMenu( m_xMenuBarContainer );
788 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
789 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )) );
790 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
791 m_xWriteDocumentHandler->endDocument();
795 void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
796 throw ( SAXException, RuntimeException )
798 sal_Int32 nItemCount = rMenuContainer->getCount();
799 sal_Bool bSeparator = sal_False;
800 Any aAny;
802 for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
804 Sequence< PropertyValue > aProps;
805 aAny = rMenuContainer->getByIndex( nItemPos );
806 if ( aAny >>= aProps )
808 ::rtl::OUString aCommandURL;
809 ::rtl::OUString aLabel;
810 ::rtl::OUString aHelpURL;
811 sal_Int16 nType( ::com::sun::star::ui::ItemType::DEFAULT );
812 Reference< XIndexAccess > xSubMenu;
814 ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType );
815 if ( xSubMenu.is() )
817 if ( aCommandURL.equalsAscii( ADDDIRECT_CMD ) ||
818 aCommandURL.equalsAscii( AUTOPILOTMENU_CMD ))
820 WriteMenuItem( aCommandURL, aLabel, aHelpURL );
821 bSeparator = sal_False;
823 else if (( aCommandURL.getLength() > 0 ) && !AddonPopupMenu::IsCommandURLPrefix ( aCommandURL ))
825 ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList;
826 Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY );
828 pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
829 m_aAttributeType,
830 aCommandURL );
832 if ( !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
833 pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
834 m_aAttributeType,
835 aLabel );
837 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
838 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )), xListMenu );
839 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
840 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )), m_xEmptyList );
841 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
843 WriteMenu( xSubMenu );
845 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
846 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )) );
847 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
848 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )) );
849 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
850 bSeparator = FALSE;
853 else
855 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
857 if ( aCommandURL.getLength() > 0 )
859 bSeparator = FALSE;
860 WriteMenuItem( aCommandURL, aLabel, aHelpURL );
863 else if ( !bSeparator )
865 // Don't write two separators together
866 WriteMenuSeparator();
867 bSeparator = TRUE;
875 void OWriteMenuDocumentHandler::WriteMenuItem( const ::rtl::OUString& aCommandURL, const ::rtl::OUString& aLabel, const ::rtl::OUString& aHelpURL)
877 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
878 Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
880 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
881 m_aAttributeType,
882 aCommandURL );
884 if ( aHelpURL.getLength() > 0 )
886 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID )),
887 m_aAttributeType,
888 aHelpURL );
891 if (( aLabel.getLength() > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL )))
893 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
894 m_aAttributeType,
895 aLabel );
898 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
899 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )), xList );
900 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
901 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )) );
905 void OWriteMenuDocumentHandler::WriteMenuSeparator()
907 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
908 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )), m_xEmptyList );
909 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
910 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )) );
913 } // namespace framework