Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / framework / source / fwe / xml / menudocumenthandler.cxx
blob94a2dee58d78e1419c4c05d31e6d385fc68152f3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <stdio.h>
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
40 #endif
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";
84 // using namespaces
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;
93 namespace framework
96 struct MenuStyleItem
98 sal_Int16 nBit;
99 const char* attrName;
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,
112 OUString& rLabel,
113 OUString& rHelpURL,
114 Reference< XIndexAccess >& rSubMenu,
115 sal_Int16& rType,
116 sal_Int16& rStyle )
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(
165 const OUString& )
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() )
184 char buffer[32];
185 snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
186 return OUString::createFromAscii( buffer );
188 else
189 return OUString();
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;
203 // Common values
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 )
244 ++m_nElementDepth;
245 m_xReader->startElement( aName, xAttrList );
247 else
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 ));
259 ++m_nElementDepth;
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 )
272 --m_nElementDepth;
273 m_xReader->endElement( aName );
274 if ( 0 == m_nElementDepth )
276 m_xReader->endDocument();
277 m_xReader.clear();
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 )
320 if ( m_bMenuMode )
322 ++m_nElementDepth;
323 m_xReader->startElement( rName, xAttrList );
325 else if ( rName == ELEMENT_MENU )
327 ++m_nElementDepth;
329 OUString aHelpId;
330 OUString aCommandId;
331 OUString aLabel;
332 sal_Int16 nItemBits(0);
334 m_bMenuMode = true;
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 )
352 aCommandId = aValue;
353 else if ( aName == ATTRIBUTE_LABEL )
354 aLabel = aValue;
355 else if ( aName == ATTRIBUTE_HELPID )
356 aHelpId = aValue;
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 ) );
385 else
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();
396 else
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 )
410 if ( m_bMenuMode )
412 --m_nElementDepth;
413 if ( 0 == m_nElementDepth )
415 m_xReader->endDocument();
416 m_xReader.clear();
417 m_bMenuMode = false;
418 if ( aName != ELEMENT_MENU )
420 OUString aErrorMessage = getErrorLineString() +
421 "closing element menu expected!";
422 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
425 else
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 )
457 ++m_nElementDepth;
458 m_xReader->startElement( aName, xAttrList );
460 else if ( aName == ELEMENT_MENUPOPUP )
462 ++m_nElementDepth;
463 m_bMenuPopupMode = true;
464 m_xReader.set( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
465 m_xReader->startDocument();
467 else
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 )
483 --m_nElementDepth;
484 if ( 0 == m_nElementDepth )
486 m_xReader->endDocument();
487 m_xReader.clear();
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() );
496 else
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 )
528 ++m_nElementDepth;
530 if ( m_bMenuMode )
531 m_xReader->startElement( rName, xAttrList );
532 else if ( rName == ELEMENT_MENU )
534 OUString aHelpId;
535 OUString aCommandId;
536 OUString aLabel;
537 sal_Int16 nItemBits(0);
539 m_bMenuMode = true;
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 )
552 aCommandId = aValue;
553 else if ( aName == ATTRIBUTE_LABEL )
554 aLabel = aValue;
555 else if ( aName == ATTRIBUTE_HELPID )
556 aHelpId = aValue;
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 ) );
586 else
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 )
598 OUString aHelpId;
599 OUString aCommandId;
600 OUString aLabel;
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 )
608 aCommandId = aValue;
609 else if ( aName == ATTRIBUTE_LABEL )
610 aLabel = aValue;
611 else if ( aName == ATTRIBUTE_HELPID )
612 aHelpId = aValue;
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;
655 else
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 )
669 --m_nElementDepth;
670 if ( m_bMenuMode )
672 if ( 0 == m_nElementDepth )
674 m_xReader->endDocument();
675 m_xReader.clear();
676 m_bMenuMode = false;
677 if ( aName != ELEMENT_MENU )
679 OUString aErrorMessage = getErrorLineString() +
680 "closing element menu expected!";
681 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
684 else
685 m_xReader->endElement( aName );
687 else
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,
717 bool bIsMenuBar ) :
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,
746 m_aAttributeType,
747 XMLNS_MENU );
749 if ( m_bIsMenuBar ) //FIXME
750 pList->AddAttribute( ATTRIBUTE_NS_ID,
751 m_aAttributeType,
752 "menubar" );
754 OUString aRootElement;
755 if ( m_bIsMenuBar )
756 aRootElement = ELEMENT_NS_MENUBAR;
757 else
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;
774 Any aAny;
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;
783 OUString aLabel;
784 OUString aHelpURL;
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 );
790 if ( xSubMenu.is() )
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,
798 m_aAttributeType,
799 aCommandURL );
801 if ( !aLabel.isEmpty() )
802 pListMenu->AddAttribute( ATTRIBUTE_NS_LABEL,
803 m_aAttributeType,
804 aLabel );
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() );
819 bSeparator = false;
822 else
824 if ( nType == css::ui::ItemType::DEFAULT )
826 if ( !aCommandURL.isEmpty() )
828 bSeparator = false;
829 WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
832 else if ( !bSeparator )
834 // Don't write two separators together
835 WriteMenuSeparator();
836 bSeparator = true;
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,
849 m_aAttributeType,
850 aCommandURL );
852 if ( !aHelpURL.isEmpty() )
854 pList->AddAttribute( ATTRIBUTE_NS_HELPID,
855 m_aAttributeType,
856 aHelpURL );
859 if ( !aLabel.isEmpty() )
861 pList->AddAttribute( ATTRIBUTE_NS_LABEL,
862 m_aAttributeType,
863 aLabel );
865 if ( nStyle > 0 )
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() )
875 aValue.append("+");
876 aValue.appendAscii( pStyle->attrName );
879 pList->AddAttribute( ATTRIBUTE_NS_STYLE,
880 m_aAttributeType,
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: */