LCOV - code coverage report
Current view: top level - framework/source/fwe/xml - menudocumenthandler.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 222 430 51.6 %
Date: 2014-04-11 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        3421 : 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        3421 :     m_aStyle( ITEM_DESCRIPTOR_STYLE )
     159             : {
     160        3421 : }
     161             : 
     162        3421 : ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
     163             : {
     164        3421 : }
     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          49 : void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
     179             :     const Reference< XLocator > &xLocator)
     180             : throw(  SAXException, RuntimeException, std::exception )
     181             : {
     182          49 :     m_xLocator = xLocator;
     183          49 : }
     184             : 
     185           0 : OUString ReadMenuDocumentHandlerBase::getErrorLineString()
     186             : {
     187             :     char buffer[32];
     188             : 
     189           0 :     if ( m_xLocator.is() )
     190             :     {
     191           0 :         snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
     192           0 :         return OUString::createFromAscii( buffer );
     193             :     }
     194             :     else
     195           0 :         return OUString();
     196             : }
     197             : 
     198       13062 : void ReadMenuDocumentHandlerBase::initPropertyCommon(
     199             :     Sequence< PropertyValue > &rProps, const OUString &rCommandURL,
     200             :     const OUString &rHelpId, const OUString &rLabel, sal_Int16 nItemStyleBits )
     201             : {
     202       13062 :     rProps[0].Name = m_aCommandURL;
     203       13062 :     rProps[1].Name = m_aHelpURL;
     204       13062 :     rProps[2].Name = m_aContainer;
     205       13062 :     rProps[3].Name = m_aLabel;
     206       13062 :     rProps[4].Name = m_aStyle;
     207       13062 :     rProps[5].Name = m_aType;
     208             : 
     209             :     // Common values
     210       13062 :     rProps[0].Value <<= rCommandURL.intern();
     211       13062 :     rProps[1].Value <<= rHelpId;
     212       13062 :     rProps[2].Value <<= Reference< XIndexContainer >();
     213       13062 :     rProps[3].Value <<= rLabel;
     214       13062 :     rProps[4].Value <<= nItemStyleBits;
     215       13062 :     rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
     216       13062 : }
     217             : 
     218          49 : OReadMenuDocumentHandler::OReadMenuDocumentHandler(
     219             :     const Reference< XIndexContainer >& rMenuBarContainer )
     220             : :   m_nElementDepth( 0 ),
     221             :     m_bMenuBarMode( false ),
     222             :     m_xMenuBarContainer( rMenuBarContainer ),
     223          49 :     m_xContainerFactory( rMenuBarContainer, UNO_QUERY )
     224             : {
     225          49 : }
     226             : 
     227          98 : OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
     228             : {
     229          98 : }
     230             : 
     231           0 : void SAL_CALL OReadMenuDocumentHandler::startDocument(void)
     232             :     throw ( SAXException, RuntimeException, std::exception )
     233             : {
     234           0 : }
     235             : 
     236           0 : void SAL_CALL OReadMenuDocumentHandler::endDocument(void)
     237             :     throw( SAXException, RuntimeException, std::exception )
     238             : {
     239           0 :     if ( m_nElementDepth > 0 )
     240             :     {
     241           0 :         OUString aErrorMessage = getErrorLineString();
     242           0 :         aErrorMessage += "A closing element is missing!";
     243           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     244             :     }
     245           0 : }
     246             : 
     247       17035 : void SAL_CALL OReadMenuDocumentHandler::startElement(
     248             :     const OUString& aName, const Reference< XAttributeList > &xAttrList )
     249             : throw( SAXException, RuntimeException, std::exception )
     250             : {
     251       17035 :     if ( m_bMenuBarMode )
     252             :     {
     253       16986 :         ++m_nElementDepth;
     254       16986 :         m_xReader->startElement( aName, xAttrList );
     255             :     }
     256          49 :     else if ( aName == ELEMENT_MENUBAR )
     257             :     {
     258          49 :         ++m_nElementDepth;
     259          49 :         m_bMenuBarMode = true;
     260          49 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory ));
     261             : 
     262          49 :         m_xReader->startDocument();
     263             :     }
     264       17035 : }
     265             : 
     266       40637 : void SAL_CALL OReadMenuDocumentHandler::characters(const OUString&)
     267             : throw(  SAXException, RuntimeException, std::exception )
     268             : {
     269       40637 : }
     270             : 
     271       17035 : void SAL_CALL OReadMenuDocumentHandler::endElement( const OUString& aName )
     272             :     throw( SAXException, RuntimeException, std::exception )
     273             : {
     274       17035 :     if ( m_bMenuBarMode )
     275             :     {
     276       17035 :         --m_nElementDepth;
     277       17035 :         m_xReader->endElement( aName );
     278       17035 :         if ( 0 == m_nElementDepth )
     279             :         {
     280          49 :             m_xReader->endDocument();
     281          49 :             m_xReader.clear();
     282          49 :             m_bMenuBarMode = false;
     283          49 :             if ( aName != ELEMENT_MENUBAR )
     284             :             {
     285           0 :                 OUString aErrorMessage = getErrorLineString();
     286           0 :                 aErrorMessage += "closing element menubar expected!";
     287           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     288             :             }
     289             :         }
     290             :     }
     291       17035 : }
     292             : 
     293          49 : OReadMenuBarHandler::OReadMenuBarHandler(
     294             :     const Reference< XIndexContainer >& rMenuBarContainer,
     295             :     const Reference< XSingleComponentFactory >& rFactory          )
     296             : :   m_nElementDepth( 0 ),
     297             :     m_bMenuMode( false ),
     298             :     m_xMenuBarContainer( rMenuBarContainer ),
     299          49 :       m_xContainerFactory( rFactory )
     300             : {
     301          49 : }
     302             : 
     303          98 : OReadMenuBarHandler::~OReadMenuBarHandler()
     304             : {
     305          98 : }
     306             : 
     307          49 : void SAL_CALL OReadMenuBarHandler::startDocument(void)
     308             :     throw ( SAXException, RuntimeException, std::exception )
     309             : {
     310          49 : }
     311             : 
     312          49 : void SAL_CALL OReadMenuBarHandler::endDocument(void)
     313             :     throw( SAXException, RuntimeException, std::exception )
     314             : {
     315          49 : }
     316             : 
     317       16986 : void SAL_CALL OReadMenuBarHandler::startElement(
     318             :     const OUString& rName, const Reference< XAttributeList > &xAttrList )
     319             : throw( SAXException, RuntimeException, std::exception )
     320             : {
     321       16986 :     if ( m_bMenuMode )
     322             :     {
     323       16556 :         ++m_nElementDepth;
     324       16556 :         m_xReader->startElement( rName, xAttrList );
     325             :     }
     326         430 :     else if ( rName == ELEMENT_MENU )
     327             :     {
     328         430 :         ++m_nElementDepth;
     329             : 
     330         430 :         OUString aHelpId;
     331         860 :         OUString aCommandId;
     332         860 :         OUString aLabel;
     333         430 :         sal_Int16 nItemBits(0);
     334             : 
     335         430 :         m_bMenuMode = true;
     336             : 
     337             :         // Container must be factory to create sub container
     338             :         Reference< XComponentContext > xComponentContext(
     339         860 :             comphelper::getProcessComponentContext() );
     340             : 
     341         860 :         Reference< XIndexContainer > xSubItemContainer;
     342         430 :         if ( m_xContainerFactory.is() )
     343         430 :             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
     344             : 
     345         430 :         if ( xSubItemContainer.is() )
     346             :         {
     347             :             // read attributes for menu
     348         867 :             for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     349             :             {
     350         437 :                 OUString aName = xAttrList->getNameByIndex( i );
     351         874 :                 OUString aValue = xAttrList->getValueByIndex( i );
     352         437 :                 if ( aName == ATTRIBUTE_ID )
     353         430 :                     aCommandId = aValue;
     354           7 :                 else if ( aName == ATTRIBUTE_LABEL )
     355           7 :                     aLabel = aValue;
     356           0 :                 else if ( aName == ATTRIBUTE_HELPID )
     357           0 :                     aHelpId = aValue;
     358           0 :                 else if ( aName == ATTRIBUTE_STYLE )
     359             :                 {
     360           0 :                     OUString aTemp( aValue );
     361           0 :                     sal_Int32 nIndex = 0;
     362           0 :                     do
     363             :                     {
     364           0 :                         OUString aToken = aTemp.getToken( 0, '+', nIndex );
     365           0 :                         if ( !aToken.isEmpty() )
     366             :                         {
     367           0 :                             if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     368           0 :                                 nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     369           0 :                             else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     370           0 :                                 nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     371           0 :                             else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     372           0 :                                 nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     373           0 :                         }
     374             :                     }
     375           0 :                     while ( nIndex >= 0 );
     376             :                 }
     377         437 :             }
     378             : 
     379         430 :             if ( !aCommandId.isEmpty() )
     380             :             {
     381         430 :                 Sequence< PropertyValue > aSubMenuProp( 6 );
     382         430 :                 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
     383         430 :                 aSubMenuProp[2].Value <<= xSubItemContainer;
     384             : 
     385         430 :                 m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) );
     386             :             }
     387             :             else
     388             :             {
     389           0 :                 OUString aErrorMessage = getErrorLineString();
     390           0 :                 aErrorMessage += "attribute id for element menu required!";
     391           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     392             :             }
     393             : 
     394         430 :             m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
     395         430 :             m_xReader->startDocument();
     396         430 :         }
     397             :     }
     398             :     else
     399             :     {
     400           0 :         OUString aErrorMessage = getErrorLineString();
     401           0 :         aErrorMessage += "element menu expected!";
     402           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     403             :     }
     404       16986 : }
     405             : 
     406           0 : void SAL_CALL OReadMenuBarHandler::characters(const OUString&)
     407             : throw(  SAXException, RuntimeException, std::exception )
     408             : {
     409           0 : }
     410             : 
     411       17035 : void OReadMenuBarHandler::endElement( const OUString& aName )
     412             :     throw( SAXException, RuntimeException, std::exception )
     413             : {
     414       17035 :     if ( m_bMenuMode )
     415             :     {
     416       16986 :         --m_nElementDepth;
     417       16986 :         if ( 0 == m_nElementDepth )
     418             :         {
     419         430 :             m_xReader->endDocument();
     420         430 :             m_xReader.clear();
     421         430 :             m_bMenuMode = false;
     422         430 :             if ( aName != ELEMENT_MENU )
     423             :             {
     424           0 :                 OUString aErrorMessage = getErrorLineString();
     425           0 :                 aErrorMessage += "closing element menu expected!";
     426           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     427             :             }
     428             :         }
     429             :         else
     430       16556 :             m_xReader->endElement( aName );
     431             :     }
     432       17035 : }
     433             : 
     434        1686 : OReadMenuHandler::OReadMenuHandler(
     435             :     const Reference< XIndexContainer >& rMenuContainer,
     436             :     const Reference< XSingleComponentFactory >& rFactory          ) :
     437             :     m_nElementDepth( 0 ),
     438             :     m_bMenuPopupMode( false ),
     439             :     m_xMenuContainer( rMenuContainer ),
     440        1686 :     m_xContainerFactory( rFactory )
     441             : {
     442        1686 : }
     443             : 
     444        3372 : OReadMenuHandler::~OReadMenuHandler()
     445             : {
     446        3372 : }
     447             : 
     448        1686 : void SAL_CALL OReadMenuHandler::startDocument(void)
     449             :     throw ( SAXException, RuntimeException, std::exception )
     450             : {
     451        1686 : }
     452             : 
     453        1686 : void SAL_CALL OReadMenuHandler::endDocument(void)
     454             :     throw( SAXException, RuntimeException, std::exception)
     455             : {
     456        1686 : }
     457             : 
     458       24554 : void SAL_CALL OReadMenuHandler::startElement(
     459             :     const OUString& aName, const Reference< XAttributeList > &xAttrList )
     460             : throw( SAXException, RuntimeException, std::exception )
     461             : {
     462       24554 :     if ( m_bMenuPopupMode )
     463             :     {
     464       22917 :         ++m_nElementDepth;
     465       22917 :         m_xReader->startElement( aName, xAttrList );
     466             :     }
     467        1637 :     else if ( aName == ELEMENT_MENUPOPUP )
     468             :     {
     469        1637 :         ++m_nElementDepth;
     470        1637 :         m_bMenuPopupMode = true;
     471        1637 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
     472        1637 :         m_xReader->startDocument();
     473             :     }
     474             :     else
     475             :     {
     476           0 :         OUString aErrorMessage = getErrorLineString();
     477           0 :         aErrorMessage += "unknown element found!";
     478           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     479             :     }
     480       24554 : }
     481             : 
     482           0 : void SAL_CALL OReadMenuHandler::characters(const OUString&)
     483             : throw(  SAXException, RuntimeException, std::exception )
     484             : {
     485           0 : }
     486             : 
     487       24554 : void SAL_CALL OReadMenuHandler::endElement( const OUString& aName )
     488             :     throw( SAXException, RuntimeException, std::exception )
     489             : {
     490       24554 :     if ( m_bMenuPopupMode )
     491             :     {
     492       24554 :         --m_nElementDepth;
     493       24554 :         if ( 0 == m_nElementDepth )
     494             :         {
     495        1637 :             m_xReader->endDocument();
     496        1637 :             m_xReader.clear();
     497        1637 :             m_bMenuPopupMode = false;
     498        1637 :             if ( aName != ELEMENT_MENUPOPUP )
     499             :             {
     500           0 :                 OUString aErrorMessage = getErrorLineString();
     501           0 :                 aErrorMessage += "closing element menupopup expected!";
     502           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     503             :             }
     504             :         }
     505             :         else
     506       22917 :             m_xReader->endElement( aName );
     507             :     }
     508       24554 : }
     509             : 
     510        1637 : OReadMenuPopupHandler::OReadMenuPopupHandler(
     511             :     const Reference< XIndexContainer >& rMenuContainer,
     512             :     const Reference< XSingleComponentFactory >& rFactory          ) :
     513             :     m_nElementDepth( 0 ),
     514             :     m_bMenuMode( false ),
     515             :     m_xMenuContainer( rMenuContainer ),
     516             :     m_xContainerFactory( rFactory ),
     517             :     m_xComponentContext( comphelper::getProcessComponentContext() ),
     518        1637 :     m_nNextElementExpected( ELEM_CLOSE_NONE )
     519             : {
     520        1637 : }
     521             : 
     522        3274 : OReadMenuPopupHandler::~OReadMenuPopupHandler()
     523             : {
     524        3274 : }
     525             : 
     526        1637 : void SAL_CALL OReadMenuPopupHandler::startDocument(void)
     527             :     throw ( SAXException, RuntimeException, std::exception )
     528             : {
     529        1637 : }
     530             : 
     531        1637 : void SAL_CALL OReadMenuPopupHandler::endDocument(void)
     532             :     throw( SAXException, RuntimeException, std::exception)
     533             : {
     534        1637 : }
     535             : 
     536       22917 : void SAL_CALL OReadMenuPopupHandler::startElement(
     537             :     const OUString& rName, const Reference< XAttributeList > &xAttrList )
     538             : throw( SAXException, RuntimeException, std::exception )
     539             : {
     540       22917 :     ++m_nElementDepth;
     541             : 
     542       22917 :     if ( m_bMenuMode )
     543        7998 :         m_xReader->startElement( rName, xAttrList );
     544       14919 :     else if ( rName == ELEMENT_MENU )
     545             :     {
     546        1256 :         OUString aHelpId;
     547        2512 :         OUString aCommandId;
     548        2512 :         OUString aLabel;
     549        1256 :         sal_Int16 nItemBits(0);
     550             : 
     551        1256 :         m_bMenuMode = true;
     552             : 
     553             :         // Container must be factory to create sub container
     554        2512 :         Reference< XIndexContainer > xSubItemContainer;
     555        1256 :         if ( m_xContainerFactory.is() )
     556        1256 :             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
     557             : 
     558             :         // read attributes for menu
     559        2518 :         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     560             :         {
     561        1262 :             OUString aName = xAttrList->getNameByIndex( i );
     562        2524 :             OUString aValue = xAttrList->getValueByIndex( i );
     563        1262 :             if ( aName == ATTRIBUTE_ID )
     564        1256 :                 aCommandId = aValue;
     565           6 :             else if ( aName == ATTRIBUTE_LABEL )
     566           6 :                 aLabel = aValue;
     567           0 :             else if ( aName == ATTRIBUTE_HELPID )
     568           0 :                 aHelpId = aValue;
     569           0 :             else if ( aName == ATTRIBUTE_STYLE )
     570             :             {
     571           0 :                 OUString aTemp( aValue );
     572           0 :                 sal_Int32 nIndex = 0;
     573           0 :                 do
     574             :                 {
     575           0 :                     OUString aToken = aTemp.getToken( 0, '+', nIndex );
     576           0 :                     if ( !aToken.isEmpty() )
     577             :                     {
     578           0 :                         if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     579           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     580           0 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     581           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     582           0 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     583           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     584           0 :                     }
     585             :                 }
     586           0 :                 while ( nIndex >= 0 );
     587             :             }
     588             : 
     589        1262 :         }
     590             : 
     591        1256 :         if ( !aCommandId.isEmpty() )
     592             :         {
     593        1256 :             Sequence< PropertyValue > aSubMenuProp( 6 );
     594        1256 :             initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
     595        1256 :             aSubMenuProp[2].Value <<= xSubItemContainer;
     596             : 
     597        1256 :             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) );
     598             :         }
     599             :         else
     600             :         {
     601           0 :             OUString aErrorMessage = getErrorLineString();
     602           0 :             aErrorMessage += "attribute id for element menu required!";
     603           0 :             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     604             :         }
     605             : 
     606        1256 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
     607        2512 :         m_xReader->startDocument();
     608             :     }
     609       13663 :     else if ( rName == ELEMENT_MENUITEM )
     610             :     {
     611       11376 :         OUString aHelpId;
     612       22752 :         OUString aCommandId;
     613       22752 :         OUString aLabel;
     614       11376 :         sal_Int16 nItemBits(0);
     615             :         // read attributes for menu item
     616       23319 :         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     617             :         {
     618       11943 :             OUString aName = xAttrList->getNameByIndex( i );
     619       23886 :             OUString aValue = xAttrList->getValueByIndex( i );
     620       11943 :             if ( aName == ATTRIBUTE_ID )
     621       11376 :                 aCommandId = aValue;
     622         567 :             else if ( aName == ATTRIBUTE_LABEL )
     623          72 :                 aLabel = aValue;
     624         495 :             else if ( aName == ATTRIBUTE_HELPID )
     625           1 :                 aHelpId = aValue;
     626         494 :             else if ( aName == ATTRIBUTE_STYLE )
     627             :             {
     628         494 :                 OUString aTemp( aValue );
     629         494 :                 sal_Int32 nIndex = 0;
     630         494 :                 do
     631             :                 {
     632         494 :                     OUString aToken = aTemp.getToken( 0, '+', nIndex );
     633         494 :                     if ( !aToken.isEmpty() )
     634             :                     {
     635         494 :                         if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     636           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     637         494 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     638           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     639         494 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     640         494 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     641         494 :                     }
     642             :                 }
     643         988 :                 while ( nIndex >= 0 );
     644             :             }
     645             : 
     646       11943 :         }
     647             : 
     648       11376 :         if ( !aCommandId.isEmpty() )
     649             :         {
     650       11376 :             Sequence< PropertyValue > aMenuItem( 6 );
     651       11376 :             initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
     652       11376 :             aMenuItem[2].Value <<= Reference< XIndexContainer >();
     653             : 
     654       11376 :             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
     655             :         }
     656             : 
     657       22752 :         m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
     658             :     }
     659        2287 :     else if ( rName == ELEMENT_MENUSEPARATOR )
     660             :     {
     661        2287 :         Sequence< PropertyValue > aMenuSeparator( 1 );
     662        2287 :         aMenuSeparator[0].Name = OUString( ITEM_DESCRIPTOR_TYPE );
     663        2287 :         aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
     664             : 
     665        2287 :         m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
     666             : 
     667        2287 :         m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR;
     668             :     }
     669             :     else
     670             :     {
     671           0 :         OUString aErrorMessage = getErrorLineString();
     672           0 :         aErrorMessage += "unknown element found!";
     673           0 :         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     674             :     }
     675       22917 : }
     676             : 
     677           0 : void SAL_CALL OReadMenuPopupHandler::characters(const OUString&)
     678             : throw(  SAXException, RuntimeException, std::exception )
     679             : {
     680           0 : }
     681             : 
     682       22917 : void SAL_CALL OReadMenuPopupHandler::endElement( const OUString& aName )
     683             :     throw( SAXException, RuntimeException, std::exception )
     684             : {
     685       22917 :     --m_nElementDepth;
     686       22917 :     if ( m_bMenuMode )
     687             :     {
     688        9254 :         if ( 0 == m_nElementDepth )
     689             :         {
     690        1256 :             m_xReader->endDocument();
     691        1256 :             m_xReader.clear();
     692        1256 :             m_bMenuMode = false;
     693        1256 :             if ( aName != ELEMENT_MENU )
     694             :             {
     695           0 :                 OUString aErrorMessage = getErrorLineString();
     696           0 :                 aErrorMessage += "closing element menu expected!";
     697           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     698             :             }
     699             :         }
     700             :         else
     701        7998 :             m_xReader->endElement( aName );
     702             :     }
     703             :     else
     704             :     {
     705       13663 :         if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
     706             :         {
     707       11376 :             if ( aName != ELEMENT_MENUITEM )
     708             :             {
     709           0 :                 OUString aErrorMessage = getErrorLineString();
     710           0 :                 aErrorMessage += "closing element menuitem expected!";
     711           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     712             :             }
     713             :         }
     714        2287 :         else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
     715             :         {
     716        2287 :             if ( aName != ELEMENT_MENUSEPARATOR )
     717             :             {
     718           0 :                 OUString aErrorMessage = getErrorLineString();
     719           0 :                 aErrorMessage += "closing element menuseparator expected!";
     720           0 :                 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
     721             :             }
     722             :         }
     723             : 
     724       13663 :         m_nNextElementExpected = ELEM_CLOSE_NONE;
     725             :     }
     726       22917 : }
     727             : 
     728             : // --------------------------------- Write XML ---------------------------------
     729             : 
     730           0 : OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
     731             :     const Reference< XIndexAccess >& rMenuBarContainer,
     732             :     const Reference< XDocumentHandler >& rDocumentHandler ) :
     733             :     m_xMenuBarContainer( rMenuBarContainer ),
     734           0 :     m_xWriteDocumentHandler( rDocumentHandler )
     735             : {
     736           0 :     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
     737           0 :     m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
     738           0 :     m_aAttributeType =  OUString( ATTRIBUTE_TYPE_CDATA );
     739           0 : }
     740             : 
     741           0 : OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
     742             : {
     743           0 : }
     744             : 
     745           0 : void OWriteMenuDocumentHandler::WriteMenuDocument()
     746             : throw ( SAXException, RuntimeException )
     747             : {
     748           0 :     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
     749           0 :     Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
     750             : 
     751           0 :     m_xWriteDocumentHandler->startDocument();
     752             : 
     753             :     // write DOCTYPE line!
     754           0 :     Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
     755           0 :     if ( xExtendedDocHandler.is() )
     756             :     {
     757           0 :         xExtendedDocHandler->unknown( OUString( MENUBAR_DOCTYPE ) );
     758           0 :         m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     759             :     }
     760             : 
     761             :     pList->AddAttribute( OUString( ATTRIBUTE_XMLNS_MENU ),
     762             :                          m_aAttributeType,
     763           0 :                          OUString( XMLNS_MENU ) );
     764             : 
     765             :     pList->AddAttribute( OUString( ATTRIBUTE_NS_ID ),
     766             :                          m_aAttributeType,
     767           0 :                          OUString( "menubar" ) );
     768             : 
     769           0 :     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUBAR ), pList );
     770           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     771             : 
     772           0 :     WriteMenu( m_xMenuBarContainer );
     773             : 
     774           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     775           0 :     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUBAR ) );
     776           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     777           0 :     m_xWriteDocumentHandler->endDocument();
     778           0 : }
     779             : 
     780           0 : void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
     781             : throw ( SAXException, RuntimeException )
     782             : {
     783           0 :     sal_Int32  nItemCount = rMenuContainer->getCount();
     784           0 :     bool   bSeparator = false;
     785           0 :     Any        aAny;
     786             : 
     787           0 :     for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
     788             :     {
     789           0 :         Sequence< PropertyValue > aProps;
     790           0 :         aAny = rMenuContainer->getByIndex( nItemPos );
     791           0 :         if ( aAny >>= aProps )
     792             :         {
     793           0 :             OUString    aCommandURL;
     794           0 :             OUString    aLabel;
     795           0 :             OUString    aHelpURL;
     796           0 :             sal_Int16   nType( ::com::sun::star::ui::ItemType::DEFAULT );
     797           0 :             sal_Int16   nItemBits( 0 );
     798           0 :             Reference< XIndexAccess > xSubMenu;
     799             : 
     800           0 :             ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits );
     801           0 :             if ( xSubMenu.is() )
     802             :             {
     803           0 :                 if ( aCommandURL == ADDDIRECT_CMD ||
     804           0 :                     aCommandURL == AUTOPILOTMENU_CMD )
     805             :                 {
     806           0 :                     WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
     807           0 :                     bSeparator = false;
     808             :                 }
     809           0 :                 else if ( !aCommandURL.isEmpty() && !AddonPopupMenu::IsCommandURLPrefix( aCommandURL ))
     810             :                 {
     811           0 :                     ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList;
     812           0 :                     Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY );
     813             : 
     814             :                     pListMenu->AddAttribute( OUString( ATTRIBUTE_NS_ID ),
     815             :                                             m_aAttributeType,
     816           0 :                                             aCommandURL );
     817             : 
     818           0 :                     if ( aCommandURL.copy( CMD_PROTOCOL_SIZE ) != CMD_PROTOCOL )
     819             :                         pListMenu->AddAttribute( OUString( ATTRIBUTE_NS_LABEL ),
     820             :                                                  m_aAttributeType,
     821           0 :                                                  aLabel );
     822             : 
     823           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     824           0 :                     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENU ), xListMenu );
     825           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     826           0 :                     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUPOPUP ), m_xEmptyList );
     827           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     828             : 
     829           0 :                     WriteMenu( xSubMenu );
     830             : 
     831           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     832           0 :                     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUPOPUP ) );
     833           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     834           0 :                     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENU ) );
     835           0 :                     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     836           0 :                     bSeparator = false;
     837             :                 }
     838             :             }
     839             :             else
     840             :             {
     841           0 :                 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
     842             :                 {
     843           0 :                     if ( !aCommandURL.isEmpty() )
     844             :                     {
     845           0 :                         bSeparator = false;
     846           0 :                         WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
     847             :                     }
     848             :                 }
     849           0 :                 else if ( !bSeparator )
     850             :                 {
     851             :                     // Don't write two separators together
     852           0 :                     WriteMenuSeparator();
     853           0 :                     bSeparator = true;
     854             :                 }
     855           0 :             }
     856             :         }
     857           0 :     }
     858           0 : }
     859             : 
     860           0 : void OWriteMenuDocumentHandler::WriteMenuItem( const OUString& aCommandURL, const OUString& aLabel, const OUString& aHelpURL, sal_Int16 nStyle )
     861             : {
     862           0 :     ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
     863           0 :     Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
     864             : 
     865             :     pList->AddAttribute( OUString( ATTRIBUTE_NS_ID ),
     866             :                                 m_aAttributeType,
     867           0 :                                 aCommandURL );
     868             : 
     869           0 :     if ( !aHelpURL.isEmpty() )
     870             :     {
     871             :         pList->AddAttribute( OUString( ATTRIBUTE_NS_HELPID ),
     872             :                              m_aAttributeType,
     873           0 :                              aHelpURL );
     874             :     }
     875             : 
     876           0 :     if ( !aLabel.isEmpty() && aCommandURL.copy( CMD_PROTOCOL_SIZE ) != CMD_PROTOCOL )
     877             :     {
     878             :         pList->AddAttribute( OUString( ATTRIBUTE_NS_LABEL ),
     879             :                                 m_aAttributeType,
     880           0 :                                 aLabel );
     881             :     }
     882           0 :     if (( nStyle > 0 ) && aCommandURL.copy( CMD_PROTOCOL_SIZE ) != CMD_PROTOCOL )
     883             :     {
     884           0 :         OUString aValue;
     885           0 :         MenuStyleItem* pStyle = MenuItemStyles;
     886             : 
     887           0 :         for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle )
     888             :         {
     889           0 :             if ( nStyle & pStyle->nBit )
     890             :             {
     891           0 :                 if ( !aValue.isEmpty() )
     892           0 :                     aValue = aValue.concat( OUString( "+" ) );
     893           0 :                 aValue += OUString::createFromAscii( pStyle->attrName );
     894             :             }
     895             :         }
     896             :         pList->AddAttribute( OUString( ATTRIBUTE_NS_STYLE ),
     897             :                                 m_aAttributeType,
     898           0 :                                 aValue );
     899             :     }
     900             : 
     901           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     902           0 :     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUITEM ), xList );
     903           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     904           0 :     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUITEM ) );
     905           0 : }
     906             : 
     907           0 : void OWriteMenuDocumentHandler::WriteMenuSeparator()
     908             : {
     909           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     910           0 :     m_xWriteDocumentHandler->startElement( OUString( ELEMENT_NS_MENUSEPARATOR ), m_xEmptyList );
     911           0 :     m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
     912           0 :     m_xWriteDocumentHandler->endElement( OUString( ELEMENT_NS_MENUSEPARATOR ) );
     913           0 : }
     914             : 
     915             : } // namespace framework
     916             : 
     917             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10