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 $
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"
36 //_________________________________________________________________________________________________________________
38 //_________________________________________________________________________________________________________________
39 #include <xml/menudocumenthandler.hxx>
40 #include <xml/menuconfiguration.hxx>
41 #include <classes/addonmenu.hxx>
43 //_________________________________________________________________________________________________________________
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 //_________________________________________________________________________________________________________________
55 //_________________________________________________________________________________________________________________
56 #include <comphelper/processfactory.hxx>
57 #include <rtl/logfile.hxx>
58 #include <comphelper/attributelist.hxx>
60 //_________________________________________________________________________________________________________________
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 //_________________________________________________________________________________________________________________
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
;
124 static void ExtractMenuParameters( const Sequence
< PropertyValue
> rProp
,
125 ::rtl::OUString
& rCommandURL
,
126 ::rtl::OUString
& rLabel
,
127 ::rtl::OUString
& rHelpURL
,
128 Reference
< XIndexAccess
>& rSubMenu
,
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() :
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()
199 if ( m_xLocator
.is() )
201 snprintf( buffer
, sizeof(buffer
), "Line: %ld - ", static_cast<long>( m_xLocator
->getLineNumber() ));
202 return ::rtl::OUString::createFromAscii( buffer
);
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
;
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
)
240 const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& OReadMenuDocumentHandler::getServiceFactory()
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
)
276 m_xReader
->startElement( aName
, xAttrList
);
278 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR
)))
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
)
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 // -----------------------------------------------------------------------------
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
)
337 const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& OReadMenuBarHandler::getServiceFactory()
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
)
367 m_xReader
->startElement( rName
, xAttrList
);
369 else if ( rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU
)))
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" ))) >>=
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
)))
398 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL
)))
400 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID
)))
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
) );
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();
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
)
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() );
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
)
500 m_xReader
->startElement( aName
, xAttrList
);
502 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP
)))
505 m_bMenuPopupMode
= sal_True
;
506 m_xReader
= Reference
< XDocumentHandler
>( new OReadMenuPopupHandler( m_xMenuContainer
, m_xContainerFactory
));
507 m_xReader
->startDocument();
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
)
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() );
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
)
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
)))
613 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL
)))
615 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID
)))
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
) );
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
)))
650 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL
)))
652 else if ( aName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID
)))
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
;
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
)
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() );
711 m_xReader
->endElement( aName
);
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
)),
777 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU
)) );
779 pList
->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID
)),
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
;
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
);
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
)),
832 if ( !( aCommandURL
.copy( CMD_PROTOCOL_SIZE
).equalsAscii( CMD_PROTOCOL
)))
833 pListMenu
->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL
)),
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() );
855 if ( nType
== ::com::sun::star::ui::ItemType::DEFAULT
)
857 if ( aCommandURL
.getLength() > 0 )
860 WriteMenuItem( aCommandURL
, aLabel
, aHelpURL
);
863 else if ( !bSeparator
)
865 // Don't write two separators together
866 WriteMenuSeparator();
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
)),
884 if ( aHelpURL
.getLength() > 0 )
886 pList
->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID
)),
891 if (( aLabel
.getLength() > 0 ) && !( aCommandURL
.copy( CMD_PROTOCOL_SIZE
).equalsAscii( CMD_PROTOCOL
)))
893 pList
->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL
)),
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