LCOV - code coverage report
Current view: top level - framework/source/fwe/xml - menudocumenthandler.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 222 430 51.6 %
Date: 2015-06-13 12:38:46 Functions: 31 48 64.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <stdio.h>
      21             : #include <sal/macros.h>
      22             : 
      23             : #include <xml/menudocumenthandler.hxx>
      24             : #include <framework/menuconfiguration.hxx>
      25             : #include <framework/addonmenu.hxx>
      26             : 
      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>
      32             : 
      33             : #include <comphelper/processfactory.hxx>
      34             : #include <comphelper/attributelist.hxx>
      35             : 
      36             : #define XMLNS_MENU                  "http://openoffice.org/2001/menu"
      37             : 
      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"
      43             : 
      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"
      49             : 
      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"
      54             : 
      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"
      59             : 
      60             : #define ATTRIBUTE_XMLNS_MENU        "xmlns:menu"
      61             : 
      62             : #define ATTRIBUTE_TYPE_CDATA        "CDATA"
      63             : 
      64             : #define MENUBAR_DOCTYPE             "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">"
      65             : 
      66             : #define ATTRIBUTE_ITEMSTYLE_TEXT    "text"
      67             : #define ATTRIBUTE_ITEMSTYLE_IMAGE    "image"
      68             : #define ATTRIBUTE_ITEMSTYLE_RADIO    "radio"
      69             : 
      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";
      77             : 
      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";
      83             : 
      84             : //  using namespaces
      85             : 
      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;
      92             : 
      93             : namespace framework
      94             : {
      95             : 
      96             : struct MenuStyleItem
      97             : {
      98             :     sal_Int16 nBit;
      99             :     const char* attrName;
     100             : };
     101             : 
     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 }
     106             : };
     107             : 
     108             : sal_Int32 nMenuStyleItemEntries = (sizeof (MenuItemStyles) / sizeof (MenuItemStyles[0]));
     109             : 
     110           0 : 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 )
     117             : {
     118           0 :     for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
     119             :     {
     120           0 :         if ( rProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
     121             :         {
     122           0 :             rProp[i].Value >>= rCommandURL;
     123           0 :             rCommandURL = rCommandURL.intern();
     124             :         }
     125           0 :         else if ( rProp[i].Name == ITEM_DESCRIPTOR_HELPURL )
     126             :         {
     127           0 :             rProp[i].Value >>= rHelpURL;
     128             :         }
     129           0 :         else if ( rProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
     130             :         {
     131           0 :             rProp[i].Value >>= rSubMenu;
     132             :         }
     133           0 :         else if ( rProp[i].Name == ITEM_DESCRIPTOR_LABEL )
     134             :         {
     135           0 :             rProp[i].Value >>= rLabel;
     136             :         }
     137           0 :         else if ( rProp[i].Name == ITEM_DESCRIPTOR_TYPE )
     138             :         {
     139           0 :             rProp[i].Value >>= rType;
     140             :         }
     141           0 :         else if ( rProp[i].Name == ITEM_DESCRIPTOR_STYLE )
     142             :         {
     143           0 :             rProp[i].Value >>= rStyle;
     144             :         }
     145             :     }
     146           0 : }
     147             : 
     148             : // Base class implementation
     149             : 
     150        5499 : ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() :
     151             :     m_xLocator( 0 ),
     152             :     m_xReader( 0 ),
     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        5499 :     m_aStyle( ITEM_DESCRIPTOR_STYLE )
     159             : {
     160        5499 : }
     161             : 
     162        5499 : ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
     163             : {
     164        5499 : }
     165             : 
     166           0 : void SAL_CALL ReadMenuDocumentHandlerBase::ignorableWhitespace(
     167             :     const OUString& )
     168             : throw( SAXException, RuntimeException, std::exception )
     169             : {
     170           0 : }
     171             : 
     172           0 : void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction(
     173             :     const OUString& /*aTarget*/, const OUString& /*aData*/ )
     174             : throw( SAXException, RuntimeException, std::exception )
     175             : {
     176           0 : }
     177             : 
     178          61 : void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
     179             :     const Reference< XLocator > &xLocator)
     180             : throw(  SAXException, RuntimeException, std::exception )
     181             : {
     182          61 :     m_xLocator = xLocator;
     183          61 : }
     184             : 
     185           0 : OUString ReadMenuDocumentHandlerBase::getErrorLineString()
     186             : {
     187           0 :     if ( m_xLocator.is() )
     188             :     {
     189             :         char buffer[32];
     190           0 :         snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
     191           0 :         return OUString::createFromAscii( buffer );
     192             :     }
     193             :     else
     194           0 :         return OUString();
     195             : }
     196             : 
     197       21113 : void ReadMenuDocumentHandlerBase::initPropertyCommon(
     198             :     Sequence< PropertyValue > &rProps, const OUString &rCommandURL,
     199             :     const OUString &rHelpId, const OUString &rLabel, sal_Int16 nItemStyleBits )
     200             : {
     201       21113 :     rProps[0].Name = m_aCommandURL;
     202       21113 :     rProps[1].Name = m_aHelpURL;
     203       21113 :     rProps[2].Name = m_aContainer;
     204       21113 :     rProps[3].Name = m_aLabel;
     205       21113 :     rProps[4].Name = m_aStyle;
     206       21113 :     rProps[5].Name = m_aType;
     207             : 
     208             :     // Common values
     209       21113 :     rProps[0].Value <<= rCommandURL.intern();
     210       21113 :     rProps[1].Value <<= rHelpId;
     211       21113 :     rProps[2].Value <<= Reference< XIndexContainer >();
     212       21113 :     rProps[3].Value <<= rLabel;
     213       21113 :     rProps[4].Value <<= nItemStyleBits;
     214       21113 :     rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
     215       21113 : }
     216             : 
     217          61 : OReadMenuDocumentHandler::OReadMenuDocumentHandler(
     218             :     const Reference< XIndexContainer >& rMenuBarContainer )
     219             : :   m_nElementDepth( 0 ),
     220             :     m_bMenuBarMode( false ),
     221             :     m_xMenuBarContainer( rMenuBarContainer ),
     222          61 :     m_xContainerFactory( rMenuBarContainer, UNO_QUERY )
     223             : {
     224          61 : }
     225             : 
     226         122 : OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
     227             : {
     228         122 : }
     229             : 
     230           0 : void SAL_CALL OReadMenuDocumentHandler::startDocument()
     231             :     throw ( SAXException, RuntimeException, std::exception )
     232             : {
     233           0 : }
     234             : 
     235           0 : void SAL_CALL OReadMenuDocumentHandler::endDocument()
     236             :     throw( SAXException, RuntimeException, std::exception )
     237             : {
     238           0 :     if ( m_nElementDepth > 0 )
     239             :     {
     240           0 :         OUString aErrorMessage = getErrorLineString();
     241           0 :         aErrorMessage += "A closing element is missing!";
     242           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     243             :     }
     244           0 : }
     245             : 
     246       27863 : void SAL_CALL OReadMenuDocumentHandler::startElement(
     247             :     const OUString& aName, const Reference< XAttributeList > &xAttrList )
     248             : throw( SAXException, RuntimeException, std::exception )
     249             : {
     250       27863 :     if ( m_bMenuBarMode )
     251             :     {
     252       27802 :         ++m_nElementDepth;
     253       27802 :         m_xReader->startElement( aName, xAttrList );
     254             :     }
     255          61 :     else if ( aName == ELEMENT_MENUBAR )
     256             :     {
     257          61 :         ++m_nElementDepth;
     258          61 :         m_bMenuBarMode = true;
     259          61 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory ));
     260             : 
     261          61 :         m_xReader->startDocument();
     262             :     }
     263       27863 : }
     264             : 
     265       66338 : void SAL_CALL OReadMenuDocumentHandler::characters(const OUString&)
     266             : throw(  SAXException, RuntimeException, std::exception )
     267             : {
     268       66338 : }
     269             : 
     270       27863 : void SAL_CALL OReadMenuDocumentHandler::endElement( const OUString& aName )
     271             :     throw( SAXException, RuntimeException, std::exception )
     272             : {
     273       27863 :     if ( m_bMenuBarMode )
     274             :     {
     275       27863 :         --m_nElementDepth;
     276       27863 :         m_xReader->endElement( aName );
     277       27863 :         if ( 0 == m_nElementDepth )
     278             :         {
     279          61 :             m_xReader->endDocument();
     280          61 :             m_xReader.clear();
     281          61 :             m_bMenuBarMode = false;
     282          61 :             if ( aName != ELEMENT_MENUBAR )
     283             :             {
     284           0 :                 OUString aErrorMessage = getErrorLineString();
     285           0 :                 aErrorMessage += "closing element menubar expected!";
     286           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     287             :             }
     288             :         }
     289             :     }
     290       27863 : }
     291             : 
     292          61 : 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          61 :       m_xContainerFactory( rFactory )
     299             : {
     300          61 : }
     301             : 
     302         122 : OReadMenuBarHandler::~OReadMenuBarHandler()
     303             : {
     304         122 : }
     305             : 
     306          61 : void SAL_CALL OReadMenuBarHandler::startDocument()
     307             :     throw ( SAXException, RuntimeException, std::exception )
     308             : {
     309          61 : }
     310             : 
     311          61 : void SAL_CALL OReadMenuBarHandler::endDocument()
     312             :     throw( SAXException, RuntimeException, std::exception )
     313             : {
     314          61 : }
     315             : 
     316       27802 : void SAL_CALL OReadMenuBarHandler::startElement(
     317             :     const OUString& rName, const Reference< XAttributeList > &xAttrList )
     318             : throw( SAXException, RuntimeException, std::exception )
     319             : {
     320       27802 :     if ( m_bMenuMode )
     321             :     {
     322       27251 :         ++m_nElementDepth;
     323       27251 :         m_xReader->startElement( rName, xAttrList );
     324             :     }
     325         551 :     else if ( rName == ELEMENT_MENU )
     326             :     {
     327         551 :         ++m_nElementDepth;
     328             : 
     329         551 :         OUString aHelpId;
     330        1102 :         OUString aCommandId;
     331        1102 :         OUString aLabel;
     332         551 :         sal_Int16 nItemBits(0);
     333             : 
     334         551 :         m_bMenuMode = true;
     335             : 
     336             :         // Container must be factory to create sub container
     337             :         Reference< XComponentContext > xComponentContext(
     338        1102 :             comphelper::getProcessComponentContext() );
     339             : 
     340        1102 :         Reference< XIndexContainer > xSubItemContainer;
     341         551 :         if ( m_xContainerFactory.is() )
     342         551 :             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
     343             : 
     344         551 :         if ( xSubItemContainer.is() )
     345             :         {
     346             :             // read attributes for menu
     347        1109 :             for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     348             :             {
     349         558 :                 OUString aName = xAttrList->getNameByIndex( i );
     350        1116 :                 OUString aValue = xAttrList->getValueByIndex( i );
     351         558 :                 if ( aName == ATTRIBUTE_ID )
     352         551 :                     aCommandId = aValue;
     353           7 :                 else if ( aName == ATTRIBUTE_LABEL )
     354           7 :                     aLabel = aValue;
     355           0 :                 else if ( aName == ATTRIBUTE_HELPID )
     356           0 :                     aHelpId = aValue;
     357           0 :                 else if ( aName == ATTRIBUTE_STYLE )
     358             :                 {
     359           0 :                     OUString aTemp( aValue );
     360           0 :                     sal_Int32 nIndex = 0;
     361           0 :                     do
     362             :                     {
     363           0 :                         OUString aToken = aTemp.getToken( 0, '+', nIndex );
     364           0 :                         if ( !aToken.isEmpty() )
     365             :                         {
     366           0 :                             if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     367           0 :                                 nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     368           0 :                             else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     369           0 :                                 nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     370           0 :                             else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     371           0 :                                 nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     372           0 :                         }
     373             :                     }
     374           0 :                     while ( nIndex >= 0 );
     375             :                 }
     376         558 :             }
     377             : 
     378         551 :             if ( !aCommandId.isEmpty() )
     379             :             {
     380         551 :                 Sequence< PropertyValue > aSubMenuProp( 6 );
     381         551 :                 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
     382         551 :                 aSubMenuProp[2].Value <<= xSubItemContainer;
     383             : 
     384         551 :                 m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) );
     385             :             }
     386             :             else
     387             :             {
     388           0 :                 OUString aErrorMessage = getErrorLineString();
     389           0 :                 aErrorMessage += "attribute id for element menu required!";
     390           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     391             :             }
     392             : 
     393         551 :             m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
     394         551 :             m_xReader->startDocument();
     395         551 :         }
     396             :     }
     397             :     else
     398             :     {
     399           0 :         OUString aErrorMessage = getErrorLineString();
     400           0 :         aErrorMessage += "element menu expected!";
     401           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     402             :     }
     403       27802 : }
     404             : 
     405           0 : void SAL_CALL OReadMenuBarHandler::characters(const OUString&)
     406             : throw(  SAXException, RuntimeException, std::exception )
     407             : {
     408           0 : }
     409             : 
     410       27863 : void OReadMenuBarHandler::endElement( const OUString& aName )
     411             :     throw( SAXException, RuntimeException, std::exception )
     412             : {
     413       27863 :     if ( m_bMenuMode )
     414             :     {
     415       27802 :         --m_nElementDepth;
     416       27802 :         if ( 0 == m_nElementDepth )
     417             :         {
     418         551 :             m_xReader->endDocument();
     419         551 :             m_xReader.clear();
     420         551 :             m_bMenuMode = false;
     421         551 :             if ( aName != ELEMENT_MENU )
     422             :             {
     423           0 :                 OUString aErrorMessage = getErrorLineString();
     424           0 :                 aErrorMessage += "closing element menu expected!";
     425           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     426             :             }
     427             :         }
     428             :         else
     429       27251 :             m_xReader->endElement( aName );
     430             :     }
     431       27863 : }
     432             : 
     433        2719 : 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        2719 :     m_xContainerFactory( rFactory )
     440             : {
     441        2719 : }
     442             : 
     443        5438 : OReadMenuHandler::~OReadMenuHandler()
     444             : {
     445        5438 : }
     446             : 
     447        2719 : void SAL_CALL OReadMenuHandler::startDocument()
     448             :     throw ( SAXException, RuntimeException, std::exception )
     449             : {
     450        2719 : }
     451             : 
     452        2719 : void SAL_CALL OReadMenuHandler::endDocument()
     453             :     throw( SAXException, RuntimeException, std::exception)
     454             : {
     455        2719 : }
     456             : 
     457       43085 : void SAL_CALL OReadMenuHandler::startElement(
     458             :     const OUString& aName, const Reference< XAttributeList > &xAttrList )
     459             : throw( SAXException, RuntimeException, std::exception )
     460             : {
     461       43085 :     if ( m_bMenuPopupMode )
     462             :     {
     463       40427 :         ++m_nElementDepth;
     464       40427 :         m_xReader->startElement( aName, xAttrList );
     465             :     }
     466        2658 :     else if ( aName == ELEMENT_MENUPOPUP )
     467             :     {
     468        2658 :         ++m_nElementDepth;
     469        2658 :         m_bMenuPopupMode = true;
     470        2658 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
     471        2658 :         m_xReader->startDocument();
     472             :     }
     473             :     else
     474             :     {
     475           0 :         OUString aErrorMessage = getErrorLineString();
     476           0 :         aErrorMessage += "unknown element found!";
     477           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     478             :     }
     479       43085 : }
     480             : 
     481           0 : void SAL_CALL OReadMenuHandler::characters(const OUString&)
     482             : throw(  SAXException, RuntimeException, std::exception )
     483             : {
     484           0 : }
     485             : 
     486       43085 : void SAL_CALL OReadMenuHandler::endElement( const OUString& aName )
     487             :     throw( SAXException, RuntimeException, std::exception )
     488             : {
     489       43085 :     if ( m_bMenuPopupMode )
     490             :     {
     491       43085 :         --m_nElementDepth;
     492       43085 :         if ( 0 == m_nElementDepth )
     493             :         {
     494        2658 :             m_xReader->endDocument();
     495        2658 :             m_xReader.clear();
     496        2658 :             m_bMenuPopupMode = false;
     497        2658 :             if ( aName != ELEMENT_MENUPOPUP )
     498             :             {
     499           0 :                 OUString aErrorMessage = getErrorLineString();
     500           0 :                 aErrorMessage += "closing element menupopup expected!";
     501           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     502             :             }
     503             :         }
     504             :         else
     505       40427 :             m_xReader->endElement( aName );
     506             :     }
     507       43085 : }
     508             : 
     509        2658 : 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        2658 :     m_nNextElementExpected( ELEM_CLOSE_NONE )
     518             : {
     519        2658 : }
     520             : 
     521        5316 : OReadMenuPopupHandler::~OReadMenuPopupHandler()
     522             : {
     523        5316 : }
     524             : 
     525        2658 : void SAL_CALL OReadMenuPopupHandler::startDocument()
     526             :     throw ( SAXException, RuntimeException, std::exception )
     527             : {
     528        2658 : }
     529             : 
     530        2658 : void SAL_CALL OReadMenuPopupHandler::endDocument()
     531             :     throw( SAXException, RuntimeException, std::exception)
     532             : {
     533        2658 : }
     534             : 
     535       40427 : void SAL_CALL OReadMenuPopupHandler::startElement(
     536             :     const OUString& rName, const Reference< XAttributeList > &xAttrList )
     537             : throw( SAXException, RuntimeException, std::exception )
     538             : {
     539       40427 :     ++m_nElementDepth;
     540             : 
     541       40427 :     if ( m_bMenuMode )
     542       15834 :         m_xReader->startElement( rName, xAttrList );
     543       24593 :     else if ( rName == ELEMENT_MENU )
     544             :     {
     545        2168 :         OUString aHelpId;
     546        4336 :         OUString aCommandId;
     547        4336 :         OUString aLabel;
     548        2168 :         sal_Int16 nItemBits(0);
     549             : 
     550        2168 :         m_bMenuMode = true;
     551             : 
     552             :         // Container must be factory to create sub container
     553        4336 :         Reference< XIndexContainer > xSubItemContainer;
     554        2168 :         if ( m_xContainerFactory.is() )
     555        2168 :             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
     556             : 
     557             :         // read attributes for menu
     558        4342 :         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     559             :         {
     560        2174 :             OUString aName = xAttrList->getNameByIndex( i );
     561        4348 :             OUString aValue = xAttrList->getValueByIndex( i );
     562        2174 :             if ( aName == ATTRIBUTE_ID )
     563        2168 :                 aCommandId = aValue;
     564           6 :             else if ( aName == ATTRIBUTE_LABEL )
     565           6 :                 aLabel = aValue;
     566           0 :             else if ( aName == ATTRIBUTE_HELPID )
     567           0 :                 aHelpId = aValue;
     568           0 :             else if ( aName == ATTRIBUTE_STYLE )
     569             :             {
     570           0 :                 OUString aTemp( aValue );
     571           0 :                 sal_Int32 nIndex = 0;
     572           0 :                 do
     573             :                 {
     574           0 :                     OUString aToken = aTemp.getToken( 0, '+', nIndex );
     575           0 :                     if ( !aToken.isEmpty() )
     576             :                     {
     577           0 :                         if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     578           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     579           0 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     580           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     581           0 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     582           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     583           0 :                     }
     584             :                 }
     585           0 :                 while ( nIndex >= 0 );
     586             :             }
     587             : 
     588        2174 :         }
     589             : 
     590        2168 :         if ( !aCommandId.isEmpty() )
     591             :         {
     592        2168 :             Sequence< PropertyValue > aSubMenuProp( 6 );
     593        2168 :             initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
     594        2168 :             aSubMenuProp[2].Value <<= xSubItemContainer;
     595             : 
     596        2168 :             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) );
     597             :         }
     598             :         else
     599             :         {
     600           0 :             OUString aErrorMessage = getErrorLineString();
     601           0 :             aErrorMessage += "attribute id for element menu required!";
     602           0 :             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     603             :         }
     604             : 
     605        2168 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
     606        4336 :         m_xReader->startDocument();
     607             :     }
     608       22425 :     else if ( rName == ELEMENT_MENUITEM )
     609             :     {
     610       18394 :         OUString aHelpId;
     611       36788 :         OUString aCommandId;
     612       36788 :         OUString aLabel;
     613       18394 :         sal_Int16 nItemBits(0);
     614             :         // read attributes for menu item
     615       37625 :         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     616             :         {
     617       19231 :             OUString aName = xAttrList->getNameByIndex( i );
     618       38462 :             OUString aValue = xAttrList->getValueByIndex( i );
     619       19231 :             if ( aName == ATTRIBUTE_ID )
     620       18394 :                 aCommandId = aValue;
     621         837 :             else if ( aName == ATTRIBUTE_LABEL )
     622          76 :                 aLabel = aValue;
     623         761 :             else if ( aName == ATTRIBUTE_HELPID )
     624           1 :                 aHelpId = aValue;
     625         760 :             else if ( aName == ATTRIBUTE_STYLE )
     626             :             {
     627         760 :                 OUString aTemp( aValue );
     628         760 :                 sal_Int32 nIndex = 0;
     629         760 :                 do
     630             :                 {
     631         760 :                     OUString aToken = aTemp.getToken( 0, '+', nIndex );
     632         760 :                     if ( !aToken.isEmpty() )
     633             :                     {
     634         760 :                         if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     635           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     636         760 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     637           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     638         760 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     639         760 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     640         760 :                     }
     641             :                 }
     642        1520 :                 while ( nIndex >= 0 );
     643             :             }
     644             : 
     645       19231 :         }
     646             : 
     647       18394 :         if ( !aCommandId.isEmpty() )
     648             :         {
     649       18394 :             Sequence< PropertyValue > aMenuItem( 6 );
     650       18394 :             initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
     651       18394 :             aMenuItem[2].Value <<= Reference< XIndexContainer >();
     652             : 
     653       18394 :             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
     654             :         }
     655             : 
     656       36788 :         m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
     657             :     }
     658        4031 :     else if ( rName == ELEMENT_MENUSEPARATOR )
     659             :     {
     660        4031 :         Sequence< PropertyValue > aMenuSeparator( 1 );
     661        4031 :         aMenuSeparator[0].Name = ITEM_DESCRIPTOR_TYPE;
     662        4031 :         aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
     663             : 
     664        4031 :         m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
     665             : 
     666        4031 :         m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR;
     667             :     }
     668             :     else
     669             :     {
     670           0 :         OUString aErrorMessage = getErrorLineString();
     671           0 :         aErrorMessage += "unknown element found!";
     672           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     673             :     }
     674       40427 : }
     675             : 
     676           0 : void SAL_CALL OReadMenuPopupHandler::characters(const OUString&)
     677             : throw(  SAXException, RuntimeException, std::exception )
     678             : {
     679           0 : }
     680             : 
     681       40427 : void SAL_CALL OReadMenuPopupHandler::endElement( const OUString& aName )
     682             :     throw( SAXException, RuntimeException, std::exception )
     683             : {
     684       40427 :     --m_nElementDepth;
     685       40427 :     if ( m_bMenuMode )
     686             :     {
     687       18002 :         if ( 0 == m_nElementDepth )
     688             :         {
     689        2168 :             m_xReader->endDocument();
     690        2168 :             m_xReader.clear();
     691        2168 :             m_bMenuMode = false;
     692        2168 :             if ( aName != ELEMENT_MENU )
     693             :             {
     694           0 :                 OUString aErrorMessage = getErrorLineString();
     695           0 :                 aErrorMessage += "closing element menu expected!";
     696           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     697             :             }
     698             :         }
     699             :         else
     700       15834 :             m_xReader->endElement( aName );
     701             :     }
     702             :     else
     703             :     {
     704       22425 :         if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
     705             :         {
     706       18394 :             if ( aName != ELEMENT_MENUITEM )
     707             :             {
     708           0 :                 OUString aErrorMessage = getErrorLineString();
     709           0 :                 aErrorMessage += "closing element menuitem expected!";
     710           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     711             :             }
     712             :         }
     713        4031 :         else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
     714             :         {
     715        4031 :             if ( aName != ELEMENT_MENUSEPARATOR )
     716             :             {
     717           0 :                 OUString aErrorMessage = getErrorLineString();
     718           0 :                 aErrorMessage += "closing element menuseparator expected!";
     719           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     720             :             }
     721             :         }
     722             : 
     723       22425 :         m_nNextElementExpected = ELEM_CLOSE_NONE;
     724             :     }
     725       40427 : }
     726             : 
     727             : // --------------------------------- Write XML ---------------------------------
     728             : 
     729           0 : OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
     730             :     const Reference< XIndexAccess >& rMenuBarContainer,
     731             :     const Reference< XDocumentHandler >& rDocumentHandler ) :
     732             :     m_xMenuBarContainer( rMenuBarContainer ),
     733           0 :     m_xWriteDocumentHandler( rDocumentHandler )
     734             : {
     735           0 :     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
     736           0 :     m_xEmptyList = Reference< XAttributeList >( static_cast<XAttributeList *>(pList), UNO_QUERY );
     737           0 :     m_aAttributeType = ATTRIBUTE_TYPE_CDATA;
     738           0 : }
     739             : 
     740           0 : OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
     741             : {
     742           0 : }
     743             : 
     744           0 : void OWriteMenuDocumentHandler::WriteMenuDocument()
     745             : throw ( SAXException, RuntimeException )
     746             : {
     747           0 :     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
     748           0 :     Reference< XAttributeList > rList( static_cast<XAttributeList *>(pList) , UNO_QUERY );
     749             : 
     750           0 :     m_xWriteDocumentHandler->startDocument();
     751             : 
     752             :     // write DOCTYPE line!
     753           0 :     Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
     754           0 :     if ( xExtendedDocHandler.is() )
     755             :     {
     756           0 :         xExtendedDocHandler->unknown( OUString( MENUBAR_DOCTYPE ) );
     757           0 :         m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     758             :     }
     759             : 
     760             :     pList->AddAttribute( OUString( ATTRIBUTE_XMLNS_MENU ),
     761             :                          m_aAttributeType,
     762           0 :                          OUString( XMLNS_MENU ) );
     763             : 
     764             :     pList->AddAttribute( OUString( ATTRIBUTE_NS_ID ),
     765             :                          m_aAttributeType,
     766           0 :                          OUString( "menubar" ) );
     767             : 
     768           0 :     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUBAR ), pList );
     769           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     770             : 
     771           0 :     WriteMenu( m_xMenuBarContainer );
     772             : 
     773           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     774           0 :     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUBAR ) );
     775           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     776           0 :     m_xWriteDocumentHandler->endDocument();
     777           0 : }
     778             : 
     779           0 : void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
     780             : throw ( SAXException, RuntimeException )
     781             : {
     782           0 :     sal_Int32  nItemCount = rMenuContainer->getCount();
     783           0 :     bool   bSeparator = false;
     784           0 :     Any        aAny;
     785             : 
     786           0 :     for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
     787             :     {
     788           0 :         Sequence< PropertyValue > aProps;
     789           0 :         aAny = rMenuContainer->getByIndex( nItemPos );
     790           0 :         if ( aAny >>= aProps )
     791             :         {
     792           0 :             OUString    aCommandURL;
     793           0 :             OUString    aLabel;
     794           0 :             OUString    aHelpURL;
     795           0 :             sal_Int16   nType( ::com::sun::star::ui::ItemType::DEFAULT );
     796           0 :             sal_Int16   nItemBits( 0 );
     797           0 :             Reference< XIndexAccess > xSubMenu;
     798             : 
     799           0 :             ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits );
     800           0 :             if ( xSubMenu.is() )
     801             :             {
     802           0 :                 if ( aCommandURL == ADDDIRECT_CMD ||
     803           0 :                     aCommandURL == AUTOPILOTMENU_CMD )
     804             :                 {
     805           0 :                     WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
     806           0 :                     bSeparator = false;
     807             :                 }
     808           0 :                 else if ( !aCommandURL.isEmpty() && !AddonPopupMenu::IsCommandURLPrefix( aCommandURL ))
     809             :                 {
     810           0 :                     ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList;
     811           0 :                     Reference< XAttributeList > xListMenu( static_cast<XAttributeList *>(pListMenu) , UNO_QUERY );
     812             : 
     813             :                     pListMenu->AddAttribute( OUString( ATTRIBUTE_NS_ID ),
     814             :                                             m_aAttributeType,
     815           0 :                                             aCommandURL );
     816             : 
     817           0 :                     if ( aCommandURL.copy( CMD_PROTOCOL_SIZE ) != CMD_PROTOCOL )
     818             :                         pListMenu->AddAttribute( OUString( ATTRIBUTE_NS_LABEL ),
     819             :                                                  m_aAttributeType,
     820           0 :                                                  aLabel );
     821             : 
     822           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     823           0 :                     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENU ), xListMenu );
     824           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     825           0 :                     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUPOPUP ), m_xEmptyList );
     826           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     827             : 
     828           0 :                     WriteMenu( xSubMenu );
     829             : 
     830           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     831           0 :                     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUPOPUP ) );
     832           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     833           0 :                     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENU ) );
     834           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     835           0 :                     bSeparator = false;
     836             :                 }
     837             :             }
     838             :             else
     839             :             {
     840           0 :                 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
     841             :                 {
     842           0 :                     if ( !aCommandURL.isEmpty() )
     843             :                     {
     844           0 :                         bSeparator = false;
     845           0 :                         WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
     846             :                     }
     847             :                 }
     848           0 :                 else if ( !bSeparator )
     849             :                 {
     850             :                     // Don't write two separators together
     851           0 :                     WriteMenuSeparator();
     852           0 :                     bSeparator = true;
     853             :                 }
     854           0 :             }
     855             :         }
     856           0 :     }
     857           0 : }
     858             : 
     859           0 : void OWriteMenuDocumentHandler::WriteMenuItem( const OUString& aCommandURL, const OUString& aLabel, const OUString& aHelpURL, sal_Int16 nStyle )
     860             : {
     861           0 :     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
     862           0 :     Reference< XAttributeList > xList( static_cast<XAttributeList *>(pList) , UNO_QUERY );
     863             : 
     864             :     pList->AddAttribute( OUString( ATTRIBUTE_NS_ID ),
     865             :                                 m_aAttributeType,
     866           0 :                                 aCommandURL );
     867             : 
     868           0 :     if ( !aHelpURL.isEmpty() )
     869             :     {
     870             :         pList->AddAttribute( OUString( ATTRIBUTE_NS_HELPID ),
     871             :                              m_aAttributeType,
     872           0 :                              aHelpURL );
     873             :     }
     874             : 
     875           0 :     if ( !aLabel.isEmpty() && aCommandURL.copy( CMD_PROTOCOL_SIZE ) != CMD_PROTOCOL )
     876             :     {
     877             :         pList->AddAttribute( OUString( ATTRIBUTE_NS_LABEL ),
     878             :                                 m_aAttributeType,
     879           0 :                                 aLabel );
     880             :     }
     881           0 :     if (( nStyle > 0 ) && aCommandURL.copy( CMD_PROTOCOL_SIZE ) != CMD_PROTOCOL )
     882             :     {
     883           0 :         OUString aValue;
     884           0 :         MenuStyleItem* pStyle = MenuItemStyles;
     885             : 
     886           0 :         for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle )
     887             :         {
     888           0 :             if ( nStyle & pStyle->nBit )
     889             :             {
     890           0 :                 if ( !aValue.isEmpty() )
     891           0 :                     aValue = aValue.concat( OUString( "+" ) );
     892           0 :                 aValue += OUString::createFromAscii( pStyle->attrName );
     893             :             }
     894             :         }
     895             :         pList->AddAttribute( OUString( ATTRIBUTE_NS_STYLE ),
     896             :                                 m_aAttributeType,
     897           0 :                                 aValue );
     898             :     }
     899             : 
     900           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     901           0 :     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUITEM ), xList );
     902           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     903           0 :     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUITEM ) );
     904           0 : }
     905             : 
     906           0 : void OWriteMenuDocumentHandler::WriteMenuSeparator()
     907             : {
     908           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     909           0 :     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUSEPARATOR ), m_xEmptyList );
     910           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     911           0 :     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUSEPARATOR ) );
     912           0 : }
     913             : 
     914             : } // namespace framework
     915             : 
     916             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11