| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_framework.hxx" |
| |
| #include <stdio.h> |
| |
| //_________________________________________________________________________________________________________________ |
| // my own includes |
| //_________________________________________________________________________________________________________________ |
| #include <xml/menudocumenthandler.hxx> |
| #include <framework/menuconfiguration.hxx> |
| #include <framework/addonmenu.hxx> |
| |
| //_________________________________________________________________________________________________________________ |
| // interface includes |
| //_________________________________________________________________________________________________________________ |
| |
| #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> |
| #include <com/sun/star/lang/XSingleComponentFactory.hpp> |
| #include <com/sun/star/ui/ItemType.hpp> |
| #include <com/sun/star/ui/ItemStyle.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| |
| //_________________________________________________________________________________________________________________ |
| // other includes |
| //_________________________________________________________________________________________________________________ |
| #include <comphelper/processfactory.hxx> |
| #include <rtl/logfile.hxx> |
| #include <comphelper/attributelist.hxx> |
| |
| //_________________________________________________________________________________________________________________ |
| // defines |
| //_________________________________________________________________________________________________________________ |
| |
| #define XMLNS_MENU "http://openoffice.org/2001/menu" |
| #define XMLNS_PREFIX "menu:" |
| |
| #define ELEMENT_MENUBAR "http://openoffice.org/2001/menu^menubar" |
| #define ELEMENT_MENU "http://openoffice.org/2001/menu^menu" |
| #define ELEMENT_MENUPOPUP "http://openoffice.org/2001/menu^menupopup" |
| #define ELEMENT_MENUITEM "http://openoffice.org/2001/menu^menuitem" |
| #define ELEMENT_MENUSEPARATOR "http://openoffice.org/2001/menu^menuseparator" |
| |
| #define ELEMENT_NS_MENUBAR "menu:menubar" |
| #define ELEMENT_NS_MENU "menu:menu" |
| #define ELEMENT_NS_MENUPOPUP "menu:menupopup" |
| #define ELEMENT_NS_MENUITEM "menu:menuitem" |
| #define ELEMENT_NS_MENUSEPARATOR "menu:menuseparator" |
| |
| #define ATTRIBUTE_ID "http://openoffice.org/2001/menu^id" |
| #define ATTRIBUTE_LABEL "http://openoffice.org/2001/menu^label" |
| #define ATTRIBUTE_HELPID "http://openoffice.org/2001/menu^helpid" |
| #define ATTRIBUTE_LINEBREAK "http://openoffice.org/2001/menu^linebreak" |
| #define ATTRIBUTE_STYLE "http://openoffice.org/2001/menu^style" |
| |
| #define ATTRIBUTE_NS_ID "menu:id" |
| #define ATTRIBUTE_NS_LABEL "menu:label" |
| #define ATTRIBUTE_NS_HELPID "menu:helpid" |
| #define ATTRIBUTE_NS_LINEBREAK "menu:linebreak" |
| #define ATTRIBUTE_NS_STYLE "menu:style" |
| |
| #define ATTRIBUTE_XMLNS_MENU "xmlns:menu" |
| |
| #define ATTRIBUTE_TYPE_CDATA "CDATA" |
| |
| #define MENUBAR_DOCTYPE "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">" |
| |
| #define ATTRIBUTE_ITEMSTYLE_TEXT "text" |
| #define ATTRIBUTE_ITEMSTYLE_IMAGE "image" |
| #define ATTRIBUTE_ITEMSTYLE_RADIO "radio" |
| |
| // Property names of a menu/menu item ItemDescriptor |
| static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; |
| static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; |
| static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer"; |
| static const char ITEM_DESCRIPTOR_LABEL[] = "Label"; |
| static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; |
| static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; |
| |
| // special popup menus (filled during runtime) must be saved as an empty popup menu or menuitem!!! |
| static const sal_Int32 CMD_PROTOCOL_SIZE = 5; |
| static const char CMD_PROTOCOL[] = ".uno:"; |
| static const char ADDDIRECT_CMD[] = ".uno:AddDirect" ; |
| static const char AUTOPILOTMENU_CMD[] = ".uno:AutoPilotMenu" ; |
| static const char FILEMENU_CMD[] = ".uno:Picklist" ; |
| static const char WINDOWMENU_CMD[] = ".uno:WindowList" ; |
| |
| //_________________________________________________________________________________________________________________ |
| // using namespaces |
| //_________________________________________________________________________________________________________________ |
| |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::xml::sax; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::ui; |
| |
| namespace framework |
| { |
| |
| struct MenuStyleItem |
| { |
| sal_Int16 nBit; |
| const char* attrName; |
| }; |
| |
| MenuStyleItem MenuItemStyles[ ] = { |
| { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE }, |
| { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT }, |
| { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO } |
| }; |
| |
| |
| sal_Int32 nMenuStyleItemEntries = sizeof( MenuItemStyles ) / sizeof( MenuItemStyles[ 0 ] ); |
| |
| static void ExtractMenuParameters( const Sequence< PropertyValue > rProp, |
| ::rtl::OUString& rCommandURL, |
| ::rtl::OUString& rLabel, |
| ::rtl::OUString& rHelpURL, |
| Reference< XIndexAccess >& rSubMenu, |
| sal_Int16& rType, |
| sal_Int16& rStyle ) |
| { |
| for ( sal_Int32 i = 0; i < rProp.getLength(); i++ ) |
| { |
| if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL )) |
| { |
| rProp[i].Value >>= rCommandURL; |
| rCommandURL = rCommandURL.intern(); |
| } |
| else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL )) |
| { |
| rProp[i].Value >>= rHelpURL; |
| } |
| else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_CONTAINER )) |
| { |
| rProp[i].Value >>= rSubMenu; |
| } |
| else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL )) |
| { |
| rProp[i].Value >>= rLabel; |
| } |
| else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE )) |
| { |
| rProp[i].Value >>= rType; |
| } |
| else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE )) |
| { |
| rProp[i].Value >>= rStyle; |
| } |
| } |
| } |
| |
| |
| // ----------------------------------------------------------------------------- |
| // Base class implementation |
| |
| ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() : |
| m_xLocator( 0 ), |
| m_xReader( 0 ), |
| m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )), |
| m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )), |
| m_aContainer( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER )), |
| m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )), |
| m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL )), |
| m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )) |
| { |
| } |
| |
| ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase() |
| { |
| } |
| |
| void SAL_CALL ReadMenuDocumentHandlerBase::ignorableWhitespace( |
| const ::rtl::OUString& ) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction( |
| const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator( |
| const Reference< XLocator > &xLocator) |
| throw( SAXException, RuntimeException ) |
| { |
| m_xLocator = xLocator; |
| } |
| |
| ::rtl::OUString ReadMenuDocumentHandlerBase::getErrorLineString() |
| { |
| char buffer[32]; |
| |
| if ( m_xLocator.is() ) |
| { |
| snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() )); |
| return ::rtl::OUString::createFromAscii( buffer ); |
| } |
| else |
| return ::rtl::OUString(); |
| } |
| |
| void ReadMenuDocumentHandlerBase::initPropertyCommon( |
| Sequence< PropertyValue > &rProps, const rtl::OUString &rCommandURL, |
| const rtl::OUString &rHelpId, const rtl::OUString &rLabel, sal_Int16 nItemStyleBits ) |
| { |
| rProps[0].Name = m_aCommandURL; |
| rProps[1].Name = m_aHelpURL; |
| rProps[2].Name = m_aContainer; |
| rProps[3].Name = m_aLabel; |
| rProps[4].Name = m_aStyle; |
| rProps[5].Name = m_aType; |
| |
| // Common values |
| rProps[0].Value <<= rCommandURL.intern(); |
| rProps[1].Value <<= rHelpId; |
| rProps[2].Value <<= Reference< XIndexContainer >(); |
| rProps[3].Value <<= rLabel; |
| rProps[4].Value <<= nItemStyleBits; |
| rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| OReadMenuDocumentHandler::OReadMenuDocumentHandler( |
| const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, |
| const Reference< XIndexContainer >& rMenuBarContainer ) |
| : m_nElementDepth( 0 ), |
| m_bMenuBarMode( sal_False ), |
| m_xMenuBarContainer( rMenuBarContainer ), |
| m_xContainerFactory( rMenuBarContainer, UNO_QUERY ), |
| mxServiceFactory(xServiceFactory) |
| { |
| } |
| |
| // #110897# |
| const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuDocumentHandler::getServiceFactory() |
| { |
| // #110897# |
| return mxServiceFactory; |
| } |
| |
| OReadMenuDocumentHandler::~OReadMenuDocumentHandler() |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuDocumentHandler::startDocument(void) |
| throw ( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuDocumentHandler::endDocument(void) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_nElementDepth > 0 ) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| |
| |
| void SAL_CALL OReadMenuDocumentHandler::startElement( |
| const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList ) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_bMenuBarMode ) |
| { |
| ++m_nElementDepth; |
| m_xReader->startElement( aName, xAttrList ); |
| } |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR ))) |
| { |
| ++m_nElementDepth; |
| m_bMenuBarMode = sal_True; |
| |
| // #110897# m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory )); |
| m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( getServiceFactory(), m_xMenuBarContainer, m_xContainerFactory )); |
| |
| m_xReader->startDocument(); |
| } |
| } |
| |
| |
| void SAL_CALL OReadMenuDocumentHandler::characters(const rtl::OUString&) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuDocumentHandler::endElement( const ::rtl::OUString& aName ) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_bMenuBarMode ) |
| { |
| --m_nElementDepth; |
| m_xReader->endElement( aName ); |
| if ( 0 == m_nElementDepth ) |
| { |
| m_xReader->endDocument(); |
| m_xReader = Reference< XDocumentHandler >(); |
| m_bMenuBarMode = sal_False; |
| if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR ))) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menubar expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| } |
| } |
| |
| |
| // ----------------------------------------------------------------------------- |
| |
| |
| // #110897# |
| OReadMenuBarHandler::OReadMenuBarHandler( |
| const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, |
| const Reference< XIndexContainer >& rMenuBarContainer, |
| const Reference< XSingleComponentFactory >& rFactory ) |
| : m_nElementDepth( 0 ), |
| m_bMenuMode( sal_False ), |
| m_xMenuBarContainer( rMenuBarContainer ), |
| m_xContainerFactory( rFactory ), |
| mxServiceFactory( xServiceFactory ) |
| { |
| } |
| |
| // #110897# |
| const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuBarHandler::getServiceFactory() |
| { |
| // #110897# |
| return mxServiceFactory; |
| } |
| |
| OReadMenuBarHandler::~OReadMenuBarHandler() |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuBarHandler::startDocument(void) |
| throw ( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuBarHandler::endDocument(void) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuBarHandler::startElement( |
| const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList ) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_bMenuMode ) |
| { |
| ++m_nElementDepth; |
| m_xReader->startElement( rName, xAttrList ); |
| } |
| else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) |
| { |
| ++m_nElementDepth; |
| |
| ::rtl::OUString aHelpId; |
| ::rtl::OUString aCommandId; |
| ::rtl::OUString aLabel; |
| sal_Int16 nItemBits(0); |
| |
| m_bMenuMode = sal_True; |
| |
| // Container must be factory to create sub container |
| Reference< XComponentContext > xComponentContext; |
| Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY ); |
| xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= |
| xComponentContext; |
| |
| Reference< XIndexContainer > xSubItemContainer; |
| if ( m_xContainerFactory.is() ) |
| xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY ); |
| |
| if ( xSubItemContainer.is() ) |
| { |
| // read attributes for menu |
| for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) |
| { |
| ::rtl::OUString aName = xAttrList->getNameByIndex( i ); |
| ::rtl::OUString aValue = xAttrList->getValueByIndex( i ); |
| if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID ))) |
| aCommandId = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL ))) |
| aLabel = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID ))) |
| aHelpId = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE ))) |
| { |
| ::rtl::OUString aTemp( aValue ); |
| sal_Int32 nIndex = 0; |
| do |
| { |
| ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex ); |
| if ( aToken.getLength() > 0 ) |
| { |
| if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; |
| else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; |
| else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; |
| } |
| } |
| while ( nIndex >= 0 ); |
| } |
| } |
| |
| if ( aCommandId.getLength() > 0 ) |
| { |
| Sequence< PropertyValue > aSubMenuProp( 6 ); |
| initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits ); |
| aSubMenuProp[2].Value <<= xSubItemContainer; |
| |
| m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) ); |
| } |
| else |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| |
| m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory )); |
| m_xReader->startDocument(); |
| } |
| } |
| else |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "element menu expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| |
| |
| void SAL_CALL OReadMenuBarHandler::characters(const rtl::OUString&) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void OReadMenuBarHandler::endElement( const ::rtl::OUString& aName ) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_bMenuMode ) |
| { |
| --m_nElementDepth; |
| if ( 0 == m_nElementDepth ) |
| { |
| m_xReader->endDocument(); |
| m_xReader = Reference< XDocumentHandler >(); |
| m_bMenuMode = sal_False; |
| if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| else |
| m_xReader->endElement( aName ); |
| } |
| } |
| |
| |
| // ----------------------------------------------------------------------------- |
| |
| |
| OReadMenuHandler::OReadMenuHandler( |
| const Reference< XIndexContainer >& rMenuContainer, |
| const Reference< XSingleComponentFactory >& rFactory ) : |
| m_nElementDepth( 0 ), |
| m_bMenuPopupMode( sal_False ), |
| m_xMenuContainer( rMenuContainer ), |
| m_xContainerFactory( rFactory ) |
| { |
| } |
| |
| |
| OReadMenuHandler::~OReadMenuHandler() |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuHandler::startDocument(void) |
| throw ( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuHandler::endDocument(void) |
| throw( SAXException, RuntimeException) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuHandler::startElement( |
| const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList ) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_bMenuPopupMode ) |
| { |
| ++m_nElementDepth; |
| m_xReader->startElement( aName, xAttrList ); |
| } |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP ))) |
| { |
| ++m_nElementDepth; |
| m_bMenuPopupMode = sal_True; |
| m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory )); |
| m_xReader->startDocument(); |
| } |
| else |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| |
| |
| void SAL_CALL OReadMenuHandler::characters(const rtl::OUString&) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuHandler::endElement( const ::rtl::OUString& aName ) |
| throw( SAXException, RuntimeException ) |
| { |
| if ( m_bMenuPopupMode ) |
| { |
| --m_nElementDepth; |
| if ( 0 == m_nElementDepth ) |
| { |
| m_xReader->endDocument(); |
| m_xReader = Reference< XDocumentHandler >(); |
| m_bMenuPopupMode = sal_False; |
| if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP ))) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menupopup expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| else |
| m_xReader->endElement( aName ); |
| } |
| } |
| |
| |
| // ----------------------------------------------------------------------------- |
| |
| |
| OReadMenuPopupHandler::OReadMenuPopupHandler( |
| const Reference< XIndexContainer >& rMenuContainer, |
| const Reference< XSingleComponentFactory >& rFactory ) : |
| m_nElementDepth( 0 ), |
| m_bMenuMode( sal_False ), |
| m_xMenuContainer( rMenuContainer ), |
| m_xContainerFactory( rFactory ), |
| m_nNextElementExpected( ELEM_CLOSE_NONE ) |
| { |
| } |
| |
| |
| OReadMenuPopupHandler::~OReadMenuPopupHandler() |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuPopupHandler::startDocument(void) |
| throw ( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuPopupHandler::endDocument(void) |
| throw( SAXException, RuntimeException) |
| { |
| } |
| |
| void SAL_CALL OReadMenuPopupHandler::startElement( |
| const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList ) |
| throw( SAXException, RuntimeException ) |
| { |
| ++m_nElementDepth; |
| |
| if ( m_bMenuMode ) |
| m_xReader->startElement( rName, xAttrList ); |
| else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) |
| { |
| ::rtl::OUString aHelpId; |
| ::rtl::OUString aCommandId; |
| ::rtl::OUString aLabel; |
| sal_Int16 nItemBits(0); |
| |
| m_bMenuMode = sal_True; |
| |
| // Container must be factory to create sub container |
| if ( !m_xComponentContext.is() ) |
| { |
| const Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); |
| m_xComponentContext.set(xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW ); |
| } |
| |
| Reference< XIndexContainer > xSubItemContainer; |
| if ( m_xContainerFactory.is() ) |
| xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY ); |
| |
| // read attributes for menu |
| for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) |
| { |
| ::rtl::OUString aName = xAttrList->getNameByIndex( i ); |
| ::rtl::OUString aValue = xAttrList->getValueByIndex( i ); |
| if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID ))) |
| aCommandId = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL ))) |
| aLabel = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID ))) |
| aHelpId = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE ))) |
| { |
| ::rtl::OUString aTemp( aValue ); |
| sal_Int32 nIndex = 0; |
| do |
| { |
| ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex ); |
| if ( aToken.getLength() > 0 ) |
| { |
| if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; |
| else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; |
| else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; |
| } |
| } |
| while ( nIndex >= 0 ); |
| } |
| |
| } |
| |
| if ( aCommandId.getLength() > 0 ) |
| { |
| Sequence< PropertyValue > aSubMenuProp( 6 ); |
| initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits ); |
| aSubMenuProp[2].Value <<= xSubItemContainer; |
| |
| m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) ); |
| } |
| else |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| |
| m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory )); |
| m_xReader->startDocument(); |
| } |
| else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM ))) |
| { |
| ::rtl::OUString aHelpId; |
| ::rtl::OUString aCommandId; |
| ::rtl::OUString aLabel; |
| sal_Int16 nItemBits(0); |
| // read attributes for menu item |
| for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) |
| { |
| ::rtl::OUString aName = xAttrList->getNameByIndex( i ); |
| ::rtl::OUString aValue = xAttrList->getValueByIndex( i ); |
| if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID ))) |
| aCommandId = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL ))) |
| aLabel = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID ))) |
| aHelpId = aValue; |
| else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE ))) |
| { |
| ::rtl::OUString aTemp( aValue ); |
| sal_Int32 nIndex = 0; |
| do |
| { |
| ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex ); |
| if ( aToken.getLength() > 0 ) |
| { |
| if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; |
| else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; |
| else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) ) |
| nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; |
| } |
| } |
| while ( nIndex >= 0 ); |
| } |
| |
| } |
| |
| if ( aCommandId.getLength() > 0 ) |
| { |
| Sequence< PropertyValue > aMenuItem( 6 ); |
| initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits ); |
| aMenuItem[2].Value <<= Reference< XIndexContainer >(); |
| |
| m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) ); |
| } |
| |
| m_nNextElementExpected = ELEM_CLOSE_MENUITEM; |
| } |
| else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR ))) |
| { |
| Sequence< PropertyValue > aMenuSeparator( 1 ); |
| aMenuSeparator[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )); |
| aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE; |
| |
| m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) ); |
| |
| m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR; |
| } |
| else |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| |
| |
| void SAL_CALL OReadMenuPopupHandler::characters(const rtl::OUString&) |
| throw( SAXException, RuntimeException ) |
| { |
| } |
| |
| |
| void SAL_CALL OReadMenuPopupHandler::endElement( const ::rtl::OUString& aName ) |
| throw( SAXException, RuntimeException ) |
| { |
| --m_nElementDepth; |
| if ( m_bMenuMode ) |
| { |
| if ( 0 == m_nElementDepth ) |
| { |
| m_xReader->endDocument(); |
| m_xReader = Reference< XDocumentHandler >(); |
| m_bMenuMode = sal_False; |
| if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| else |
| m_xReader->endElement( aName ); |
| } |
| else |
| { |
| if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM ) |
| { |
| if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM ))) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuitem expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR ) |
| { |
| if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR ))) |
| { |
| ::rtl::OUString aErrorMessage = getErrorLineString(); |
| aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuseparator expected!" )); |
| throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); |
| } |
| } |
| |
| m_nNextElementExpected = ELEM_CLOSE_NONE; |
| } |
| } |
| |
| |
| // --------------------------------- Write XML --------------------------------- |
| |
| |
| OWriteMenuDocumentHandler::OWriteMenuDocumentHandler( |
| const Reference< XIndexAccess >& rMenuBarContainer, |
| const Reference< XDocumentHandler >& rDocumentHandler ) : |
| m_xMenuBarContainer( rMenuBarContainer ), |
| m_xWriteDocumentHandler( rDocumentHandler ) |
| { |
| ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; |
| m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY ); |
| m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); |
| } |
| |
| |
| OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler() |
| { |
| } |
| |
| |
| void OWriteMenuDocumentHandler::WriteMenuDocument() |
| throw ( SAXException, RuntimeException ) |
| { |
| ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; |
| Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY ); |
| |
| m_xWriteDocumentHandler->startDocument(); |
| |
| // write DOCTYPE line! |
| Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY ); |
| if ( xExtendedDocHandler.is() ) |
| { |
| xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MENUBAR_DOCTYPE )) ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| } |
| |
| pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_MENU )), |
| m_aAttributeType, |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU )) ); |
| |
| pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )), |
| m_aAttributeType, |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "menubar" )) ); |
| |
| m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )), pList ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| |
| WriteMenu( m_xMenuBarContainer ); |
| |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )) ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->endDocument(); |
| } |
| |
| |
| void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer ) |
| throw ( SAXException, RuntimeException ) |
| { |
| sal_Int32 nItemCount = rMenuContainer->getCount(); |
| sal_Bool bSeparator = sal_False; |
| Any aAny; |
| |
| for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ ) |
| { |
| Sequence< PropertyValue > aProps; |
| aAny = rMenuContainer->getByIndex( nItemPos ); |
| if ( aAny >>= aProps ) |
| { |
| ::rtl::OUString aCommandURL; |
| ::rtl::OUString aLabel; |
| ::rtl::OUString aHelpURL; |
| sal_Int16 nType( ::com::sun::star::ui::ItemType::DEFAULT ); |
| sal_Int16 nItemBits( 0 ); |
| Reference< XIndexAccess > xSubMenu; |
| |
| ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits ); |
| if ( xSubMenu.is() ) |
| { |
| if ( aCommandURL.equalsAscii( ADDDIRECT_CMD ) || |
| aCommandURL.equalsAscii( AUTOPILOTMENU_CMD )) |
| { |
| WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits ); |
| bSeparator = sal_False; |
| } |
| else if (( aCommandURL.getLength() > 0 ) && !AddonPopupMenu::IsCommandURLPrefix ( aCommandURL )) |
| { |
| ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList; |
| Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY ); |
| |
| pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )), |
| m_aAttributeType, |
| aCommandURL ); |
| |
| if ( !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL ))) |
| pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )), |
| m_aAttributeType, |
| aLabel ); |
| |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )), xListMenu ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )), m_xEmptyList ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| |
| WriteMenu( xSubMenu ); |
| |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )) ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )) ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| bSeparator = sal_False; |
| } |
| } |
| else |
| { |
| if ( nType == ::com::sun::star::ui::ItemType::DEFAULT ) |
| { |
| if ( aCommandURL.getLength() > 0 ) |
| { |
| bSeparator = sal_False; |
| WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits ); |
| } |
| } |
| else if ( !bSeparator ) |
| { |
| // Don't write two separators together |
| WriteMenuSeparator(); |
| bSeparator = sal_True; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| void OWriteMenuDocumentHandler::WriteMenuItem( const ::rtl::OUString& aCommandURL, const ::rtl::OUString& aLabel, const ::rtl::OUString& aHelpURL, sal_Int16 nStyle ) |
| { |
| ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; |
| Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); |
| |
| pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )), |
| m_aAttributeType, |
| aCommandURL ); |
| |
| if ( aHelpURL.getLength() > 0 ) |
| { |
| pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID )), |
| m_aAttributeType, |
| aHelpURL ); |
| } |
| |
| if (( aLabel.getLength() > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL ))) |
| { |
| pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )), |
| m_aAttributeType, |
| aLabel ); |
| } |
| if (( nStyle > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL ))) |
| { |
| rtl::OUString aValue; |
| MenuStyleItem* pStyle = MenuItemStyles; |
| |
| for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle ) |
| { |
| if ( nStyle & pStyle->nBit ) |
| { |
| if ( aValue.getLength() ) |
| aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("+") ) ); |
| aValue += rtl::OUString::createFromAscii( pStyle->attrName ); |
| } |
| } |
| pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_STYLE )), |
| m_aAttributeType, |
| aValue ); |
| } |
| |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )), xList ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )) ); |
| } |
| |
| |
| void OWriteMenuDocumentHandler::WriteMenuSeparator() |
| { |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )), m_xEmptyList ); |
| m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); |
| m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )) ); |
| } |
| |
| } // namespace framework |
| |