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>
22 #include <rtl/ref.hxx>
23 #include <rtl/ustrbuf.hxx>
25 #include <xml/menudocumenthandler.hxx>
26 #include <framework/menuconfiguration.hxx>
28 #include <com/sun/star/xml/sax/SAXException.hpp>
29 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
30 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
31 #include <com/sun/star/ui/ItemType.hpp>
32 #include <com/sun/star/ui/ItemStyle.hpp>
33 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/attributelist.hxx>
38 #ifdef ATTRIBUTE_HELPID
39 #undef ATTRIBUTE_HELPID
42 #define XMLNS_MENU "http://openoffice.org/2001/menu"
44 #define ELEMENT_MENUBAR "http://openoffice.org/2001/menu^menubar"
45 #define ELEMENT_MENU "http://openoffice.org/2001/menu^menu"
46 #define ELEMENT_MENUPOPUP "http://openoffice.org/2001/menu^menupopup"
47 #define ELEMENT_MENUITEM "http://openoffice.org/2001/menu^menuitem"
48 #define ELEMENT_MENUSEPARATOR "http://openoffice.org/2001/menu^menuseparator"
50 #define ELEMENT_NS_MENUBAR "menu:menubar"
51 #define ELEMENT_NS_MENU "menu:menu"
52 #define ELEMENT_NS_MENUPOPUP "menu:menupopup"
53 #define ELEMENT_NS_MENUITEM "menu:menuitem"
54 #define ELEMENT_NS_MENUSEPARATOR "menu:menuseparator"
56 #define ATTRIBUTE_ID "http://openoffice.org/2001/menu^id"
57 #define ATTRIBUTE_LABEL "http://openoffice.org/2001/menu^label"
58 #define ATTRIBUTE_HELPID "http://openoffice.org/2001/menu^helpid"
59 #define ATTRIBUTE_STYLE "http://openoffice.org/2001/menu^style"
61 #define ATTRIBUTE_NS_ID "menu:id"
62 #define ATTRIBUTE_NS_LABEL "menu:label"
63 #define ATTRIBUTE_NS_HELPID "menu:helpid"
64 #define ATTRIBUTE_NS_STYLE "menu:style"
66 #define ATTRIBUTE_XMLNS_MENU "xmlns:menu"
68 #define ATTRIBUTE_TYPE_CDATA "CDATA"
70 #define MENUBAR_DOCTYPE "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">"
72 #define ATTRIBUTE_ITEMSTYLE_TEXT "text"
73 #define ATTRIBUTE_ITEMSTYLE_IMAGE "image"
74 #define ATTRIBUTE_ITEMSTYLE_RADIO "radio"
76 // Property names of a menu/menu item ItemDescriptor
77 static const char ITEM_DESCRIPTOR_COMMANDURL
[] = "CommandURL";
78 static const char ITEM_DESCRIPTOR_HELPURL
[] = "HelpURL";
79 static const char ITEM_DESCRIPTOR_CONTAINER
[] = "ItemDescriptorContainer";
80 static const char ITEM_DESCRIPTOR_LABEL
[] = "Label";
81 static const char ITEM_DESCRIPTOR_TYPE
[] = "Type";
82 static const char ITEM_DESCRIPTOR_STYLE
[] = "Style";
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 const MenuStyleItem MenuItemStyles
[ ] = {
103 { css::ui::ItemStyle::ICON
, ATTRIBUTE_ITEMSTYLE_IMAGE
},
104 { css::ui::ItemStyle::TEXT
, ATTRIBUTE_ITEMSTYLE_TEXT
},
105 { css::ui::ItemStyle::RADIO_CHECK
, ATTRIBUTE_ITEMSTYLE_RADIO
}
108 sal_Int32
const nMenuStyleItemEntries
= SAL_N_ELEMENTS(MenuItemStyles
);
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() :
151 m_aType( ITEM_DESCRIPTOR_TYPE
),
152 m_aLabel( ITEM_DESCRIPTOR_LABEL
),
153 m_aContainer( ITEM_DESCRIPTOR_CONTAINER
),
154 m_aHelpURL( ITEM_DESCRIPTOR_HELPURL
),
155 m_aCommandURL( ITEM_DESCRIPTOR_COMMANDURL
),
156 m_aStyle( ITEM_DESCRIPTOR_STYLE
)
160 ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
164 void SAL_CALL
ReadMenuDocumentHandlerBase::ignorableWhitespace(
169 void SAL_CALL
ReadMenuDocumentHandlerBase::processingInstruction(
170 const OUString
& /*aTarget*/, const OUString
& /*aData*/ )
174 void SAL_CALL
ReadMenuDocumentHandlerBase::setDocumentLocator(
175 const Reference
< XLocator
> &xLocator
)
177 m_xLocator
= xLocator
;
180 OUString
ReadMenuDocumentHandlerBase::getErrorLineString()
182 if ( m_xLocator
.is() )
185 snprintf( buffer
, sizeof(buffer
), "Line: %ld - ", static_cast<long>( m_xLocator
->getLineNumber() ));
186 return OUString::createFromAscii( buffer
);
192 void ReadMenuDocumentHandlerBase::initPropertyCommon(
193 Sequence
< PropertyValue
> &rProps
, const OUString
&rCommandURL
,
194 const OUString
&rHelpId
, const OUString
&rLabel
, sal_Int16 nItemStyleBits
)
196 rProps
[0].Name
= m_aCommandURL
;
197 rProps
[1].Name
= m_aHelpURL
;
198 rProps
[2].Name
= m_aContainer
;
199 rProps
[3].Name
= m_aLabel
;
200 rProps
[4].Name
= m_aStyle
;
201 rProps
[5].Name
= m_aType
;
204 rProps
[0].Value
<<= rCommandURL
.intern();
205 rProps
[1].Value
<<= rHelpId
;
206 rProps
[2].Value
<<= Reference
< XIndexContainer
>();
207 rProps
[3].Value
<<= rLabel
;
208 rProps
[4].Value
<<= nItemStyleBits
;
209 rProps
[5].Value
<<= css::ui::ItemType::DEFAULT
;
212 OReadMenuDocumentHandler::OReadMenuDocumentHandler(
213 const Reference
< XIndexContainer
>& rMenuBarContainer
)
214 : m_nElementDepth( 0 ),
215 m_eReaderMode( ReaderMode::None
),
216 m_xMenuBarContainer( rMenuBarContainer
),
217 m_xContainerFactory( rMenuBarContainer
, UNO_QUERY
)
221 OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
225 void SAL_CALL
OReadMenuDocumentHandler::startDocument()
229 void SAL_CALL
OReadMenuDocumentHandler::endDocument()
231 if ( m_nElementDepth
> 0 )
233 OUString aErrorMessage
= getErrorLineString() +
234 "A closing element is missing!";
235 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
239 void SAL_CALL
OReadMenuDocumentHandler::startElement(
240 const OUString
& aName
, const Reference
< XAttributeList
> &xAttrList
)
242 if ( m_eReaderMode
!= ReaderMode::None
)
245 m_xReader
->startElement( aName
, xAttrList
);
249 if ( aName
== ELEMENT_MENUBAR
)
251 m_eReaderMode
= ReaderMode::MenuBar
;
252 m_xReader
.set( new OReadMenuBarHandler( m_xMenuBarContainer
, m_xContainerFactory
));
254 else if ( aName
== ELEMENT_MENUPOPUP
)
256 m_eReaderMode
= ReaderMode::MenuPopup
;
257 m_xReader
.set( new OReadMenuPopupHandler( m_xMenuBarContainer
, m_xContainerFactory
));
260 m_xReader
->startDocument();
264 void SAL_CALL
OReadMenuDocumentHandler::characters(const OUString
&)
268 void SAL_CALL
OReadMenuDocumentHandler::endElement( const OUString
& aName
)
270 if ( m_eReaderMode
!= ReaderMode::None
)
273 m_xReader
->endElement( aName
);
274 if ( 0 == m_nElementDepth
)
276 m_xReader
->endDocument();
278 if ( m_eReaderMode
== ReaderMode::MenuBar
&& aName
!= ELEMENT_MENUBAR
)
280 OUString aErrorMessage
= getErrorLineString() +
281 "closing element menubar expected!";
282 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
284 else if ( m_eReaderMode
== ReaderMode::MenuPopup
&& aName
!= ELEMENT_MENUPOPUP
)
286 OUString aErrorMessage
= getErrorLineString() +
287 "closing element menupopup expected!";
288 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
290 m_eReaderMode
= ReaderMode::None
;
295 OReadMenuBarHandler::OReadMenuBarHandler(
296 const Reference
< XIndexContainer
>& rMenuBarContainer
,
297 const Reference
< XSingleComponentFactory
>& rFactory
)
298 : m_nElementDepth( 0 ),
299 m_bMenuMode( false ),
300 m_xMenuBarContainer( rMenuBarContainer
),
301 m_xContainerFactory( rFactory
)
305 OReadMenuBarHandler::~OReadMenuBarHandler()
309 void SAL_CALL
OReadMenuBarHandler::startDocument()
313 void SAL_CALL
OReadMenuBarHandler::endDocument()
317 void SAL_CALL
OReadMenuBarHandler::startElement(
318 const OUString
& rName
, const Reference
< XAttributeList
> &xAttrList
)
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
.set( 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 const 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 sal_Int32 nIndex
= 0;
362 OUString aToken
= aValue
.getToken( 0, '+', nIndex
);
363 if ( !aToken
.isEmpty() )
365 if ( aToken
== ATTRIBUTE_ITEMSTYLE_TEXT
)
366 nItemBits
|= css::ui::ItemStyle::TEXT
;
367 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_IMAGE
)
368 nItemBits
|= css::ui::ItemStyle::ICON
;
369 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_RADIO
)
370 nItemBits
|= css::ui::ItemStyle::RADIO_CHECK
;
373 while ( nIndex
>= 0 );
377 if ( !aCommandId
.isEmpty() )
379 Sequence
< PropertyValue
> aSubMenuProp( 6 );
380 initPropertyCommon( aSubMenuProp
, aCommandId
, aHelpId
, aLabel
, nItemBits
);
381 aSubMenuProp
[2].Value
<<= xSubItemContainer
;
383 m_xMenuBarContainer
->insertByIndex( m_xMenuBarContainer
->getCount(), makeAny( aSubMenuProp
) );
387 OUString aErrorMessage
= getErrorLineString() +
388 "attribute id for element menu required!";
389 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
392 m_xReader
.set( new OReadMenuHandler( xSubItemContainer
, m_xContainerFactory
));
393 m_xReader
->startDocument();
398 OUString aErrorMessage
= getErrorLineString() +
399 "element menu expected!";
400 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
404 void SAL_CALL
OReadMenuBarHandler::characters(const OUString
&)
408 void OReadMenuBarHandler::endElement( const OUString
& aName
)
413 if ( 0 == m_nElementDepth
)
415 m_xReader
->endDocument();
418 if ( aName
!= ELEMENT_MENU
)
420 OUString aErrorMessage
= getErrorLineString() +
421 "closing element menu expected!";
422 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
426 m_xReader
->endElement( aName
);
430 OReadMenuHandler::OReadMenuHandler(
431 const Reference
< XIndexContainer
>& rMenuContainer
,
432 const Reference
< XSingleComponentFactory
>& rFactory
) :
433 m_nElementDepth( 0 ),
434 m_bMenuPopupMode( false ),
435 m_xMenuContainer( rMenuContainer
),
436 m_xContainerFactory( rFactory
)
440 OReadMenuHandler::~OReadMenuHandler()
444 void SAL_CALL
OReadMenuHandler::startDocument()
448 void SAL_CALL
OReadMenuHandler::endDocument()
452 void SAL_CALL
OReadMenuHandler::startElement(
453 const OUString
& aName
, const Reference
< XAttributeList
> &xAttrList
)
455 if ( m_bMenuPopupMode
)
458 m_xReader
->startElement( aName
, xAttrList
);
460 else if ( aName
== ELEMENT_MENUPOPUP
)
463 m_bMenuPopupMode
= true;
464 m_xReader
.set( new OReadMenuPopupHandler( m_xMenuContainer
, m_xContainerFactory
));
465 m_xReader
->startDocument();
469 OUString aErrorMessage
= getErrorLineString() +
470 "unknown element found!";
471 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
475 void SAL_CALL
OReadMenuHandler::characters(const OUString
&)
479 void SAL_CALL
OReadMenuHandler::endElement( const OUString
& aName
)
481 if ( m_bMenuPopupMode
)
484 if ( 0 == m_nElementDepth
)
486 m_xReader
->endDocument();
488 m_bMenuPopupMode
= false;
489 if ( aName
!= ELEMENT_MENUPOPUP
)
491 OUString aErrorMessage
= getErrorLineString() +
492 "closing element menupopup expected!";
493 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
497 m_xReader
->endElement( aName
);
501 OReadMenuPopupHandler::OReadMenuPopupHandler(
502 const Reference
< XIndexContainer
>& rMenuContainer
,
503 const Reference
< XSingleComponentFactory
>& rFactory
) :
504 m_nElementDepth( 0 ),
505 m_bMenuMode( false ),
506 m_xMenuContainer( rMenuContainer
),
507 m_xContainerFactory( rFactory
),
508 m_xComponentContext( comphelper::getProcessComponentContext() ),
509 m_nNextElementExpected( ELEM_CLOSE_NONE
)
513 OReadMenuPopupHandler::~OReadMenuPopupHandler()
517 void SAL_CALL
OReadMenuPopupHandler::startDocument()
521 void SAL_CALL
OReadMenuPopupHandler::endDocument()
525 void SAL_CALL
OReadMenuPopupHandler::startElement(
526 const OUString
& rName
, const Reference
< XAttributeList
> &xAttrList
)
531 m_xReader
->startElement( rName
, xAttrList
);
532 else if ( rName
== ELEMENT_MENU
)
537 sal_Int16
nItemBits(0);
541 // Container must be factory to create sub container
542 Reference
< XIndexContainer
> xSubItemContainer
;
543 if ( m_xContainerFactory
.is() )
544 xSubItemContainer
.set( m_xContainerFactory
->createInstanceWithContext( m_xComponentContext
), UNO_QUERY
);
546 // read attributes for menu
547 for ( sal_Int16 i
=0; i
< xAttrList
->getLength(); i
++ )
549 OUString aName
= xAttrList
->getNameByIndex( i
);
550 const OUString aValue
= xAttrList
->getValueByIndex( i
);
551 if ( aName
== ATTRIBUTE_ID
)
553 else if ( aName
== ATTRIBUTE_LABEL
)
555 else if ( aName
== ATTRIBUTE_HELPID
)
557 else if ( aName
== ATTRIBUTE_STYLE
)
559 sal_Int32 nIndex
= 0;
562 OUString aToken
= aValue
.getToken( 0, '+', nIndex
);
563 if ( !aToken
.isEmpty() )
565 if ( aToken
== ATTRIBUTE_ITEMSTYLE_TEXT
)
566 nItemBits
|= css::ui::ItemStyle::TEXT
;
567 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_IMAGE
)
568 nItemBits
|= css::ui::ItemStyle::ICON
;
569 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_RADIO
)
570 nItemBits
|= css::ui::ItemStyle::RADIO_CHECK
;
573 while ( nIndex
>= 0 );
578 if ( !aCommandId
.isEmpty() )
580 Sequence
< PropertyValue
> aSubMenuProp( 6 );
581 initPropertyCommon( aSubMenuProp
, aCommandId
, aHelpId
, aLabel
, nItemBits
);
582 aSubMenuProp
[2].Value
<<= xSubItemContainer
;
584 m_xMenuContainer
->insertByIndex( m_xMenuContainer
->getCount(), makeAny( aSubMenuProp
) );
588 OUString aErrorMessage
= getErrorLineString() +
589 "attribute id for element menu required!";
590 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
593 m_xReader
.set( new OReadMenuHandler( xSubItemContainer
, m_xContainerFactory
));
594 m_xReader
->startDocument();
596 else if ( rName
== ELEMENT_MENUITEM
)
601 sal_Int16
nItemBits(0);
602 // read attributes for menu item
603 for ( sal_Int16 i
=0; i
< xAttrList
->getLength(); i
++ )
605 OUString aName
= xAttrList
->getNameByIndex( i
);
606 const OUString aValue
= xAttrList
->getValueByIndex( i
);
607 if ( aName
== ATTRIBUTE_ID
)
609 else if ( aName
== ATTRIBUTE_LABEL
)
611 else if ( aName
== ATTRIBUTE_HELPID
)
613 else if ( aName
== ATTRIBUTE_STYLE
)
615 sal_Int32 nIndex
= 0;
618 OUString aToken
= aValue
.getToken( 0, '+', nIndex
);
619 if ( !aToken
.isEmpty() )
621 if ( aToken
== ATTRIBUTE_ITEMSTYLE_TEXT
)
622 nItemBits
|= css::ui::ItemStyle::TEXT
;
623 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_IMAGE
)
624 nItemBits
|= css::ui::ItemStyle::ICON
;
625 else if ( aToken
== ATTRIBUTE_ITEMSTYLE_RADIO
)
626 nItemBits
|= css::ui::ItemStyle::RADIO_CHECK
;
629 while ( nIndex
>= 0 );
634 if ( !aCommandId
.isEmpty() )
636 Sequence
< PropertyValue
> aMenuItem( 6 );
637 initPropertyCommon( aMenuItem
, aCommandId
, aHelpId
, aLabel
, nItemBits
);
638 aMenuItem
[2].Value
<<= Reference
< XIndexContainer
>();
640 m_xMenuContainer
->insertByIndex( m_xMenuContainer
->getCount(), makeAny( aMenuItem
) );
643 m_nNextElementExpected
= ELEM_CLOSE_MENUITEM
;
645 else if ( rName
== ELEMENT_MENUSEPARATOR
)
647 Sequence
< PropertyValue
> aMenuSeparator( 1 );
648 aMenuSeparator
[0].Name
= ITEM_DESCRIPTOR_TYPE
;
649 aMenuSeparator
[0].Value
<<= css::ui::ItemType::SEPARATOR_LINE
;
651 m_xMenuContainer
->insertByIndex( m_xMenuContainer
->getCount(), makeAny( aMenuSeparator
) );
653 m_nNextElementExpected
= ELEM_CLOSE_MENUSEPARATOR
;
657 OUString aErrorMessage
= getErrorLineString() +
658 "unknown element found!";
659 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
663 void SAL_CALL
OReadMenuPopupHandler::characters(const OUString
&)
667 void SAL_CALL
OReadMenuPopupHandler::endElement( const OUString
& aName
)
672 if ( 0 == m_nElementDepth
)
674 m_xReader
->endDocument();
677 if ( aName
!= ELEMENT_MENU
)
679 OUString aErrorMessage
= getErrorLineString() +
680 "closing element menu expected!";
681 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
685 m_xReader
->endElement( aName
);
689 if ( m_nNextElementExpected
== ELEM_CLOSE_MENUITEM
)
691 if ( aName
!= ELEMENT_MENUITEM
)
693 OUString aErrorMessage
= getErrorLineString() +
694 "closing element menuitem expected!";
695 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
698 else if ( m_nNextElementExpected
== ELEM_CLOSE_MENUSEPARATOR
)
700 if ( aName
!= ELEMENT_MENUSEPARATOR
)
702 OUString aErrorMessage
= getErrorLineString() +
703 "closing element menuseparator expected!";
704 throw SAXException( aErrorMessage
, Reference
< XInterface
>(), Any() );
708 m_nNextElementExpected
= ELEM_CLOSE_NONE
;
712 // --------------------------------- Write XML ---------------------------------
714 OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
715 const Reference
< XIndexAccess
>& rMenuBarContainer
,
716 const Reference
< XDocumentHandler
>& rDocumentHandler
,
718 m_xMenuBarContainer( rMenuBarContainer
),
719 m_xWriteDocumentHandler( rDocumentHandler
),
720 m_bIsMenuBar( bIsMenuBar
)
722 ::comphelper::AttributeList
* pList
= new ::comphelper::AttributeList
;
723 m_xEmptyList
.set( static_cast<XAttributeList
*>(pList
), UNO_QUERY
);
724 m_aAttributeType
= ATTRIBUTE_TYPE_CDATA
;
727 OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
731 void OWriteMenuDocumentHandler::WriteMenuDocument()
733 rtl::Reference
<::comphelper::AttributeList
> pList
= new ::comphelper::AttributeList
;
735 m_xWriteDocumentHandler
->startDocument();
737 // write DOCTYPE line!
738 Reference
< XExtendedDocumentHandler
> xExtendedDocHandler( m_xWriteDocumentHandler
, UNO_QUERY
);
739 if ( m_bIsMenuBar
/*FIXME*/ && xExtendedDocHandler
.is() )
741 xExtendedDocHandler
->unknown( MENUBAR_DOCTYPE
);
742 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
745 pList
->AddAttribute( ATTRIBUTE_XMLNS_MENU
,
749 if ( m_bIsMenuBar
) //FIXME
750 pList
->AddAttribute( ATTRIBUTE_NS_ID
,
754 OUString aRootElement
;
756 aRootElement
= ELEMENT_NS_MENUBAR
;
758 aRootElement
= ELEMENT_NS_MENUPOPUP
;
759 m_xWriteDocumentHandler
->startElement( aRootElement
, pList
.get() );
760 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
762 WriteMenu( m_xMenuBarContainer
);
764 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
765 m_xWriteDocumentHandler
->endElement( aRootElement
);
766 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
767 m_xWriteDocumentHandler
->endDocument();
770 void OWriteMenuDocumentHandler::WriteMenu( const Reference
< XIndexAccess
>& rMenuContainer
)
772 sal_Int32 nItemCount
= rMenuContainer
->getCount();
773 bool bSeparator
= false;
776 for ( sal_Int32 nItemPos
= 0; nItemPos
< nItemCount
; nItemPos
++ )
778 Sequence
< PropertyValue
> aProps
;
779 aAny
= rMenuContainer
->getByIndex( nItemPos
);
780 if ( aAny
>>= aProps
)
782 OUString aCommandURL
;
785 sal_Int16
nType( css::ui::ItemType::DEFAULT
);
786 sal_Int16
nItemBits( 0 );
787 Reference
< XIndexAccess
> xSubMenu
;
789 ExtractMenuParameters( aProps
, aCommandURL
, aLabel
, aHelpURL
, xSubMenu
, nType
, nItemBits
);
792 if ( !aCommandURL
.isEmpty() )
794 ::comphelper::AttributeList
* pListMenu
= new ::comphelper::AttributeList
;
795 Reference
< XAttributeList
> xListMenu( static_cast<XAttributeList
*>(pListMenu
) , UNO_QUERY
);
797 pListMenu
->AddAttribute( ATTRIBUTE_NS_ID
,
801 if ( !aLabel
.isEmpty() )
802 pListMenu
->AddAttribute( ATTRIBUTE_NS_LABEL
,
806 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
807 m_xWriteDocumentHandler
->startElement( ELEMENT_NS_MENU
, xListMenu
);
808 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
809 m_xWriteDocumentHandler
->startElement( ELEMENT_NS_MENUPOPUP
, m_xEmptyList
);
810 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
812 WriteMenu( xSubMenu
);
814 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
815 m_xWriteDocumentHandler
->endElement( ELEMENT_NS_MENUPOPUP
);
816 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
817 m_xWriteDocumentHandler
->endElement( ELEMENT_NS_MENU
);
818 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
824 if ( nType
== css::ui::ItemType::DEFAULT
)
826 if ( !aCommandURL
.isEmpty() )
829 WriteMenuItem( aCommandURL
, aLabel
, aHelpURL
, nItemBits
);
832 else if ( !bSeparator
)
834 // Don't write two separators together
835 WriteMenuSeparator();
843 void OWriteMenuDocumentHandler::WriteMenuItem( const OUString
& aCommandURL
, const OUString
& aLabel
, const OUString
& aHelpURL
, sal_Int16 nStyle
)
845 ::comphelper::AttributeList
* pList
= new ::comphelper::AttributeList
;
846 Reference
< XAttributeList
> xList( static_cast<XAttributeList
*>(pList
) , UNO_QUERY
);
848 pList
->AddAttribute( ATTRIBUTE_NS_ID
,
852 if ( !aHelpURL
.isEmpty() )
854 pList
->AddAttribute( ATTRIBUTE_NS_HELPID
,
859 if ( !aLabel
.isEmpty() )
861 pList
->AddAttribute( ATTRIBUTE_NS_LABEL
,
867 OUStringBuffer aValue
;
868 const MenuStyleItem
* pStyle
= MenuItemStyles
;
870 for ( sal_Int32 nIndex
= 0; nIndex
< nMenuStyleItemEntries
; ++nIndex
, ++pStyle
)
872 if ( nStyle
& pStyle
->nBit
)
874 if ( !aValue
.isEmpty() )
876 aValue
.appendAscii( pStyle
->attrName
);
879 pList
->AddAttribute( ATTRIBUTE_NS_STYLE
,
881 aValue
.makeStringAndClear() );
884 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
885 m_xWriteDocumentHandler
->startElement( ELEMENT_NS_MENUITEM
, xList
);
886 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
887 m_xWriteDocumentHandler
->endElement( ELEMENT_NS_MENUITEM
);
890 void OWriteMenuDocumentHandler::WriteMenuSeparator()
892 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
893 m_xWriteDocumentHandler
->startElement( ELEMENT_NS_MENUSEPARATOR
, m_xEmptyList
);
894 m_xWriteDocumentHandler
->ignorableWhitespace( OUString() );
895 m_xWriteDocumentHandler
->endElement( ELEMENT_NS_MENUSEPARATOR
);
898 } // namespace framework
900 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */