1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/macros.h>
23 #include <xml/menudocumenthandler.hxx>
24 #include <framework/menuconfiguration.hxx>
25 #include <framework/addonmenu.hxx>
27 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
28 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
29 #include <com/sun/star/ui/ItemType.hpp>
30 #include <com/sun/star/ui/ItemStyle.hpp>
31 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/attributelist.hxx>
36 #define XMLNS_MENU "http://openoffice.org/2001/menu"
38 #define ELEMENT_MENUBAR "http://openoffice.org/2001/menu^menubar"
39 #define ELEMENT_MENU "http://openoffice.org/2001/menu^menu"
40 #define ELEMENT_MENUPOPUP "http://openoffice.org/2001/menu^menupopup"
41 #define ELEMENT_MENUITEM "http://openoffice.org/2001/menu^menuitem"
42 #define ELEMENT_MENUSEPARATOR "http://openoffice.org/2001/menu^menuseparator"
44 #define ELEMENT_NS_MENUBAR "menu:menubar"
45 #define ELEMENT_NS_MENU "menu:menu"
46 #define ELEMENT_NS_MENUPOPUP "menu:menupopup"
47 #define ELEMENT_NS_MENUITEM "menu:menuitem"
48 #define ELEMENT_NS_MENUSEPARATOR "menu:menuseparator"
50 #define ATTRIBUTE_ID "http://openoffice.org/2001/menu^id"
51 #define ATTRIBUTE_LABEL "http://openoffice.org/2001/menu^label"
52 #define ATTRIBUTE_HELPID "http://openoffice.org/2001/menu^helpid"
53 #define ATTRIBUTE_STYLE "http://openoffice.org/2001/menu^style"
55 #define ATTRIBUTE_NS_ID "menu:id"
56 #define ATTRIBUTE_NS_LABEL "menu:label"
57 #define ATTRIBUTE_NS_HELPID "menu:helpid"
58 #define ATTRIBUTE_NS_STYLE "menu:style"
60 #define ATTRIBUTE_XMLNS_MENU "xmlns:menu"
62 #define ATTRIBUTE_TYPE_CDATA "CDATA"
64 #define MENUBAR_DOCTYPE "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">"
66 #define ATTRIBUTE_ITEMSTYLE_TEXT "text"
67 #define ATTRIBUTE_ITEMSTYLE_IMAGE "image"
68 #define ATTRIBUTE_ITEMSTYLE_RADIO "radio"
70 // Property names of a menu/menu item ItemDescriptor
71 static const char ITEM_DESCRIPTOR_COMMANDURL
[] = "CommandURL";
72 static const char ITEM_DESCRIPTOR_HELPURL
[] = "HelpURL";
73 static const char ITEM_DESCRIPTOR_CONTAINER
[] = "ItemDescriptorContainer";
74 static const char ITEM_DESCRIPTOR_LABEL
[] = "Label";
75 static const char ITEM_DESCRIPTOR_TYPE
[] = "Type";
76 static const char ITEM_DESCRIPTOR_STYLE
[] = "Style";
78 // special popup menus (filled during runtime) must be saved as an empty popup menu or menuitem!!!
79 static const sal_Int32 CMD_PROTOCOL_SIZE
= 5;
80 static const char CMD_PROTOCOL
[] = ".uno:";
81 static const char ADDDIRECT_CMD
[] = ".uno:AddDirect";
82 static const char AUTOPILOTMENU_CMD
[] = ".uno:AutoPilotMenu";
86 using namespace ::com::sun::star::uno
;
87 using namespace ::com::sun::star::lang
;
88 using namespace ::com::sun::star::beans
;
89 using namespace ::com::sun::star::xml::sax
;
90 using namespace ::com::sun::star::container
;
91 using namespace ::com::sun::star::ui
;
102 MenuStyleItem MenuItemStyles
[ ] = {
103 { ::com::sun::star::ui::ItemStyle::ICON
, ATTRIBUTE_ITEMSTYLE_IMAGE
},
104 { ::com::sun::star::ui::ItemStyle::TEXT
, ATTRIBUTE_ITEMSTYLE_TEXT
},
105 { ::com::sun::star::ui::ItemStyle::RADIO_CHECK
, ATTRIBUTE_ITEMSTYLE_RADIO
}
108 sal_Int32 nMenuStyleItemEntries
= (sizeof (MenuItemStyles
) / sizeof (MenuItemStyles
[0]));
110 static void ExtractMenuParameters( const Sequence
< PropertyValue
>& rProp
,
111 OUString
& rCommandURL
,
114 Reference
< XIndexAccess
>& rSubMenu
,
118 for ( sal_Int32 i
= 0; i
< rProp
.getLength(); i
++ )
120 if ( rProp
[i
].Name
== ITEM_DESCRIPTOR_COMMANDURL
)
122 rProp
[i
].Value
>>= rCommandURL
;
123 rCommandURL
= rCommandURL
.intern();
125 else if ( rProp
[i
].Name
== ITEM_DESCRIPTOR_HELPURL
)
127 rProp
[i
].Value
>>= rHelpURL
;
129 else if ( rProp
[i
].Name
== ITEM_DESCRIPTOR_CONTAINER
)
131 rProp
[i
].Value
>>= rSubMenu
;
133 else if ( rProp
[i
].Name
== ITEM_DESCRIPTOR_LABEL
)
135 rProp
[i
].Value
>>= rLabel
;
137 else if ( rProp
[i
].Name
== ITEM_DESCRIPTOR_TYPE
)
139 rProp
[i
].Value
>>= rType
;
141 else if ( rProp
[i
].Name
== ITEM_DESCRIPTOR_STYLE
)
143 rProp
[i
].Value
>>= rStyle
;
148 // Base class implementation
150 ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() :
153 m_aType( ITEM_DESCRIPTOR_TYPE
),
154 m_aLabel( ITEM_DESCRIPTOR_LABEL
),
155 m_aContainer( ITEM_DESCRIPTOR_CONTAINER
),
156 m_aHelpURL( ITEM_DESCRIPTOR_HELPURL
),
157 m_aCommandURL( ITEM_DESCRIPTOR_COMMANDURL
),
158 m_aStyle( ITEM_DESCRIPTOR_STYLE
)
162 ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
166 void SAL_CALL
ReadMenuDocumentHandlerBase::ignorableWhitespace(
168 throw( SAXException
, RuntimeException
, std::exception
)
172 void SAL_CALL
ReadMenuDocumentHandlerBase::processingInstruction(
173 const OUString
& /*aTarget*/, const OUString
& /*aData*/ )
174 throw( SAXException
, RuntimeException
, std::exception
)
178 void SAL_CALL
ReadMenuDocumentHandlerBase::setDocumentLocator(
179 const Reference
< XLocator
> &xLocator
)
180 throw( SAXException
, RuntimeException
, std::exception
)
182 m_xLocator
= xLocator
;
185 OUString
ReadMenuDocumentHandlerBase::getErrorLineString()
187 if ( m_xLocator
.is() )
190 snprintf( buffer
, sizeof(buffer
), "Line: %ld - ", static_cast<long>( m_xLocator
->getLineNumber() ));
191 return OUString::createFromAscii( buffer
);
197 void ReadMenuDocumentHandlerBase::initPropertyCommon(
198 Sequence
< PropertyValue
> &rProps
, const OUString
&rCommandURL
,
199 const OUString
&rHelpId
, const OUString
&rLabel
, sal_Int16 nItemStyleBits
)
201 rProps
[0].Name
= m_aCommandURL
;
202 rProps
[1].Name
= m_aHelpURL
;
203 rProps
[2].Name
= m_aContainer
;
204 rProps
[3].Name
= m_aLabel
;
205 rProps
[4].Name
= m_aStyle
;
206 rProps
[5].Name
= m_aType
;
209 rProps
[0].Value
<<= rCommandURL
.intern();
210 rProps
[1].Value
<<= rHelpId
;
211 rProps
[2].Value
<<= Reference
< XIndexContainer
>();
212 rProps
[3].Value
<<= rLabel
;
213 rProps
[4].Value
<<= nItemStyleBits
;
214 rProps
[5].Value
<<= ::com::sun::star::ui::ItemType::DEFAULT
;
217 OReadMenuDocumentHandler::OReadMenuDocumentHandler(
218 const Reference
< XIndexContainer
>& rMenuBarContainer
)
219 : m_nElementDepth( 0 ),
220 m_bMenuBarMode( false ),
221 m_xMenuBarContainer( rMenuBarContainer
),
222 m_xContainerFactory( rMenuBarContainer
, UNO_QUERY
)
226 OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
230 void SAL_CALL
OReadMenuDocumentHandler::startDocument()
231 throw ( SAXException
, RuntimeException
, std::exception
)
235 void SAL_CALL
OReadMenuDocumentHandler::endDocument()
236 throw( SAXException
, RuntimeException
, std::exception
)
238 if ( m_nElementDepth
> 0 )
240 OUString aErrorMessage
= getErrorLineString();
241 aErrorMessage
+= "A closing element is missing!";
242 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
246 void SAL_CALL
OReadMenuDocumentHandler::startElement(
247 const OUString
& aName
, const Reference
< XAttributeList
> &xAttrList
)
248 throw( SAXException
, RuntimeException
, std::exception
)
250 if ( m_bMenuBarMode
)
253 m_xReader
->startElement( aName
, xAttrList
);
255 else if ( aName
== ELEMENT_MENUBAR
)
258 m_bMenuBarMode
= true;
259 m_xReader
= Reference
< XDocumentHandler
>( new OReadMenuBarHandler( m_xMenuBarContainer
, m_xContainerFactory
));
261 m_xReader
->startDocument();
265 void SAL_CALL
OReadMenuDocumentHandler::characters(const OUString
&)
266 throw( SAXException
, RuntimeException
, std::exception
)
270 void SAL_CALL
OReadMenuDocumentHandler::endElement( const OUString
& aName
)
271 throw( SAXException
, RuntimeException
, std::exception
)
273 if ( m_bMenuBarMode
)
276 m_xReader
->endElement( aName
);
277 if ( 0 == m_nElementDepth
)
279 m_xReader
->endDocument();
281 m_bMenuBarMode
= false;
282 if ( aName
!= ELEMENT_MENUBAR
)
284 OUString aErrorMessage
= getErrorLineString();
285 aErrorMessage
+= "closing element menubar expected!";
286 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
292 OReadMenuBarHandler::OReadMenuBarHandler(
293 const Reference
< XIndexContainer
>& rMenuBarContainer
,
294 const Reference
< XSingleComponentFactory
>& rFactory
)
295 : m_nElementDepth( 0 ),
296 m_bMenuMode( false ),
297 m_xMenuBarContainer( rMenuBarContainer
),
298 m_xContainerFactory( rFactory
)
302 OReadMenuBarHandler::~OReadMenuBarHandler()
306 void SAL_CALL
OReadMenuBarHandler::startDocument()
307 throw ( SAXException
, RuntimeException
, std::exception
)
311 void SAL_CALL
OReadMenuBarHandler::endDocument()
312 throw( SAXException
, RuntimeException
, std::exception
)
316 void SAL_CALL
OReadMenuBarHandler::startElement(
317 const OUString
& rName
, const Reference
< XAttributeList
> &xAttrList
)
318 throw( SAXException
, RuntimeException
, std::exception
)
323 m_xReader
->startElement( rName
, xAttrList
);
325 else if ( rName
== ELEMENT_MENU
)
332 sal_Int16
nItemBits(0);
336 // Container must be factory to create sub container
337 Reference
< XComponentContext
> xComponentContext(
338 comphelper::getProcessComponentContext() );
340 Reference
< XIndexContainer
> xSubItemContainer
;
341 if ( m_xContainerFactory
.is() )
342 xSubItemContainer
= Reference
< XIndexContainer
>( m_xContainerFactory
->createInstanceWithContext( xComponentContext
), UNO_QUERY
);
344 if ( xSubItemContainer
.is() )
346 // read attributes for menu
347 for ( sal_Int16 i
=0; i
< xAttrList
->getLength(); i
++ )
349 OUString aName
= xAttrList
->getNameByIndex( i
);
350 OUString aValue
= xAttrList
->getValueByIndex( i
);
351 if ( aName
== ATTRIBUTE_ID
)
353 else if ( aName
== ATTRIBUTE_LABEL
)
355 else if ( aName
== ATTRIBUTE_HELPID
)
357 else if ( aName
== ATTRIBUTE_STYLE
)
359 OUString
aTemp( aValue
);
360 sal_Int32 nIndex
= 0;
363 OUString aToken
= aTemp
.getToken( 0, '+', nIndex
);
364 if ( !aToken
.isEmpty() )
366 if ( aToken
== ATTRIBUTE_ITEMSTYLE_TEXT
)
367 nItemBits
|= ::com::sun::star::ui::ItemStyle::TEXT
;
368 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_IMAGE
)
369 nItemBits
|= ::com::sun::star::ui::ItemStyle::ICON
;
370 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_RADIO
)
371 nItemBits
|= ::com::sun::star::ui::ItemStyle::RADIO_CHECK
;
374 while ( nIndex
>= 0 );
378 if ( !aCommandId
.isEmpty() )
380 Sequence
< PropertyValue
> aSubMenuProp( 6 );
381 initPropertyCommon( aSubMenuProp
, aCommandId
, aHelpId
, aLabel
, nItemBits
);
382 aSubMenuProp
[2].Value
<<= xSubItemContainer
;
384 m_xMenuBarContainer
->insertByIndex( m_xMenuBarContainer
->getCount(), makeAny( aSubMenuProp
) );
388 OUString aErrorMessage
= getErrorLineString();
389 aErrorMessage
+= "attribute id for element menu required!";
390 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
393 m_xReader
= Reference
< XDocumentHandler
>( new OReadMenuHandler( xSubItemContainer
, m_xContainerFactory
));
394 m_xReader
->startDocument();
399 OUString aErrorMessage
= getErrorLineString();
400 aErrorMessage
+= "element menu expected!";
401 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
405 void SAL_CALL
OReadMenuBarHandler::characters(const OUString
&)
406 throw( SAXException
, RuntimeException
, std::exception
)
410 void OReadMenuBarHandler::endElement( const OUString
& aName
)
411 throw( SAXException
, RuntimeException
, std::exception
)
416 if ( 0 == m_nElementDepth
)
418 m_xReader
->endDocument();
421 if ( aName
!= ELEMENT_MENU
)
423 OUString aErrorMessage
= getErrorLineString();
424 aErrorMessage
+= "closing element menu expected!";
425 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
429 m_xReader
->endElement( aName
);
433 OReadMenuHandler::OReadMenuHandler(
434 const Reference
< XIndexContainer
>& rMenuContainer
,
435 const Reference
< XSingleComponentFactory
>& rFactory
) :
436 m_nElementDepth( 0 ),
437 m_bMenuPopupMode( false ),
438 m_xMenuContainer( rMenuContainer
),
439 m_xContainerFactory( rFactory
)
443 OReadMenuHandler::~OReadMenuHandler()
447 void SAL_CALL
OReadMenuHandler::startDocument()
448 throw ( SAXException
, RuntimeException
, std::exception
)
452 void SAL_CALL
OReadMenuHandler::endDocument()
453 throw( SAXException
, RuntimeException
, std::exception
)
457 void SAL_CALL
OReadMenuHandler::startElement(
458 const OUString
& aName
, const Reference
< XAttributeList
> &xAttrList
)
459 throw( SAXException
, RuntimeException
, std::exception
)
461 if ( m_bMenuPopupMode
)
464 m_xReader
->startElement( aName
, xAttrList
);
466 else if ( aName
== ELEMENT_MENUPOPUP
)
469 m_bMenuPopupMode
= true;
470 m_xReader
= Reference
< XDocumentHandler
>( new OReadMenuPopupHandler( m_xMenuContainer
, m_xContainerFactory
));
471 m_xReader
->startDocument();
475 OUString aErrorMessage
= getErrorLineString();
476 aErrorMessage
+= "unknown element found!";
477 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
481 void SAL_CALL
OReadMenuHandler::characters(const OUString
&)
482 throw( SAXException
, RuntimeException
, std::exception
)
486 void SAL_CALL
OReadMenuHandler::endElement( const OUString
& aName
)
487 throw( SAXException
, RuntimeException
, std::exception
)
489 if ( m_bMenuPopupMode
)
492 if ( 0 == m_nElementDepth
)
494 m_xReader
->endDocument();
496 m_bMenuPopupMode
= false;
497 if ( aName
!= ELEMENT_MENUPOPUP
)
499 OUString aErrorMessage
= getErrorLineString();
500 aErrorMessage
+= "closing element menupopup expected!";
501 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
505 m_xReader
->endElement( aName
);
509 OReadMenuPopupHandler::OReadMenuPopupHandler(
510 const Reference
< XIndexContainer
>& rMenuContainer
,
511 const Reference
< XSingleComponentFactory
>& rFactory
) :
512 m_nElementDepth( 0 ),
513 m_bMenuMode( false ),
514 m_xMenuContainer( rMenuContainer
),
515 m_xContainerFactory( rFactory
),
516 m_xComponentContext( comphelper::getProcessComponentContext() ),
517 m_nNextElementExpected( ELEM_CLOSE_NONE
)
521 OReadMenuPopupHandler::~OReadMenuPopupHandler()
525 void SAL_CALL
OReadMenuPopupHandler::startDocument()
526 throw ( SAXException
, RuntimeException
, std::exception
)
530 void SAL_CALL
OReadMenuPopupHandler::endDocument()
531 throw( SAXException
, RuntimeException
, std::exception
)
535 void SAL_CALL
OReadMenuPopupHandler::startElement(
536 const OUString
& rName
, const Reference
< XAttributeList
> &xAttrList
)
537 throw( SAXException
, RuntimeException
, std::exception
)
542 m_xReader
->startElement( rName
, xAttrList
);
543 else if ( rName
== ELEMENT_MENU
)
548 sal_Int16
nItemBits(0);
552 // Container must be factory to create sub container
553 Reference
< XIndexContainer
> xSubItemContainer
;
554 if ( m_xContainerFactory
.is() )
555 xSubItemContainer
= Reference
< XIndexContainer
>( m_xContainerFactory
->createInstanceWithContext( m_xComponentContext
), UNO_QUERY
);
557 // read attributes for menu
558 for ( sal_Int16 i
=0; i
< xAttrList
->getLength(); i
++ )
560 OUString aName
= xAttrList
->getNameByIndex( i
);
561 OUString aValue
= xAttrList
->getValueByIndex( i
);
562 if ( aName
== ATTRIBUTE_ID
)
564 else if ( aName
== ATTRIBUTE_LABEL
)
566 else if ( aName
== ATTRIBUTE_HELPID
)
568 else if ( aName
== ATTRIBUTE_STYLE
)
570 OUString
aTemp( aValue
);
571 sal_Int32 nIndex
= 0;
574 OUString aToken
= aTemp
.getToken( 0, '+', nIndex
);
575 if ( !aToken
.isEmpty() )
577 if ( aToken
== ATTRIBUTE_ITEMSTYLE_TEXT
)
578 nItemBits
|= ::com::sun::star::ui::ItemStyle::TEXT
;
579 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_IMAGE
)
580 nItemBits
|= ::com::sun::star::ui::ItemStyle::ICON
;
581 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_RADIO
)
582 nItemBits
|= ::com::sun::star::ui::ItemStyle::RADIO_CHECK
;
585 while ( nIndex
>= 0 );
590 if ( !aCommandId
.isEmpty() )
592 Sequence
< PropertyValue
> aSubMenuProp( 6 );
593 initPropertyCommon( aSubMenuProp
, aCommandId
, aHelpId
, aLabel
, nItemBits
);
594 aSubMenuProp
[2].Value
<<= xSubItemContainer
;
596 m_xMenuContainer
->insertByIndex( m_xMenuContainer
->getCount(), makeAny( aSubMenuProp
) );
600 OUString aErrorMessage
= getErrorLineString();
601 aErrorMessage
+= "attribute id for element menu required!";
602 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
605 m_xReader
= Reference
< XDocumentHandler
>( new OReadMenuHandler( xSubItemContainer
, m_xContainerFactory
));
606 m_xReader
->startDocument();
608 else if ( rName
== ELEMENT_MENUITEM
)
613 sal_Int16
nItemBits(0);
614 // read attributes for menu item
615 for ( sal_Int16 i
=0; i
< xAttrList
->getLength(); i
++ )
617 OUString aName
= xAttrList
->getNameByIndex( i
);
618 OUString aValue
= xAttrList
->getValueByIndex( i
);
619 if ( aName
== ATTRIBUTE_ID
)
621 else if ( aName
== ATTRIBUTE_LABEL
)
623 else if ( aName
== ATTRIBUTE_HELPID
)
625 else if ( aName
== ATTRIBUTE_STYLE
)
627 OUString
aTemp( aValue
);
628 sal_Int32 nIndex
= 0;
631 OUString aToken
= aTemp
.getToken( 0, '+', nIndex
);
632 if ( !aToken
.isEmpty() )
634 if ( aToken
== ATTRIBUTE_ITEMSTYLE_TEXT
)
635 nItemBits
|= ::com::sun::star::ui::ItemStyle::TEXT
;
636 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_IMAGE
)
637 nItemBits
|= ::com::sun::star::ui::ItemStyle::ICON
;
638 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_RADIO
)
639 nItemBits
|= ::com::sun::star::ui::ItemStyle::RADIO_CHECK
;
642 while ( nIndex
>= 0 );
647 if ( !aCommandId
.isEmpty() )
649 Sequence
< PropertyValue
> aMenuItem( 6 );
650 initPropertyCommon( aMenuItem
, aCommandId
, aHelpId
, aLabel
, nItemBits
);
651 aMenuItem
[2].Value
<<= Reference
< XIndexContainer
>();
653 m_xMenuContainer
->insertByIndex( m_xMenuContainer
->getCount(), makeAny( aMenuItem
) );
656 m_nNextElementExpected
= ELEM_CLOSE_MENUITEM
;
658 else if ( rName
== ELEMENT_MENUSEPARATOR
)
660 Sequence
< PropertyValue
> aMenuSeparator( 1 );
661 aMenuSeparator
[0].Name
= ITEM_DESCRIPTOR_TYPE
;
662 aMenuSeparator
[0].Value
<<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE
;
664 m_xMenuContainer
->insertByIndex( m_xMenuContainer
->getCount(), makeAny( aMenuSeparator
) );
666 m_nNextElementExpected
= ELEM_CLOSE_MENUSEPARATOR
;
670 OUString aErrorMessage
= getErrorLineString();
671 aErrorMessage
+= "unknown element found!";
672 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
676 void SAL_CALL
OReadMenuPopupHandler::characters(const OUString
&)
677 throw( SAXException
, RuntimeException
, std::exception
)
681 void SAL_CALL
OReadMenuPopupHandler::endElement( const OUString
& aName
)
682 throw( SAXException
, RuntimeException
, std::exception
)
687 if ( 0 == m_nElementDepth
)
689 m_xReader
->endDocument();
692 if ( aName
!= ELEMENT_MENU
)
694 OUString aErrorMessage
= getErrorLineString();
695 aErrorMessage
+= "closing element menu expected!";
696 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
700 m_xReader
->endElement( aName
);
704 if ( m_nNextElementExpected
== ELEM_CLOSE_MENUITEM
)
706 if ( aName
!= ELEMENT_MENUITEM
)
708 OUString aErrorMessage
= getErrorLineString();
709 aErrorMessage
+= "closing element menuitem expected!";
710 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
713 else if ( m_nNextElementExpected
== ELEM_CLOSE_MENUSEPARATOR
)
715 if ( aName
!= ELEMENT_MENUSEPARATOR
)
717 OUString aErrorMessage
= getErrorLineString();
718 aErrorMessage
+= "closing element menuseparator expected!";
719 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
723 m_nNextElementExpected
= ELEM_CLOSE_NONE
;
727 // --------------------------------- Write XML ---------------------------------
729 OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
730 const Reference
< XIndexAccess
>& rMenuBarContainer
,
731 const Reference
< XDocumentHandler
>& rDocumentHandler
) :
732 m_xMenuBarContainer( rMenuBarContainer
),
733 m_xWriteDocumentHandler( rDocumentHandler
)
735 ::comphelper::AttributeList
* pList
= new ::comphelper::AttributeList
;
736 m_xEmptyList
= Reference
< XAttributeList
>( (XAttributeList
*) pList
, UNO_QUERY
);
737 m_aAttributeType
= ATTRIBUTE_TYPE_CDATA
;
740 OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
744 void OWriteMenuDocumentHandler::WriteMenuDocument()
745 throw ( SAXException
, RuntimeException
)
747 ::comphelper::AttributeList
* pList
= new ::comphelper::AttributeList
;
748 Reference
< XAttributeList
> rList( (XAttributeList
*) pList
, UNO_QUERY
);
750 m_xWriteDocumentHandler
->startDocument();
752 // write DOCTYPE line!
753 Reference
< XExtendedDocumentHandler
> xExtendedDocHandler( m_xWriteDocumentHandler
, UNO_QUERY
);
754 if ( xExtendedDocHandler
.is() )
756 xExtendedDocHandler
->unknown( OUString( MENUBAR_DOCTYPE
) );
757 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
760 pList
->AddAttribute( OUString( ATTRIBUTE_XMLNS_MENU
),
762 OUString( XMLNS_MENU
) );
764 pList
->AddAttribute( OUString( ATTRIBUTE_NS_ID
),
766 OUString( "menubar" ) );
768 m_xWriteDocumentHandler
->startElement( OUString( ELEMENT_NS_MENUBAR
), pList
);
769 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
771 WriteMenu( m_xMenuBarContainer
);
773 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
774 m_xWriteDocumentHandler
->endElement( OUString( ELEMENT_NS_MENUBAR
) );
775 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
776 m_xWriteDocumentHandler
->endDocument();
779 void OWriteMenuDocumentHandler::WriteMenu( const Reference
< XIndexAccess
>& rMenuContainer
)
780 throw ( SAXException
, RuntimeException
)
782 sal_Int32 nItemCount
= rMenuContainer
->getCount();
783 bool bSeparator
= false;
786 for ( sal_Int32 nItemPos
= 0; nItemPos
< nItemCount
; nItemPos
++ )
788 Sequence
< PropertyValue
> aProps
;
789 aAny
= rMenuContainer
->getByIndex( nItemPos
);
790 if ( aAny
>>= aProps
)
792 OUString aCommandURL
;
795 sal_Int16
nType( ::com::sun::star::ui::ItemType::DEFAULT
);
796 sal_Int16
nItemBits( 0 );
797 Reference
< XIndexAccess
> xSubMenu
;
799 ExtractMenuParameters( aProps
, aCommandURL
, aLabel
, aHelpURL
, xSubMenu
, nType
, nItemBits
);
802 if ( aCommandURL
== ADDDIRECT_CMD
||
803 aCommandURL
== AUTOPILOTMENU_CMD
)
805 WriteMenuItem( aCommandURL
, aLabel
, aHelpURL
, nItemBits
);
808 else if ( !aCommandURL
.isEmpty() && !AddonPopupMenu::IsCommandURLPrefix( aCommandURL
))
810 ::comphelper::AttributeList
* pListMenu
= new ::comphelper::AttributeList
;
811 Reference
< XAttributeList
> xListMenu( (XAttributeList
*)pListMenu
, UNO_QUERY
);
813 pListMenu
->AddAttribute( OUString( ATTRIBUTE_NS_ID
),
817 if ( aCommandURL
.copy( CMD_PROTOCOL_SIZE
) != CMD_PROTOCOL
)
818 pListMenu
->AddAttribute( OUString( ATTRIBUTE_NS_LABEL
),
822 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
823 m_xWriteDocumentHandler
->startElement( OUString( ELEMENT_NS_MENU
), xListMenu
);
824 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
825 m_xWriteDocumentHandler
->startElement( OUString( ELEMENT_NS_MENUPOPUP
), m_xEmptyList
);
826 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
828 WriteMenu( xSubMenu
);
830 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
831 m_xWriteDocumentHandler
->endElement( OUString( ELEMENT_NS_MENUPOPUP
) );
832 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
833 m_xWriteDocumentHandler
->endElement( OUString( ELEMENT_NS_MENU
) );
834 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
840 if ( nType
== ::com::sun::star::ui::ItemType::DEFAULT
)
842 if ( !aCommandURL
.isEmpty() )
845 WriteMenuItem( aCommandURL
, aLabel
, aHelpURL
, nItemBits
);
848 else if ( !bSeparator
)
850 // Don't write two separators together
851 WriteMenuSeparator();
859 void OWriteMenuDocumentHandler::WriteMenuItem( const OUString
& aCommandURL
, const OUString
& aLabel
, const OUString
& aHelpURL
, sal_Int16 nStyle
)
861 ::comphelper::AttributeList
* pList
= new ::comphelper::AttributeList
;
862 Reference
< XAttributeList
> xList( (XAttributeList
*) pList
, UNO_QUERY
);
864 pList
->AddAttribute( OUString( ATTRIBUTE_NS_ID
),
868 if ( !aHelpURL
.isEmpty() )
870 pList
->AddAttribute( OUString( ATTRIBUTE_NS_HELPID
),
875 if ( !aLabel
.isEmpty() && aCommandURL
.copy( CMD_PROTOCOL_SIZE
) != CMD_PROTOCOL
)
877 pList
->AddAttribute( OUString( ATTRIBUTE_NS_LABEL
),
881 if (( nStyle
> 0 ) && aCommandURL
.copy( CMD_PROTOCOL_SIZE
) != CMD_PROTOCOL
)
884 MenuStyleItem
* pStyle
= MenuItemStyles
;
886 for ( sal_Int32 nIndex
= 0; nIndex
< nMenuStyleItemEntries
; ++nIndex
, ++pStyle
)
888 if ( nStyle
& pStyle
->nBit
)
890 if ( !aValue
.isEmpty() )
891 aValue
= aValue
.concat( OUString( "+" ) );
892 aValue
+= OUString::createFromAscii( pStyle
->attrName
);
895 pList
->AddAttribute( OUString( ATTRIBUTE_NS_STYLE
),
900 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
901 m_xWriteDocumentHandler
->startElement( OUString( ELEMENT_NS_MENUITEM
), xList
);
902 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
903 m_xWriteDocumentHandler
->endElement( OUString( ELEMENT_NS_MENUITEM
) );
906 void OWriteMenuDocumentHandler::WriteMenuSeparator()
908 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
909 m_xWriteDocumentHandler
->startElement( OUString( ELEMENT_NS_MENUSEPARATOR
), m_xEmptyList
);
910 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
911 m_xWriteDocumentHandler
->endElement( OUString( ELEMENT_NS_MENUSEPARATOR
) );
914 } // namespace framework
916 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */