LCOV - code coverage report
Current view: top level - framework/source/fwe/xml - menudocumenthandler.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 223 431 51.7 %
Date: 2014-11-03 Functions: 33 50 66.0 %
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        7062 : 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        7062 :     m_aStyle( ITEM_DESCRIPTOR_STYLE )
     159             : {
     160        7062 : }
     161             : 
     162        7062 : ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
     163             : {
     164        7062 : }
     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         102 : void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
     179             :     const Reference< XLocator > &xLocator)
     180             : throw(  SAXException, RuntimeException, std::exception )
     181             : {
     182         102 :     m_xLocator = xLocator;
     183         102 : }
     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       27258 : void ReadMenuDocumentHandlerBase::initPropertyCommon(
     199             :     Sequence< PropertyValue > &rProps, const OUString &rCommandURL,
     200             :     const OUString &rHelpId, const OUString &rLabel, sal_Int16 nItemStyleBits )
     201             : {
     202       27258 :     rProps[0].Name = m_aCommandURL;
     203       27258 :     rProps[1].Name = m_aHelpURL;
     204       27258 :     rProps[2].Name = m_aContainer;
     205       27258 :     rProps[3].Name = m_aLabel;
     206       27258 :     rProps[4].Name = m_aStyle;
     207       27258 :     rProps[5].Name = m_aType;
     208             : 
     209             :     // Common values
     210       27258 :     rProps[0].Value <<= rCommandURL.intern();
     211       27258 :     rProps[1].Value <<= rHelpId;
     212       27258 :     rProps[2].Value <<= Reference< XIndexContainer >();
     213       27258 :     rProps[3].Value <<= rLabel;
     214       27258 :     rProps[4].Value <<= nItemStyleBits;
     215       27258 :     rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
     216       27258 : }
     217             : 
     218         102 : OReadMenuDocumentHandler::OReadMenuDocumentHandler(
     219             :     const Reference< XIndexContainer >& rMenuBarContainer )
     220             : :   m_nElementDepth( 0 ),
     221             :     m_bMenuBarMode( false ),
     222             :     m_xMenuBarContainer( rMenuBarContainer ),
     223         102 :     m_xContainerFactory( rMenuBarContainer, UNO_QUERY )
     224             : {
     225         102 : }
     226             : 
     227         204 : OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
     228             : {
     229         204 : }
     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       35576 : void SAL_CALL OReadMenuDocumentHandler::startElement(
     248             :     const OUString& aName, const Reference< XAttributeList > &xAttrList )
     249             : throw( SAXException, RuntimeException, std::exception )
     250             : {
     251       35576 :     if ( m_bMenuBarMode )
     252             :     {
     253       35474 :         ++m_nElementDepth;
     254       35474 :         m_xReader->startElement( aName, xAttrList );
     255             :     }
     256         102 :     else if ( aName == ELEMENT_MENUBAR )
     257             :     {
     258         102 :         ++m_nElementDepth;
     259         102 :         m_bMenuBarMode = true;
     260         102 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory ));
     261             : 
     262         102 :         m_xReader->startDocument();
     263             :     }
     264       35576 : }
     265             : 
     266       84676 : void SAL_CALL OReadMenuDocumentHandler::characters(const OUString&)
     267             : throw(  SAXException, RuntimeException, std::exception )
     268             : {
     269       84676 : }
     270             : 
     271       35576 : void SAL_CALL OReadMenuDocumentHandler::endElement( const OUString& aName )
     272             :     throw( SAXException, RuntimeException, std::exception )
     273             : {
     274       35576 :     if ( m_bMenuBarMode )
     275             :     {
     276       35576 :         --m_nElementDepth;
     277       35576 :         m_xReader->endElement( aName );
     278       35576 :         if ( 0 == m_nElementDepth )
     279             :         {
     280         102 :             m_xReader->endDocument();
     281         102 :             m_xReader.clear();
     282         102 :             m_bMenuBarMode = false;
     283         102 :             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       35576 : }
     292             : 
     293         102 : 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         102 :       m_xContainerFactory( rFactory )
     300             : {
     301         102 : }
     302             : 
     303         204 : OReadMenuBarHandler::~OReadMenuBarHandler()
     304             : {
     305         204 : }
     306             : 
     307         102 : void SAL_CALL OReadMenuBarHandler::startDocument(void)
     308             :     throw ( SAXException, RuntimeException, std::exception )
     309             : {
     310         102 : }
     311             : 
     312         102 : void SAL_CALL OReadMenuBarHandler::endDocument(void)
     313             :     throw( SAXException, RuntimeException, std::exception )
     314             : {
     315         102 : }
     316             : 
     317       35474 : void SAL_CALL OReadMenuBarHandler::startElement(
     318             :     const OUString& rName, const Reference< XAttributeList > &xAttrList )
     319             : throw( SAXException, RuntimeException, std::exception )
     320             : {
     321       35474 :     if ( m_bMenuMode )
     322             :     {
     323       34582 :         ++m_nElementDepth;
     324       34582 :         m_xReader->startElement( rName, xAttrList );
     325             :     }
     326         892 :     else if ( rName == ELEMENT_MENU )
     327             :     {
     328         892 :         ++m_nElementDepth;
     329             : 
     330         892 :         OUString aHelpId;
     331        1784 :         OUString aCommandId;
     332        1784 :         OUString aLabel;
     333         892 :         sal_Int16 nItemBits(0);
     334             : 
     335         892 :         m_bMenuMode = true;
     336             : 
     337             :         // Container must be factory to create sub container
     338             :         Reference< XComponentContext > xComponentContext(
     339        1784 :             comphelper::getProcessComponentContext() );
     340             : 
     341        1784 :         Reference< XIndexContainer > xSubItemContainer;
     342         892 :         if ( m_xContainerFactory.is() )
     343         892 :             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
     344             : 
     345         892 :         if ( xSubItemContainer.is() )
     346             :         {
     347             :             // read attributes for menu
     348        1798 :             for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     349             :             {
     350         906 :                 OUString aName = xAttrList->getNameByIndex( i );
     351        1812 :                 OUString aValue = xAttrList->getValueByIndex( i );
     352         906 :                 if ( aName == ATTRIBUTE_ID )
     353         892 :                     aCommandId = aValue;
     354          14 :                 else if ( aName == ATTRIBUTE_LABEL )
     355          14 :                     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         906 :             }
     378             : 
     379         892 :             if ( !aCommandId.isEmpty() )
     380             :             {
     381         892 :                 Sequence< PropertyValue > aSubMenuProp( 6 );
     382         892 :                 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
     383         892 :                 aSubMenuProp[2].Value <<= xSubItemContainer;
     384             : 
     385         892 :                 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         892 :             m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
     395         892 :             m_xReader->startDocument();
     396         892 :         }
     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       35474 : }
     405             : 
     406           0 : void SAL_CALL OReadMenuBarHandler::characters(const OUString&)
     407             : throw(  SAXException, RuntimeException, std::exception )
     408             : {
     409           0 : }
     410             : 
     411       35576 : void OReadMenuBarHandler::endElement( const OUString& aName )
     412             :     throw( SAXException, RuntimeException, std::exception )
     413             : {
     414       35576 :     if ( m_bMenuMode )
     415             :     {
     416       35474 :         --m_nElementDepth;
     417       35474 :         if ( 0 == m_nElementDepth )
     418             :         {
     419         892 :             m_xReader->endDocument();
     420         892 :             m_xReader.clear();
     421         892 :             m_bMenuMode = false;
     422         892 :             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       34582 :             m_xReader->endElement( aName );
     431             :     }
     432       35576 : }
     433             : 
     434        3480 : 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        3480 :     m_xContainerFactory( rFactory )
     441             : {
     442        3480 : }
     443             : 
     444        6960 : OReadMenuHandler::~OReadMenuHandler()
     445             : {
     446        6960 : }
     447             : 
     448        3480 : void SAL_CALL OReadMenuHandler::startDocument(void)
     449             :     throw ( SAXException, RuntimeException, std::exception )
     450             : {
     451        3480 : }
     452             : 
     453        3480 : void SAL_CALL OReadMenuHandler::endDocument(void)
     454             :     throw( SAXException, RuntimeException, std::exception)
     455             : {
     456        3480 : }
     457             : 
     458       51130 : void SAL_CALL OReadMenuHandler::startElement(
     459             :     const OUString& aName, const Reference< XAttributeList > &xAttrList )
     460             : throw( SAXException, RuntimeException, std::exception )
     461             : {
     462       51130 :     if ( m_bMenuPopupMode )
     463             :     {
     464       47752 :         ++m_nElementDepth;
     465       47752 :         m_xReader->startElement( aName, xAttrList );
     466             :     }
     467        3378 :     else if ( aName == ELEMENT_MENUPOPUP )
     468             :     {
     469        3378 :         ++m_nElementDepth;
     470        3378 :         m_bMenuPopupMode = true;
     471        3378 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
     472        3378 :         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       51130 : }
     481             : 
     482           0 : void SAL_CALL OReadMenuHandler::characters(const OUString&)
     483             : throw(  SAXException, RuntimeException, std::exception )
     484             : {
     485           0 : }
     486             : 
     487       51130 : void SAL_CALL OReadMenuHandler::endElement( const OUString& aName )
     488             :     throw( SAXException, RuntimeException, std::exception )
     489             : {
     490       51130 :     if ( m_bMenuPopupMode )
     491             :     {
     492       51130 :         --m_nElementDepth;
     493       51130 :         if ( 0 == m_nElementDepth )
     494             :         {
     495        3378 :             m_xReader->endDocument();
     496        3378 :             m_xReader.clear();
     497        3378 :             m_bMenuPopupMode = false;
     498        3378 :             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       47752 :             m_xReader->endElement( aName );
     507             :     }
     508       51130 : }
     509             : 
     510        3378 : 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        3378 :     m_nNextElementExpected( ELEM_CLOSE_NONE )
     519             : {
     520        3378 : }
     521             : 
     522        6756 : OReadMenuPopupHandler::~OReadMenuPopupHandler()
     523             : {
     524        6756 : }
     525             : 
     526        3378 : void SAL_CALL OReadMenuPopupHandler::startDocument(void)
     527             :     throw ( SAXException, RuntimeException, std::exception )
     528             : {
     529        3378 : }
     530             : 
     531        3378 : void SAL_CALL OReadMenuPopupHandler::endDocument(void)
     532             :     throw( SAXException, RuntimeException, std::exception)
     533             : {
     534        3378 : }
     535             : 
     536       47752 : void SAL_CALL OReadMenuPopupHandler::startElement(
     537             :     const OUString& rName, const Reference< XAttributeList > &xAttrList )
     538             : throw( SAXException, RuntimeException, std::exception )
     539             : {
     540       47752 :     ++m_nElementDepth;
     541             : 
     542       47752 :     if ( m_bMenuMode )
     543       16548 :         m_xReader->startElement( rName, xAttrList );
     544       31204 :     else if ( rName == ELEMENT_MENU )
     545             :     {
     546        2588 :         OUString aHelpId;
     547        5176 :         OUString aCommandId;
     548        5176 :         OUString aLabel;
     549        2588 :         sal_Int16 nItemBits(0);
     550             : 
     551        2588 :         m_bMenuMode = true;
     552             : 
     553             :         // Container must be factory to create sub container
     554        5176 :         Reference< XIndexContainer > xSubItemContainer;
     555        2588 :         if ( m_xContainerFactory.is() )
     556        2588 :             xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
     557             : 
     558             :         // read attributes for menu
     559        5188 :         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     560             :         {
     561        2600 :             OUString aName = xAttrList->getNameByIndex( i );
     562        5200 :             OUString aValue = xAttrList->getValueByIndex( i );
     563        2600 :             if ( aName == ATTRIBUTE_ID )
     564        2588 :                 aCommandId = aValue;
     565          12 :             else if ( aName == ATTRIBUTE_LABEL )
     566          12 :                 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        2600 :         }
     590             : 
     591        2588 :         if ( !aCommandId.isEmpty() )
     592             :         {
     593        2588 :             Sequence< PropertyValue > aSubMenuProp( 6 );
     594        2588 :             initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
     595        2588 :             aSubMenuProp[2].Value <<= xSubItemContainer;
     596             : 
     597        2588 :             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        2588 :         m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
     607        5176 :         m_xReader->startDocument();
     608             :     }
     609       28616 :     else if ( rName == ELEMENT_MENUITEM )
     610             :     {
     611       23778 :         OUString aHelpId;
     612       47556 :         OUString aCommandId;
     613       47556 :         OUString aLabel;
     614       23778 :         sal_Int16 nItemBits(0);
     615             :         // read attributes for menu item
     616       48738 :         for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
     617             :         {
     618       24960 :             OUString aName = xAttrList->getNameByIndex( i );
     619       49920 :             OUString aValue = xAttrList->getValueByIndex( i );
     620       24960 :             if ( aName == ATTRIBUTE_ID )
     621       23778 :                 aCommandId = aValue;
     622        1182 :             else if ( aName == ATTRIBUTE_LABEL )
     623         152 :                 aLabel = aValue;
     624        1030 :             else if ( aName == ATTRIBUTE_HELPID )
     625           2 :                 aHelpId = aValue;
     626        1028 :             else if ( aName == ATTRIBUTE_STYLE )
     627             :             {
     628        1028 :                 OUString aTemp( aValue );
     629        1028 :                 sal_Int32 nIndex = 0;
     630        1028 :                 do
     631             :                 {
     632        1028 :                     OUString aToken = aTemp.getToken( 0, '+', nIndex );
     633        1028 :                     if ( !aToken.isEmpty() )
     634             :                     {
     635        1028 :                         if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
     636           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
     637        1028 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
     638           0 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
     639        1028 :                         else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
     640        1028 :                             nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
     641        1028 :                     }
     642             :                 }
     643        2056 :                 while ( nIndex >= 0 );
     644             :             }
     645             : 
     646       24960 :         }
     647             : 
     648       23778 :         if ( !aCommandId.isEmpty() )
     649             :         {
     650       23778 :             Sequence< PropertyValue > aMenuItem( 6 );
     651       23778 :             initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
     652       23778 :             aMenuItem[2].Value <<= Reference< XIndexContainer >();
     653             : 
     654       23778 :             m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
     655             :         }
     656             : 
     657       47556 :         m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
     658             :     }
     659        4838 :     else if ( rName == ELEMENT_MENUSEPARATOR )
     660             :     {
     661        4838 :         Sequence< PropertyValue > aMenuSeparator( 1 );
     662        4838 :         aMenuSeparator[0].Name = OUString( ITEM_DESCRIPTOR_TYPE );
     663        4838 :         aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
     664             : 
     665        4838 :         m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
     666             : 
     667        4838 :         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       47752 : }
     676             : 
     677           0 : void SAL_CALL OReadMenuPopupHandler::characters(const OUString&)
     678             : throw(  SAXException, RuntimeException, std::exception )
     679             : {
     680           0 : }
     681             : 
     682       47752 : void SAL_CALL OReadMenuPopupHandler::endElement( const OUString& aName )
     683             :     throw( SAXException, RuntimeException, std::exception )
     684             : {
     685       47752 :     --m_nElementDepth;
     686       47752 :     if ( m_bMenuMode )
     687             :     {
     688       19136 :         if ( 0 == m_nElementDepth )
     689             :         {
     690        2588 :             m_xReader->endDocument();
     691        2588 :             m_xReader.clear();
     692        2588 :             m_bMenuMode = false;
     693        2588 :             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       16548 :             m_xReader->endElement( aName );
     702             :     }
     703             :     else
     704             :     {
     705       28616 :         if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
     706             :         {
     707       23778 :             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        4838 :         else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
     715             :         {
     716        4838 :             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       28616 :         m_nNextElementExpected = ELEM_CLOSE_NONE;
     725             :     }
     726       47752 : }
     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         969 : } // namespace framework
     916             : 
     917             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10