LCOV - code coverage report
Current view: top level - libreoffice/framework/source/fwe/classes - addonsoptions.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 482 708 68.1 %
Date: 2012-12-17 Functions: 52 64 81.2 %
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 <framework/addonsoptions.hxx>
      21             : #include <unotools/configmgr.hxx>
      22             : #include <unotools/configitem.hxx>
      23             : #include <unotools/ucbstreamhelper.hxx>
      24             : #include <tools/stream.hxx>
      25             : #include <com/sun/star/uno/Any.hxx>
      26             : #include <com/sun/star/uno/Sequence.hxx>
      27             : #include "com/sun/star/util/XMacroExpander.hpp"
      28             : #include "com/sun/star/uno/XComponentContext.hpp"
      29             : #include <rtl/ustrbuf.hxx>
      30             : #include <rtl/uri.hxx>
      31             : #include <comphelper/processfactory.hxx>
      32             : #include <vcl/graph.hxx>
      33             : #include <svtools/filter.hxx>
      34             : 
      35             : #include <boost/unordered_map.hpp>
      36             : #include <algorithm>
      37             : #include <vector>
      38             : 
      39             : //_________________________________________________________________________________________________________________
      40             : //  namespaces
      41             : //_________________________________________________________________________________________________________________
      42             : 
      43             : using namespace ::std                   ;
      44             : using namespace ::utl                   ;
      45             : using namespace ::osl                   ;
      46             : using namespace ::com::sun::star::uno   ;
      47             : using namespace ::com::sun::star::beans ;
      48             : using namespace ::com::sun::star::lang  ;
      49             : 
      50             : #define ROOTNODE_ADDONMENU                              ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Addons" ))
      51             : #define PATHDELIMITER                                   ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"             ))
      52             : #define SEPARATOR_URL_STR                               "private:separator"
      53             : #define SEPARATOR_URL_LEN                               17
      54             : #define SEPARATOR_URL                                   ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SEPARATOR_URL_STR ))
      55             : 
      56             : #define PROPERTYNAME_URL                                ADDONSMENUITEM_PROPERTYNAME_URL
      57             : #define PROPERTYNAME_TITLE                              ADDONSMENUITEM_PROPERTYNAME_TITLE
      58             : #define PROPERTYNAME_TARGET                             ADDONSMENUITEM_PROPERTYNAME_TARGET
      59             : #define PROPERTYNAME_IMAGEIDENTIFIER                    ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER
      60             : #define PROPERTYNAME_CONTEXT                            ADDONSMENUITEM_PROPERTYNAME_CONTEXT
      61             : #define PROPERTYNAME_SUBMENU                            ADDONSMENUITEM_PROPERTYNAME_SUBMENU
      62             : #define PROPERTYNAME_CONTROLTYPE                        ADDONSMENUITEM_PROPERTYNAME_CONTROLTYPE
      63             : #define PROPERTYNAME_WIDTH                              ADDONSMENUITEM_PROPERTYNAME_WIDTH
      64             : 
      65             : #define PROPERTYNAME_IMAGESMALL                         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmall" ))
      66             : #define PROPERTYNAME_IMAGEBIG                           ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBig" ))
      67             : #define PROPERTYNAME_IMAGESMALLHC                       ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHC" ))
      68             : #define PROPERTYNAME_IMAGEBIGHC                         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHC" ))
      69             : #define PROPERTYNAME_IMAGESMALL_URL                     ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallURL" ))
      70             : #define PROPERTYNAME_IMAGEBIG_URL                       ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigURL" ))
      71             : #define PROPERTYNAME_IMAGESMALLHC_URL                   ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHCURL" ))
      72             : #define PROPERTYNAME_IMAGEBIGHC_URL                     ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHCURL" ))
      73             : 
      74             : #define IMAGES_NODENAME                                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefinedImages" ))
      75             : #define PRIVATE_IMAGE_URL                               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:image/" ))
      76             : 
      77             : #define PROPERTYNAME_MERGEMENU_MERGEPOINT               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
      78             : #define PROPERTYNAME_MERGEMENU_MERGECOMMAND             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
      79             : #define PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
      80             : #define PROPERTYNAME_MERGEMENU_MERGEFALLBACK            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
      81             : #define PROPERTYNAME_MERGEMENU_MERGECONTEXT             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
      82             : #define PROPERTYNAME_MERGEMENU_MENUITEMS                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MenuItems" ))
      83             : 
      84             : #define PROPERTYNAME_MERGETOOLBAR_TOOLBAR               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeToolBar" ))
      85             : #define PROPERTYNAME_MERGETOOLBAR_MERGEPOINT            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
      86             : #define PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
      87             : #define PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
      88             : #define PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
      89             : #define PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
      90             : #define PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ToolBarItems" ))
      91             : 
      92             : // The following order is mandatory. Please add properties at the end!
      93             : #define INDEX_URL             0
      94             : #define INDEX_TITLE           1
      95             : #define INDEX_IMAGEIDENTIFIER 2
      96             : #define INDEX_TARGET          3
      97             : #define INDEX_CONTEXT         4
      98             : #define INDEX_SUBMENU         5
      99             : #define INDEX_CONTROLTYPE     6
     100             : #define INDEX_WIDTH           7
     101             : #define PROPERTYCOUNT_INDEX   8
     102             : 
     103             : // The following order is mandatory. Please add properties at the end!
     104             : #define PROPERTYCOUNT_MENUITEM                          6
     105             : #define OFFSET_MENUITEM_URL                             0
     106             : #define OFFSET_MENUITEM_TITLE                           1
     107             : #define OFFSET_MENUITEM_IMAGEIDENTIFIER                 2
     108             : #define OFFSET_MENUITEM_TARGET                          3
     109             : #define OFFSET_MENUITEM_CONTEXT                         4
     110             : #define OFFSET_MENUITEM_SUBMENU                         5
     111             : 
     112             : // The following order is mandatory. Please add properties at the end!
     113             : #define PROPERTYCOUNT_POPUPMENU                         4
     114             : #define OFFSET_POPUPMENU_TITLE                          0
     115             : #define OFFSET_POPUPMENU_CONTEXT                        1
     116             : #define OFFSET_POPUPMENU_SUBMENU                        2
     117             : #define OFFSET_POPUPMENU_URL                            3   // Used for property set
     118             : 
     119             : // The following order is mandatory. Please add properties at the end!
     120             : #define PROPERTYCOUNT_TOOLBARITEM                       7
     121             : #define OFFSET_TOOLBARITEM_URL                          0
     122             : #define OFFSET_TOOLBARITEM_TITLE                        1
     123             : #define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER              2
     124             : #define OFFSET_TOOLBARITEM_TARGET                       3
     125             : #define OFFSET_TOOLBARITEM_CONTEXT                      4
     126             : #define OFFSET_TOOLBARITEM_CONTROLTYPE                  5
     127             : #define OFFSET_TOOLBARITEM_WIDTH                        6
     128             : 
     129             : // The following order is mandatory. Please add properties at the end!
     130             : #define PROPERTYCOUNT_IMAGES                            8
     131             : #define PROPERTYCOUNT_EMBEDDED_IMAGES                   4
     132             : #define OFFSET_IMAGES_SMALL                             0
     133             : #define OFFSET_IMAGES_BIG                               1
     134             : #define OFFSET_IMAGES_SMALLHC                           2
     135             : #define OFFSET_IMAGES_BIGHC                             3
     136             : #define OFFSET_IMAGES_SMALL_URL                         4
     137             : #define OFFSET_IMAGES_BIG_URL                           5
     138             : #define OFFSET_IMAGES_SMALLHC_URL                       6
     139             : #define OFFSET_IMAGES_BIGHC_URL                         7
     140             : 
     141             : #define PROPERTYCOUNT_MERGE_MENUBAR                     6
     142             : #define OFFSET_MERGEMENU_MERGEPOINT                     0
     143             : #define OFFSET_MERGEMENU_MERGECOMMAND                   1
     144             : #define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER          2
     145             : #define OFFSET_MERGEMENU_MERGEFALLBACK                  3
     146             : #define OFFSET_MERGEMENU_MERGECONTEXT                   4
     147             : #define OFFSET_MERGEMENU_MENUITEMS                      5
     148             : 
     149             : #define PROPERTYCOUNT_MERGE_TOOLBAR                     7
     150             : #define OFFSET_MERGETOOLBAR_TOOLBAR                     0
     151             : #define OFFSET_MERGETOOLBAR_MERGEPOINT                  1
     152             : #define OFFSET_MERGETOOLBAR_MERGECOMMAND                2
     153             : #define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER       3
     154             : #define OFFSET_MERGETOOLBAR_MERGEFALLBACK               4
     155             : #define OFFSET_MERGETOOLBAR_MERGECONTEXT                5
     156             : #define OFFSET_MERGETOOLBAR_TOOLBARITEMS                6
     157             : 
     158             : #define EXPAND_PROTOCOL                                 "vnd.sun.star.expand:"
     159             : 
     160          78 : const Size  aImageSizeSmall( 16, 16 );
     161          78 : const Size  aImageSizeBig( 26, 26 );
     162             : 
     163             : //_________________________________________________________________________________________________________________
     164             : //  private declarations!
     165             : //_________________________________________________________________________________________________________________
     166             : 
     167             : /*-****************************************************************************************************************
     168             :     @descr  struct to hold information about one menu entry.
     169             : ****************************************************************************************************************-*/
     170             : 
     171             : namespace framework
     172             : {
     173             : 
     174             : class AddonsOptions_Impl : public ConfigItem
     175             : {
     176             :     //-------------------------------------------------------------------------------------------------------------
     177             :     //  public methods
     178             :     //-------------------------------------------------------------------------------------------------------------
     179             : 
     180             :     public:
     181             :         //---------------------------------------------------------------------------------------------------------
     182             :         //  constructor / destructor
     183             :         //---------------------------------------------------------------------------------------------------------
     184             : 
     185             :          AddonsOptions_Impl();
     186             :         ~AddonsOptions_Impl();
     187             : 
     188             :         //---------------------------------------------------------------------------------------------------------
     189             :         //  overloaded methods of baseclass
     190             :         //---------------------------------------------------------------------------------------------------------
     191             : 
     192             :         /*-****************************************************************************************************//**
     193             :             @short      called for notify of configmanager
     194             :             @descr      These method is called from the ConfigManager before application ends or from the
     195             :                          PropertyChangeListener if the sub tree broadcasts changes. You must update your
     196             :                         internal values.
     197             : 
     198             :             @seealso    baseclass ConfigItem
     199             : 
     200             :             @param      "lPropertyNames" is the list of properties which should be updated.
     201             :             @return     -
     202             : 
     203             :             @onerror    -
     204             :         *//*-*****************************************************************************************************/
     205             : 
     206             :         virtual void Notify( const Sequence< ::rtl::OUString >& lPropertyNames );
     207             : 
     208             :         /*-****************************************************************************************************//**
     209             :             @short      write changes to configuration
     210             :             @descr      These method writes the changed values into the sub tree
     211             :                         and should always called in our destructor to guarantee consistency of config data.
     212             : 
     213             :             @seealso    baseclass ConfigItem
     214             : 
     215             :             @param      -
     216             :             @return     -
     217             : 
     218             :             @onerror    -
     219             :         *//*-*****************************************************************************************************/
     220             : 
     221             :         virtual void Commit();
     222             : 
     223             :         //---------------------------------------------------------------------------------------------------------
     224             :         //  public interface
     225             :         //---------------------------------------------------------------------------------------------------------
     226             : 
     227             :         /*-****************************************************************************************************//**
     228             :             @short      base implementation of public interface for "SvtDynamicMenuOptions"!
     229             :             @descr      These class is used as static member of "SvtDynamicMenuOptions" ...
     230             :                         => The code exist only for one time and isn't duplicated for every instance!
     231             : 
     232             :             @seealso    -
     233             : 
     234             :             @param      -
     235             :             @return     -
     236             : 
     237             :             @onerror    -
     238             :         *//*-*****************************************************************************************************/
     239             : 
     240             :         sal_Bool                                        HasAddonsMenu        () const ;
     241             :         sal_Int32                                       GetAddonsToolBarCount() const ;
     242             :         const Sequence< Sequence< PropertyValue > >&    GetAddonsMenu        () const ;
     243             :         const Sequence< Sequence< PropertyValue > >&    GetAddonsMenuBarPart () const ;
     244             :         const Sequence< Sequence< PropertyValue > >&    GetAddonsToolBarPart ( sal_uInt32 nIndex ) const ;
     245             :         const ::rtl::OUString                           GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
     246             :         const Sequence< Sequence< PropertyValue > >&    GetAddonsHelpMenu    () const ;
     247             :         Image                                           GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const;
     248             :         const MergeMenuInstructionContainer&            GetMergeMenuInstructions() const;
     249             :         bool                                            GetMergeToolbarInstructions( const ::rtl::OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
     250             : 
     251             :         void                                            ReadConfigurationData();
     252             : 
     253             :     //-------------------------------------------------------------------------------------------------------------
     254             :     //  private methods
     255             :     //-------------------------------------------------------------------------------------------------------------
     256             : 
     257             :     private:
     258             :         struct OUStringHashCode
     259             :         {
     260          60 :             size_t operator()( const ::rtl::OUString& sString ) const
     261             :             {
     262          60 :                 return sString.hashCode();
     263             :             }
     264             :         };
     265             : 
     266         120 :         struct ImageEntry
     267             :         {
     268             :             Image   aImageSmall;
     269             :             Image   aImageBig;
     270             : 
     271             :             Image   aImageSmallNoScale;
     272             :             Image   aImageBigNoScale;
     273             :         };
     274             : 
     275             :         typedef boost::unordered_map< ::rtl::OUString, ImageEntry, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ImageManager;
     276             :         typedef boost::unordered_map< ::rtl::OUString, sal_uInt32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > StringToIndexMap;
     277             :         typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
     278             :         typedef ::boost::unordered_map< ::rtl::OUString, MergeToolbarInstructionContainer, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarMergingInstructions;
     279             : 
     280             :         enum ImageSize
     281             :         {
     282             :             IMGSIZE_SMALL,
     283             :             IMGSIZE_BIG
     284             :         };
     285             : 
     286             :         /*-****************************************************************************************************//**
     287             :             @short      return list of key names of our configuration management which represent oue module tree
     288             :             @descr      These methods return the current list of key names! We need it to get needed values from our
     289             :                         configuration management!
     290             : 
     291             :             @seealso    -
     292             : 
     293             :             @param      "nCount"     ,   returns count of menu entries for "new"
     294             :             @return     A list of configuration key names is returned.
     295             : 
     296             :             @onerror    -
     297             :         *//*-*****************************************************************************************************/
     298             : 
     299             :         sal_Bool             ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
     300             :         sal_Bool             ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
     301             :         sal_Bool             ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< rtl::OUString >& rAddonOfficeToolBarResNames );
     302             :         sal_Bool             ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
     303             :         sal_Bool             ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
     304             :         sal_Bool             ReadImages( ImageManager& aImageManager );
     305             :         sal_Bool             ReadMenuMergeInstructions( MergeMenuInstructionContainer& rContainer );
     306             :         sal_Bool             ReadToolbarMergeInstructions( ToolbarMergingInstructions& rToolbarMergeMap );
     307             : 
     308             :         sal_Bool             ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
     309             :         sal_Bool             ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
     310             :         sal_Bool             ReadMenuItem( const ::rtl::OUString& aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu = sal_False );
     311             :         sal_Bool             ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
     312             :         sal_Bool             AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
     313             :         sal_Bool             ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
     314             :         sal_Bool             ReadImagesItem( const ::rtl::OUString& aImagesItemNodeName, Sequence< PropertyValue >& aImagesItem );
     315             :         ImageEntry*          ReadImageData( const ::rtl::OUString& aImagesNodeName );
     316             :         void                 ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId );
     317             :         void                 ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aURL, Image& aImage, Image& aNoScaleImage );
     318             :         sal_Bool             HasAssociatedImages( const ::rtl::OUString& aURL );
     319             :         void                 SubstituteVariables( ::rtl::OUString& aURL );
     320             : 
     321             :         sal_Bool             ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
     322             :         void                 InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq );
     323             :         ::rtl::OUString          GeneratePrefixURL();
     324             : 
     325             :         Sequence< ::rtl::OUString > GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const;
     326             :         Sequence< ::rtl::OUString > GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const;
     327             :         Sequence< ::rtl::OUString > GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const;
     328             :         Sequence< ::rtl::OUString > GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const;
     329             :         sal_Bool             CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
     330             : 
     331             :     //-------------------------------------------------------------------------------------------------------------
     332             :     //  private member
     333             :     //-------------------------------------------------------------------------------------------------------------
     334             : 
     335             :     private:
     336             :         ImageEntry* ReadOptionalImageData( const ::rtl::OUString& aMenuNodeName );
     337             : 
     338             :         sal_Int32                                         m_nRootAddonPopupMenuId;
     339             :         ::rtl::OUString                                   m_aPropNames[PROPERTYCOUNT_INDEX];
     340             :         ::rtl::OUString                                   m_aPropImagesNames[PROPERTYCOUNT_IMAGES];
     341             :         ::rtl::OUString                                   m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR];
     342             :         ::rtl::OUString                                   m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR];
     343             :         ::rtl::OUString                                   m_aEmpty;
     344             :         ::rtl::OUString                                   m_aPathDelimiter;
     345             :         ::rtl::OUString                                   m_aSeparator;
     346             :         ::rtl::OUString                                   m_aRootAddonPopupMenuURLPrexfix;
     347             :         ::rtl::OUString                                   m_aPrivateImageURL;
     348             :         Sequence< Sequence< PropertyValue > >             m_aCachedMenuProperties;
     349             :         Sequence< Sequence< PropertyValue > >             m_aCachedMenuBarPartProperties;
     350             :         AddonToolBars                                     m_aCachedToolBarPartProperties;
     351             :         std::vector< rtl::OUString >                      m_aCachedToolBarPartResourceNames;
     352             :         Sequence< Sequence< PropertyValue > >             m_aCachedHelpMenuProperties;
     353             :         Reference< com::sun::star::util::XMacroExpander > m_xMacroExpander;
     354             :         ImageManager                                      m_aImageManager;
     355             :         Sequence< Sequence< PropertyValue > >             m_aEmptyAddonToolBar;
     356             :         MergeMenuInstructionContainer                     m_aCachedMergeMenuInsContainer;
     357             :         ToolbarMergingInstructions                        m_aCachedToolbarMergingInstructions;
     358             : };
     359             : 
     360             : //*****************************************************************************************************************
     361             : //  constructor
     362             : //*****************************************************************************************************************
     363          54 : AddonsOptions_Impl::AddonsOptions_Impl()
     364             :     // Init baseclasses first
     365             :     : ConfigItem( ROOTNODE_ADDONMENU ),
     366             :     m_nRootAddonPopupMenuId( 0 ),
     367             :     m_aPathDelimiter( PATHDELIMITER ),
     368             :     m_aSeparator( SEPARATOR_URL ),
     369             :     m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX ),
     370          54 :     m_aPrivateImageURL( PRIVATE_IMAGE_URL )
     371             : {
     372             :     // initialize array with fixed property names
     373          54 :     m_aPropNames[ INDEX_URL             ] = PROPERTYNAME_URL;
     374          54 :     m_aPropNames[ INDEX_TITLE           ] = PROPERTYNAME_TITLE;
     375          54 :     m_aPropNames[ INDEX_TARGET          ] = PROPERTYNAME_TARGET;
     376          54 :     m_aPropNames[ INDEX_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
     377          54 :     m_aPropNames[ INDEX_CONTEXT         ] = PROPERTYNAME_CONTEXT;
     378          54 :     m_aPropNames[ INDEX_SUBMENU         ] = PROPERTYNAME_SUBMENU; // Submenu set!
     379          54 :     m_aPropNames[ INDEX_CONTROLTYPE     ] = PROPERTYNAME_CONTROLTYPE;
     380          54 :     m_aPropNames[ INDEX_WIDTH           ] = PROPERTYNAME_WIDTH;
     381             : 
     382             :     // initialize array with fixed images property names
     383          54 :     m_aPropImagesNames[ OFFSET_IMAGES_SMALL         ] = PROPERTYNAME_IMAGESMALL;
     384          54 :     m_aPropImagesNames[ OFFSET_IMAGES_BIG           ] = PROPERTYNAME_IMAGEBIG;
     385          54 :     m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC       ] = PROPERTYNAME_IMAGESMALLHC;
     386          54 :     m_aPropImagesNames[ OFFSET_IMAGES_BIGHC         ] = PROPERTYNAME_IMAGEBIGHC;
     387          54 :     m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL     ] = PROPERTYNAME_IMAGESMALL_URL;
     388          54 :     m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL       ] = PROPERTYNAME_IMAGEBIG_URL;
     389          54 :     m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL   ] = PROPERTYNAME_IMAGESMALLHC_URL;
     390          54 :     m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL     ] = PROPERTYNAME_IMAGEBIGHC_URL;
     391             : 
     392             :     // initialize array with fixed merge menu property names
     393          54 :     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT    ] = PROPERTYNAME_MERGEMENU_MERGEPOINT;
     394          54 :     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND  ] = PROPERTYNAME_MERGEMENU_MERGECOMMAND;
     395          54 :     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER;
     396          54 :     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] = PROPERTYNAME_MERGEMENU_MERGEFALLBACK;
     397          54 :     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT  ] = PROPERTYNAME_MERGEMENU_MERGECONTEXT;
     398          54 :     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS     ] = PROPERTYNAME_MERGEMENU_MENUITEMS;
     399             : 
     400          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR               ] = PROPERTYNAME_MERGETOOLBAR_TOOLBAR;
     401          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT            ] = PROPERTYNAME_MERGETOOLBAR_MERGEPOINT;
     402          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND          ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND;
     403          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER;
     404          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK         ] = PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK;
     405          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT          ] = PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT;
     406          54 :     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS          ] = PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS;
     407             : 
     408             :     Reference< XComponentContext > xContext(
     409          54 :         comphelper::getProcessComponentContext() );
     410          54 :     m_xMacroExpander =  Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
     411          54 :                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
     412          54 :                                 UNO_QUERY );
     413             : 
     414          54 :     ReadConfigurationData();
     415             : 
     416             :     // Enable notification mechanism of ouer baseclass.
     417             :     // We need it to get information about changes outside these class on ouer used configuration keys!
     418          54 :     Sequence< rtl::OUString > aNotifySeq( 1 );
     419          54 :     aNotifySeq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AddonUI" ));
     420          54 :     EnableNotification( aNotifySeq );
     421          54 : }
     422             : 
     423             : //*****************************************************************************************************************
     424             : //  destructor
     425             : //*****************************************************************************************************************
     426        1152 : AddonsOptions_Impl::~AddonsOptions_Impl()
     427             : {
     428             :     // We must save our current values .. if user forget it!
     429          32 :     if( IsModified() == sal_True )
     430             :     {
     431           0 :         Commit();
     432             :     }
     433        1120 : }
     434             : 
     435          54 : void AddonsOptions_Impl::ReadConfigurationData()
     436             : {
     437             :     // reset members to be read again from configuration
     438          54 :     m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
     439          54 :     m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
     440          54 :     m_aCachedToolBarPartProperties = AddonToolBars();
     441          54 :     m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
     442          54 :     m_aCachedToolBarPartResourceNames.clear();
     443          54 :     m_aImageManager = ImageManager();
     444             : 
     445          54 :     ReadAddonMenuSet( m_aCachedMenuProperties );
     446          54 :     ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties );
     447          54 :     ReadOfficeToolBarSet( m_aCachedToolBarPartProperties, m_aCachedToolBarPartResourceNames );
     448          54 :     ReadOfficeHelpSet( m_aCachedHelpMenuProperties );
     449          54 :     ReadImages( m_aImageManager );
     450             : 
     451          54 :     m_aCachedMergeMenuInsContainer.clear();
     452          54 :     m_aCachedToolbarMergingInstructions.clear();
     453             : 
     454          54 :     ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer );
     455          54 :     ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions );
     456          54 : }
     457             : 
     458             : //*****************************************************************************************************************
     459             : //  public method
     460             : //*****************************************************************************************************************
     461           0 : void AddonsOptions_Impl::Notify( const Sequence< ::rtl::OUString >& /*lPropertyNames*/ )
     462             : {
     463           0 :     Application::PostUserEvent( STATIC_LINK( 0, AddonsOptions, Notify ) );
     464           0 : }
     465             : 
     466             : //*****************************************************************************************************************
     467             : //  public method
     468             : //*****************************************************************************************************************
     469           0 : void AddonsOptions_Impl::Commit()
     470             : {
     471             :     OSL_FAIL( "AddonsOptions_Impl::Commit()\nNot implemented yet!\n" );
     472           0 : }
     473             : 
     474             : //*****************************************************************************************************************
     475             : //  public method
     476             : //*****************************************************************************************************************
     477           2 : sal_Bool AddonsOptions_Impl::HasAddonsMenu() const
     478             : {
     479           2 :     return ( m_aCachedMenuProperties.getLength() > 0 );
     480             : }
     481             : 
     482             : //*****************************************************************************************************************
     483             : //  public method
     484             : //*****************************************************************************************************************
     485        1032 : sal_Int32 AddonsOptions_Impl::GetAddonsToolBarCount() const
     486             : {
     487        1032 :     return m_aCachedToolBarPartProperties.size();
     488             : }
     489             : 
     490             : //*****************************************************************************************************************
     491             : //  public method
     492             : //*****************************************************************************************************************
     493           0 : const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenu() const
     494             : {
     495           0 :     return m_aCachedMenuProperties;
     496             : }
     497             : 
     498             : //*****************************************************************************************************************
     499             : //  public method
     500             : //*****************************************************************************************************************
     501           2 : const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenuBarPart() const
     502             : {
     503           2 :     return m_aCachedMenuBarPartProperties;
     504             : }
     505             : 
     506             : //*****************************************************************************************************************
     507             : //  public method
     508             : //*****************************************************************************************************************
     509        1016 : const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
     510             : {
     511        1016 :     if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
     512        1016 :         return m_aCachedToolBarPartProperties[nIndex];
     513             :     else
     514           0 :         return m_aEmptyAddonToolBar;
     515             : }
     516             : 
     517             : //*****************************************************************************************************************
     518             : //  public method
     519             : //*****************************************************************************************************************
     520        1016 : const ::rtl::OUString AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
     521             : {
     522        1016 :     if ( nIndex < m_aCachedToolBarPartResourceNames.size() )
     523        1016 :         return m_aCachedToolBarPartResourceNames[nIndex];
     524             :     else
     525           0 :         return rtl::OUString();
     526             : }
     527             : 
     528             : //*****************************************************************************************************************
     529             : //  public method
     530             : //*****************************************************************************************************************
     531           2 : const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsHelpMenu  () const
     532             : {
     533           2 :     return m_aCachedHelpMenuProperties;
     534             : }
     535             : 
     536             : //*****************************************************************************************************************
     537             : //  public method
     538             : //*****************************************************************************************************************
     539           2 : const MergeMenuInstructionContainer& AddonsOptions_Impl::GetMergeMenuInstructions() const
     540             : {
     541           2 :     return m_aCachedMergeMenuInsContainer;
     542             : }
     543             : 
     544             : //*****************************************************************************************************************
     545             : //  public method
     546             : //*****************************************************************************************************************
     547           4 : bool AddonsOptions_Impl::GetMergeToolbarInstructions(
     548             :     const ::rtl::OUString& rToolbarName,
     549             :     MergeToolbarInstructionContainer& rToolbarInstructions ) const
     550             : {
     551           4 :     ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
     552           4 :     if ( pIter != m_aCachedToolbarMergingInstructions.end() )
     553             :     {
     554           0 :         rToolbarInstructions = pIter->second;
     555           0 :         return true;
     556             :     }
     557             :     else
     558           4 :         return false;
     559             : }
     560             : 
     561             : //*****************************************************************************************************************
     562             : //  public method
     563             : //*****************************************************************************************************************
     564        4782 : Image AddonsOptions_Impl::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const
     565             : {
     566        4782 :     Image aImage;
     567             : 
     568        4782 :     ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
     569        4782 :     if ( pIter != m_aImageManager.end() )
     570             :     {
     571          18 :         if ( bNoScale )
     572           0 :             aImage = ( bBig ? pIter->second.aImageBigNoScale : pIter->second.aImageSmallNoScale );
     573          18 :         if ( !aImage )
     574          18 :             aImage = ( bBig ? pIter->second.aImageBig : pIter->second.aImageSmall );
     575             :     }
     576             : 
     577        4782 :     return aImage;
     578             : }
     579             : 
     580             : //*****************************************************************************************************************
     581             : //  private method
     582             : //*****************************************************************************************************************
     583          54 : sal_Bool AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
     584             : {
     585             :     // Read the AddonMenu set and fill property sequences
     586          54 :     ::rtl::OUString             aAddonMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/AddonMenu" ));
     587          54 :     Sequence< ::rtl::OUString > aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
     588          54 :     ::rtl::OUString             aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
     589             : 
     590          54 :     sal_uInt32              nCount = aAddonMenuNodeSeq.getLength();
     591          54 :     sal_uInt32              nIndex = 0;
     592          54 :     Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
     593             : 
     594             :     // Init the property value sequence
     595          54 :     aMenuItem[ OFFSET_MENUITEM_URL              ].Name = m_aPropNames[ INDEX_URL            ];
     596          54 :     aMenuItem[ OFFSET_MENUITEM_TITLE            ].Name = m_aPropNames[ INDEX_TITLE          ];
     597          54 :     aMenuItem[ OFFSET_MENUITEM_TARGET           ].Name = m_aPropNames[ INDEX_TARGET         ];
     598          54 :     aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER  ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
     599          54 :     aMenuItem[ OFFSET_MENUITEM_CONTEXT          ].Name = m_aPropNames[ INDEX_CONTEXT        ];
     600          54 :     aMenuItem[ OFFSET_MENUITEM_SUBMENU          ].Name = m_aPropNames[ INDEX_SUBMENU        ];  // Submenu set!
     601             : 
     602          54 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     603             :     {
     604           0 :         ::rtl::OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
     605             : 
     606             :         // Read the MenuItem
     607           0 :         if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
     608             :         {
     609             :             // Successfully read a menu item, append to our list
     610           0 :             sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
     611           0 :             rAddonMenuSeq.realloc( nMenuItemCount );
     612           0 :             rAddonMenuSeq[nIndex++] = aMenuItem;
     613             :         }
     614           0 :     }
     615             : 
     616          54 :     return ( rAddonMenuSeq.getLength() > 0 );
     617             : }
     618             : 
     619             : //*****************************************************************************************************************
     620             : //  private method
     621             : //*****************************************************************************************************************
     622          54 : sal_Bool AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
     623             : {
     624             :     // Read the AddonMenu set and fill property sequences
     625          54 :     ::rtl::OUString             aAddonHelpMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeHelp" ));
     626          54 :     Sequence< ::rtl::OUString > aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
     627          54 :     ::rtl::OUString             aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
     628             : 
     629          54 :     sal_uInt32              nCount = aAddonHelpMenuNodeSeq.getLength();
     630          54 :     sal_uInt32              nIndex = 0;
     631          54 :     Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
     632             : 
     633             :     // Init the property value sequence
     634          54 :     aMenuItem[ OFFSET_MENUITEM_URL              ].Name = m_aPropNames[ INDEX_URL            ];
     635          54 :     aMenuItem[ OFFSET_MENUITEM_TITLE            ].Name = m_aPropNames[ INDEX_TITLE          ];
     636          54 :     aMenuItem[ OFFSET_MENUITEM_TARGET           ].Name = m_aPropNames[ INDEX_TARGET         ];
     637          54 :     aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER  ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
     638          54 :     aMenuItem[ OFFSET_MENUITEM_CONTEXT          ].Name = m_aPropNames[ INDEX_CONTEXT        ];
     639          54 :     aMenuItem[ OFFSET_MENUITEM_SUBMENU          ].Name = m_aPropNames[ INDEX_SUBMENU        ];  // Submenu set!
     640             : 
     641          54 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     642             :     {
     643           0 :         ::rtl::OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
     644             : 
     645             :         // Read the MenuItem
     646           0 :         if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, sal_True ) )
     647             :         {
     648             :             // Successfully read a menu item, append to our list
     649           0 :             sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
     650           0 :             rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
     651           0 :             rAddonOfficeHelpMenuSeq[nIndex++] = aMenuItem;
     652             :         }
     653           0 :     }
     654             : 
     655          54 :     return ( rAddonOfficeHelpMenuSeq.getLength() > 0 );
     656             : }
     657             : 
     658             : //*****************************************************************************************************************
     659             : //  private method
     660             : //*****************************************************************************************************************
     661          54 : sal_Bool AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
     662             : {
     663             :     // Read the OfficeMenuBar set and fill property sequences
     664          54 :     ::rtl::OUString             aAddonMenuBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBar" ));
     665          54 :     Sequence< ::rtl::OUString > aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
     666          54 :     ::rtl::OUString             aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
     667             : 
     668          54 :     sal_uInt32              nCount = aAddonMenuBarNodeSeq.getLength();
     669          54 :     sal_uInt32              nIndex = 0;
     670          54 :     Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
     671             : 
     672             :     // Init the property value sequence
     673          54 :     aPopupMenu[ OFFSET_POPUPMENU_TITLE      ].Name = m_aPropNames[ INDEX_TITLE  ];
     674          54 :     aPopupMenu[ OFFSET_POPUPMENU_CONTEXT    ].Name = m_aPropNames[ INDEX_CONTEXT];
     675          54 :     aPopupMenu[ OFFSET_POPUPMENU_SUBMENU    ].Name = m_aPropNames[ INDEX_SUBMENU];
     676          54 :     aPopupMenu[ OFFSET_POPUPMENU_URL        ].Name = m_aPropNames[ INDEX_URL    ];
     677             : 
     678          54 :     StringToIndexMap aTitleToIndexMap;
     679             : 
     680          54 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     681             :     {
     682           0 :         ::rtl::OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
     683             : 
     684             :         // Read the MenuItem
     685           0 :         if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
     686             :         {
     687             :             // Successfully read a popup menu, append to our list
     688           0 :             ::rtl::OUString aPopupTitle;
     689           0 :             if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
     690             :             {
     691           0 :                 StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
     692           0 :                 if ( pIter != aTitleToIndexMap.end() )
     693             :                 {
     694             :                     // title already there => concat both popup menus
     695           0 :                     Sequence< PropertyValue >& rOldPopupMenu = rAddonOfficeMenuBarSeq[pIter->second];
     696           0 :                     AppendPopupMenu( rOldPopupMenu, aPopupMenu );
     697             :                 }
     698             :                 else
     699             :                 {
     700             :                     // not found
     701           0 :                     sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
     702           0 :                     rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
     703           0 :                     rAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
     704           0 :                     aTitleToIndexMap.insert( StringToIndexMap::value_type( aPopupTitle, nIndex ));
     705           0 :                     ++nIndex;
     706             :                 }
     707           0 :             }
     708             :         }
     709           0 :     }
     710             : 
     711          54 :     return ( rAddonOfficeMenuBarSeq.getLength() > 0 );
     712             : }
     713             : 
     714             : //*****************************************************************************************************************
     715             : //  private method
     716             : //*****************************************************************************************************************
     717          54 : sal_Bool AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< rtl::OUString >& rAddonOfficeToolBarResNames )
     718             : {
     719             :     // Read the OfficeToolBar set and fill property sequences
     720          54 :     ::rtl::OUString             aAddonToolBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolBar" ));
     721          54 :     Sequence< ::rtl::OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
     722          54 :     ::rtl::OUString             aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
     723             : 
     724          54 :     sal_uInt32           nCount = aAddonToolBarNodeSeq.getLength();
     725             : 
     726         106 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     727             :     {
     728          52 :         ::rtl::OUString aToolBarItemNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] );
     729          52 :         rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
     730          52 :         rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
     731          52 :         ReadToolBarItemSet( aToolBarItemNode, rAddonOfficeToolBars[n] );
     732          52 :     }
     733             : 
     734          54 :     return ( !rAddonOfficeToolBars.empty() );
     735             : }
     736             : 
     737             : 
     738             : //*****************************************************************************************************************
     739             : //  private method
     740             : //*****************************************************************************************************************
     741          52 : sal_Bool AddonsOptions_Impl::ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
     742             : {
     743          52 :     sal_Bool                    bInsertSeparator        = sal_False;
     744          52 :     sal_uInt32                  nToolBarItemCount       = rAddonOfficeToolBarSeq.getLength();
     745          52 :     ::rtl::OUString                 aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
     746          52 :     Sequence< ::rtl::OUString >     aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
     747          52 :     Sequence< PropertyValue >   aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
     748             : 
     749             :     // Init the property value sequence
     750          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_URL                ].Name = m_aPropNames[ INDEX_URL            ];
     751          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_TITLE              ].Name = m_aPropNames[ INDEX_TITLE          ];
     752          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER    ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
     753          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_TARGET             ].Name = m_aPropNames[ INDEX_TARGET         ];
     754          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT            ].Name = m_aPropNames[ INDEX_CONTEXT        ];
     755          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE        ].Name = m_aPropNames[ INDEX_CONTROLTYPE    ];
     756          52 :     aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH              ].Name = m_aPropNames[ INDEX_WIDTH          ];
     757             : 
     758          52 :     sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
     759         572 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     760             :     {
     761         520 :         ::rtl::OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
     762             : 
     763             :         // Read the ToolBarItem
     764         520 :         if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
     765             :         {
     766         520 :             if ( bInsertSeparator )
     767             :             {
     768           0 :                 bInsertSeparator = sal_False;
     769           0 :                 InsertToolBarSeparator( rAddonOfficeToolBarSeq );
     770             :             }
     771             : 
     772             :             // Successfully read a toolbar item, append to our list
     773         520 :             sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
     774         520 :             rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
     775         520 :             rAddonOfficeToolBarSeq[nAddonCount] = aToolBarItem;
     776             :         }
     777         520 :     }
     778             : 
     779          52 :     return ( (sal_uInt32)rAddonOfficeToolBarSeq.getLength() > nToolBarItemCount );
     780             : }
     781             : 
     782             : //*****************************************************************************************************************
     783             : //  private method
     784             : //*****************************************************************************************************************
     785           0 : void AddonsOptions_Impl::InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
     786             : {
     787           0 :     Sequence< PropertyValue >   aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
     788             : 
     789           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_URL                ].Name = m_aPropNames[ INDEX_URL            ];
     790           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_TITLE              ].Name = m_aPropNames[ INDEX_TITLE          ];
     791           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER    ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
     792           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_TARGET             ].Name = m_aPropNames[ INDEX_TARGET         ];
     793           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT            ].Name = m_aPropNames[ INDEX_CONTEXT        ];
     794             : 
     795           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_URL                ].Value <<= SEPARATOR_URL;
     796           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_TITLE              ].Value <<= m_aEmpty;
     797           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_TARGET             ].Value <<= m_aEmpty;
     798           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER    ].Value <<= m_aEmpty;
     799           0 :     aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT            ].Value <<= m_aEmpty;
     800             : 
     801           0 :     sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
     802           0 :     rAddonOfficeToolBarSeq.realloc( nToolBarItemCount+1 );
     803           0 :     rAddonOfficeToolBarSeq[nToolBarItemCount] = aToolBarItem;
     804           0 : }
     805             : 
     806             : //*****************************************************************************************************************
     807             : //  private method
     808             : //*****************************************************************************************************************
     809          54 : sal_Bool AddonsOptions_Impl::ReadImages( ImageManager& aImageManager )
     810             : {
     811             :     // Read the user-defined Images set and fill image manager
     812          54 :     ::rtl::OUString                aAddonImagesNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/Images" ));
     813          54 :     Sequence< ::rtl::OUString > aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
     814          54 :     ::rtl::OUString                aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
     815             : 
     816          54 :     sal_uInt32              nCount = aAddonImagesNodeSeq.getLength();
     817             : 
     818             :     // Init the property value sequence
     819          54 :     Sequence< ::rtl::OUString > aAddonImageItemNodePropNames( 1 );
     820          54 :     ::rtl::OUString                aURL;
     821             : 
     822         524 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
     823             :     {
     824         470 :         ::rtl::OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
     825             : 
     826             :         // Create sequence for data access
     827         470 :         ::rtl::OUStringBuffer aBuffer( aImagesItemNode );
     828         470 :         aBuffer.append( m_aPathDelimiter );
     829         470 :         aBuffer.append( m_aPropNames[ OFFSET_MENUITEM_URL ] );
     830         470 :         aAddonImageItemNodePropNames[0] = aBuffer.makeStringAndClear();
     831             : 
     832         470 :         Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
     833             : 
     834             :         // An user-defined image entry must have an URL. As "ImageIdentifier" has a higher priority
     835             :         // we also check if we already have an images association.
     836        1410 :         if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
     837         470 :             !aURL.isEmpty() &&
     838         470 :             !HasAssociatedImages( aURL ))
     839             :         {
     840         470 :             ::rtl::OUStringBuffer aBuf( aImagesItemNode );
     841         470 :             aBuf.append( m_aPathDelimiter );
     842         470 :             aBuf.append( IMAGES_NODENAME );
     843         470 :             aBuf.append( m_aPathDelimiter );
     844         470 :             ::rtl::OUString aImagesUserDefinedItemNode = aBuf.makeStringAndClear();
     845             : 
     846             :             // Read a user-defined images data
     847         470 :             ImageEntry* pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
     848         470 :             if ( pImageEntry )
     849             :             {
     850             :                 // Successfully read a user-defined images item, put it into our image manager
     851          20 :                 aImageManager.insert( ImageManager::value_type( aURL, *pImageEntry ));
     852          20 :                 delete pImageEntry; // We have the ownership of the pointer
     853         470 :             }
     854             :         }
     855         470 :     }
     856             : 
     857          54 :     return sal_True;
     858             : }
     859             : 
     860             : //*****************************************************************************************************************
     861             : //  private method
     862             : //*****************************************************************************************************************
     863             : 
     864           0 : ::rtl::OUString AddonsOptions_Impl::GeneratePrefixURL()
     865             : {
     866             :     // Create an unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
     867             :     // They use a different image manager, so they must be identified by the sfx2/framework code.
     868           0 :     ::rtl::OUString aPopupMenuURL;
     869           0 :     ::rtl::OUStringBuffer aBuf( m_aRootAddonPopupMenuURLPrexfix.getLength() + 3 );
     870           0 :     aBuf.append( m_aRootAddonPopupMenuURLPrexfix );
     871           0 :     aBuf.append( ::rtl::OUString::valueOf( ++m_nRootAddonPopupMenuId ));
     872           0 :     aPopupMenuURL = aBuf.makeStringAndClear();
     873           0 :     return aPopupMenuURL;
     874             : }
     875             : 
     876             : //*****************************************************************************************************************
     877             : //  private method
     878             : //*****************************************************************************************************************
     879             : 
     880          54 : sal_Bool AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer& aContainer )
     881             : {
     882          54 :     const ::rtl::OUString aMenuMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBarMerging/" ));
     883             : 
     884          54 :     Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
     885          54 :     ::rtl::OUString                aAddonMergeNode( aMenuMergeRootName );
     886             : 
     887          54 :     sal_uInt32              nCount = aAddonMergeNodesSeq.getLength();
     888             : 
     889             :     // Init the property value sequence
     890          54 :     Sequence< ::rtl::OUString > aNodePropNames( 5 );
     891          54 :     ::rtl::OUString                aURL;
     892             : 
     893          56 :     for ( sal_uInt32 i = 0; i < nCount; i++ )
     894             :     {
     895           2 :         ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
     896             : 
     897           2 :         Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
     898           2 :         sal_uInt32           nCountAddons = aAddonInstMergeNodesSeq.getLength();
     899             : 
     900           4 :         for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
     901             :         {
     902           2 :             ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
     903           2 :             aMergeAddonInstructionBase.append( m_aPathDelimiter );
     904           2 :             aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
     905           2 :             aMergeAddonInstructionBase.append( m_aPathDelimiter );
     906             : 
     907             :             // Create sequence for data access
     908           2 :             ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
     909           2 :             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
     910           2 :             aNodePropNames[0] = aBuffer.makeStringAndClear();
     911             : 
     912           2 :             aBuffer = aMergeAddonInstructionBase;
     913           2 :             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
     914           2 :             aNodePropNames[1] = aBuffer.makeStringAndClear();
     915             : 
     916           2 :             aBuffer = aMergeAddonInstructionBase;
     917           2 :             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
     918           2 :             aNodePropNames[2] = aBuffer.makeStringAndClear();
     919             : 
     920           2 :             aBuffer = aMergeAddonInstructionBase;
     921           2 :             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
     922           2 :             aNodePropNames[3] = aBuffer.makeStringAndClear();
     923             : 
     924           2 :             aBuffer = aMergeAddonInstructionBase;
     925           2 :             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
     926           2 :             aNodePropNames[4] = aBuffer.makeStringAndClear();
     927             : 
     928           2 :             Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
     929             : 
     930           2 :             MergeMenuInstruction aMergeMenuInstruction;
     931           2 :             aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
     932           2 :             aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
     933           2 :             aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
     934           2 :             aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
     935           2 :             aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
     936             : 
     937           2 :             ::rtl::OUString aMergeMenuBase = aMergeAddonInstructionBase.makeStringAndClear();
     938           2 :             ReadMergeMenuData( aMergeMenuBase, aMergeMenuInstruction.aMergeMenu );
     939             : 
     940           2 :             aContainer.push_back( aMergeMenuInstruction );
     941           2 :         }
     942           2 :     }
     943             : 
     944          54 :     return sal_True;
     945             : }
     946             : 
     947             : //*****************************************************************************************************************
     948             : //  private method
     949             : //*****************************************************************************************************************
     950           2 : sal_Bool AddonsOptions_Impl::ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
     951             : {
     952           2 :     ::rtl::OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
     953             : 
     954           2 :     Sequence< ::rtl::OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
     955           2 :     aMergeMenuBaseNode += m_aPathDelimiter;
     956             : 
     957             :     // extend the node names to have full path strings
     958           6 :     for ( sal_uInt32 i = 0; i < (sal_uInt32)aSubMenuNodeNames.getLength(); i++ )
     959           4 :         aSubMenuNodeNames[i] = ::rtl::OUString( aMergeMenuBaseNode + aSubMenuNodeNames[i] );
     960             : 
     961           2 :     return ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
     962             : }
     963             : 
     964             : //*****************************************************************************************************************
     965             : //  private method
     966             : //*****************************************************************************************************************
     967          54 : sal_Bool AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions& rCachedToolbarMergingInstructions )
     968             : {
     969          54 :     const ::rtl::OUString aToolbarMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolbarMerging/" ));
     970             : 
     971          54 :     Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
     972          54 :     ::rtl::OUString                aAddonMergeNode( aToolbarMergeRootName );
     973             : 
     974          54 :     sal_uInt32              nCount = aAddonMergeNodesSeq.getLength();
     975             : 
     976             :     // Init the property value sequence
     977          54 :     Sequence< ::rtl::OUString > aNodePropNames( 6 );
     978          54 :     ::rtl::OUString                aURL;
     979             : 
     980          54 :     for ( sal_uInt32 i = 0; i < nCount; i++ )
     981             :     {
     982           0 :         ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
     983             : 
     984           0 :         Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
     985           0 :         sal_uInt32           nCountAddons = aAddonInstMergeNodesSeq.getLength();
     986             : 
     987           0 :         for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
     988             :         {
     989           0 :             ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
     990           0 :             aMergeAddonInstructionBase.append( m_aPathDelimiter );
     991           0 :             aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
     992           0 :             aMergeAddonInstructionBase.append( m_aPathDelimiter );
     993             : 
     994             :             // Create sequence for data access
     995           0 :             ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
     996           0 :             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] );
     997           0 :             aNodePropNames[0] = aBuffer.makeStringAndClear();
     998             : 
     999           0 :             aBuffer = aMergeAddonInstructionBase;
    1000           0 :             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] );
    1001           0 :             aNodePropNames[1] = aBuffer.makeStringAndClear();
    1002             : 
    1003           0 :             aBuffer = aMergeAddonInstructionBase;
    1004           0 :             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] );
    1005           0 :             aNodePropNames[2] = aBuffer.makeStringAndClear();
    1006             : 
    1007           0 :             aBuffer = aMergeAddonInstructionBase;
    1008           0 :             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] );
    1009           0 :             aNodePropNames[3] = aBuffer.makeStringAndClear();
    1010             : 
    1011           0 :             aBuffer = aMergeAddonInstructionBase;
    1012           0 :             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] );
    1013           0 :             aNodePropNames[4] = aBuffer.makeStringAndClear();
    1014             : 
    1015           0 :             aBuffer = aMergeAddonInstructionBase;
    1016           0 :             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] );
    1017           0 :             aNodePropNames[5] = aBuffer.makeStringAndClear();
    1018             : 
    1019           0 :             Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
    1020             : 
    1021           0 :             MergeToolbarInstruction aMergeToolbarInstruction;
    1022           0 :             aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
    1023           0 :             aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
    1024           0 :             aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
    1025           0 :             aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
    1026           0 :             aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
    1027           0 :             aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
    1028             : 
    1029             :             ReadMergeToolbarData( aMergeAddonInstructionBase.makeStringAndClear(),
    1030           0 :                                   aMergeToolbarInstruction.aMergeToolbarItems );
    1031             : 
    1032           0 :             MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
    1033           0 :             rVector.push_back( aMergeToolbarInstruction );
    1034           0 :         }
    1035           0 :     }
    1036             : 
    1037          54 :     return sal_True;
    1038             : }
    1039             : 
    1040             : //*****************************************************************************************************************
    1041             : //  private method
    1042             : //*****************************************************************************************************************
    1043           0 : sal_Bool AddonsOptions_Impl::ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
    1044             : {
    1045           0 :     ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
    1046           0 :     aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] );
    1047             : 
    1048           0 :     ::rtl::OUString aMergeToolbarBaseNode = aBuffer.makeStringAndClear();
    1049             : 
    1050           0 :     return ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
    1051             : }
    1052             : 
    1053             : //*****************************************************************************************************************
    1054             : //  private method
    1055             : //*****************************************************************************************************************
    1056           4 : sal_Bool AddonsOptions_Impl::ReadMenuItem( const ::rtl::OUString& aMenuNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu )
    1057             : {
    1058           4 :     sal_Bool            bResult = sal_False;
    1059           4 :     ::rtl::OUString         aStrValue;
    1060           4 :     ::rtl::OUString         aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
    1061           4 :     Sequence< Any >     aMenuItemNodePropValues;
    1062             : 
    1063           4 :     aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
    1064           4 :     if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && !aStrValue.isEmpty() )
    1065             :     {
    1066           2 :         aMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
    1067             : 
    1068           2 :         ::rtl::OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
    1069           2 :         Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
    1070           2 :         if ( aRootSubMenuNodeNames.getLength() > 0 && !bIgnoreSubMenu )
    1071             :         {
    1072             :             // Set a unique prefixed Add-On popup menu URL so it can be identified later
    1073           0 :             ::rtl::OUString aPopupMenuURL     = GeneratePrefixURL();
    1074           0 :             ::rtl::OUString aPopupMenuImageId;
    1075             : 
    1076           0 :             aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
    1077           0 :             ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
    1078             : 
    1079             :             // A popup menu must have a title and can have a URL and ImageIdentifier
    1080             :             // Set the other property values to empty
    1081           0 :             aMenuItem[ OFFSET_MENUITEM_URL              ].Value <<= aPopupMenuURL;
    1082           0 :             aMenuItem[ OFFSET_MENUITEM_TARGET           ].Value <<= m_aEmpty;
    1083           0 :             aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER  ].Value <<= aPopupMenuImageId;
    1084           0 :             aMenuItem[ OFFSET_MENUITEM_CONTEXT          ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
    1085             : 
    1086             :             // Continue to read the sub menu nodes
    1087           0 :             Sequence< Sequence< PropertyValue > > aSubMenuSeq;
    1088           0 :             ::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
    1089           0 :             for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
    1090           0 :                 aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
    1091           0 :             ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
    1092           0 :             aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
    1093           0 :             bResult = sal_True;
    1094             :         }
    1095           2 :         else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && !aStrValue.isEmpty() )
    1096             :         {
    1097             :             // A simple menu item => read the other properties;
    1098           2 :             ::rtl::OUString aMenuImageId;
    1099             : 
    1100           2 :             aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
    1101           2 :              ReadAndAssociateImages( aStrValue, aMenuImageId );
    1102             : 
    1103           2 :             aMenuItem[ OFFSET_MENUITEM_URL              ].Value <<= aStrValue;
    1104           2 :             aMenuItem[ OFFSET_MENUITEM_TARGET           ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET         ];
    1105           2 :             aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER  ].Value <<= aMenuImageId;
    1106           2 :             aMenuItem[ OFFSET_MENUITEM_CONTEXT          ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT        ];
    1107           2 :             aMenuItem[ OFFSET_MENUITEM_SUBMENU          ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
    1108             : 
    1109           2 :             bResult = sal_True;
    1110           2 :         }
    1111             :     }
    1112           4 :     else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
    1113           2 :               aStrValue.equalsAsciiL( SEPARATOR_URL_STR, SEPARATOR_URL_LEN ))
    1114             :     {
    1115             :         // Separator
    1116           2 :         aMenuItem[ OFFSET_MENUITEM_URL              ].Value <<= aStrValue;
    1117           2 :         aMenuItem[ OFFSET_MENUITEM_TARGET           ].Value <<= m_aEmpty;
    1118           2 :         aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER  ].Value <<= m_aEmpty;
    1119           2 :         aMenuItem[ OFFSET_MENUITEM_CONTEXT          ].Value <<= m_aEmpty;
    1120           2 :         aMenuItem[ OFFSET_MENUITEM_SUBMENU          ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
    1121           2 :         bResult = sal_True;
    1122             :     }
    1123             : 
    1124           4 :     return bResult;
    1125             : }
    1126             : 
    1127             : //*****************************************************************************************************************
    1128             : //  private method
    1129             : //*****************************************************************************************************************
    1130           0 : sal_Bool AddonsOptions_Impl::ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
    1131             : {
    1132           0 :     sal_Bool            bResult = sal_False;
    1133           0 :     ::rtl::OUString         aStrValue;
    1134           0 :     ::rtl::OUString         aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
    1135           0 :     Sequence< Any >     aPopupMenuNodePropValues;
    1136             : 
    1137           0 :     aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
    1138           0 :     if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
    1139           0 :          !aStrValue.isEmpty() )
    1140             :     {
    1141           0 :         aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
    1142             : 
    1143           0 :         ::rtl::OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
    1144           0 :         Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
    1145           0 :         if ( aRootSubMenuNodeNames.getLength() > 0 )
    1146             :         {
    1147             :             // A top-level popup menu needs a title
    1148             :             // Set a unique prefixed Add-On popup menu URL so it can be identified later
    1149           0 :             ::rtl::OUString aPopupMenuURL = GeneratePrefixURL();
    1150             : 
    1151           0 :             aPopupMenu[ OFFSET_POPUPMENU_URL        ].Value <<= aPopupMenuURL;
    1152           0 :             aPopupMenu[ OFFSET_POPUPMENU_CONTEXT    ].Value <<= aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
    1153             : 
    1154             :             // Continue to read the sub menu nodes
    1155           0 :             Sequence< Sequence< PropertyValue > > aSubMenuSeq;
    1156           0 :             ::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
    1157           0 :             for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
    1158           0 :                 aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
    1159           0 :             ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
    1160           0 :             aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
    1161           0 :             bResult = sal_True;
    1162           0 :         }
    1163             :     }
    1164             : 
    1165           0 :     return bResult;
    1166             : }
    1167             : 
    1168             : //*****************************************************************************************************************
    1169             : //  private method
    1170             : //*****************************************************************************************************************
    1171           0 : sal_Bool AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
    1172             : {
    1173           0 :     Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
    1174           0 :     Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
    1175             : 
    1176           0 :     if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
    1177           0 :         ( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
    1178             :     {
    1179           0 :         sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
    1180           0 :         aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
    1181           0 :         for ( sal_uInt32 i = 0; i < sal_uInt32( aSourceSubMenuSeq.getLength() ); i++ )
    1182           0 :             aTargetSubMenuSeq[nIndex++] = aSourceSubMenuSeq[i];
    1183           0 :         rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
    1184             :     }
    1185             : 
    1186           0 :     return sal_True;
    1187             : }
    1188             : 
    1189             : //*****************************************************************************************************************
    1190             : //  private method
    1191             : //*****************************************************************************************************************
    1192         520 : sal_Bool AddonsOptions_Impl::ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
    1193             : {
    1194         520 :     sal_Bool            bResult = sal_False;
    1195         520 :     ::rtl::OUString         aTitle;
    1196         520 :     ::rtl::OUString         aURL;
    1197         520 :     ::rtl::OUString         aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
    1198         520 :     Sequence< Any >     aToolBarItemNodePropValues;
    1199             : 
    1200         520 :     aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
    1201             : 
    1202             :     // A toolbar item must have a command URL
    1203         520 :     if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && !aURL.isEmpty() )
    1204             :     {
    1205         520 :         if ( aURL.equals( SEPARATOR_URL ))
    1206             :         {
    1207             :             // A speparator toolbar item only needs a URL
    1208           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_URL                ].Value <<= aURL;
    1209           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_TITLE              ].Value <<= m_aEmpty;
    1210           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_TARGET             ].Value <<= m_aEmpty;
    1211           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER    ].Value <<= m_aEmpty;
    1212           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT            ].Value <<= m_aEmpty;
    1213           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE        ].Value <<= m_aEmpty;
    1214           0 :             aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH              ].Value <<= sal_Int32( 0 );
    1215             : 
    1216           0 :             bResult = sal_True;
    1217             :         }
    1218         520 :         else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE ] >>= aTitle ) && !aTitle.isEmpty() )
    1219             :         {
    1220             :             // A normal toolbar item must also have title => read the other properties;
    1221         520 :             ::rtl::OUString aImageId;
    1222             : 
    1223             :             // Try to map a user-defined image URL to our internal private image URL
    1224         520 :             aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
    1225         520 :              ReadAndAssociateImages( aURL, aImageId );
    1226             : 
    1227         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_URL                ].Value <<= aURL;
    1228         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_TITLE              ].Value <<= aTitle;
    1229         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_TARGET             ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET      ];
    1230         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER    ].Value <<= aImageId;
    1231         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT            ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT     ];
    1232         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE        ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
    1233             : 
    1234             :             // Configuration uses hyper for long. Therefore transform into sal_Int32
    1235         520 :             sal_Int64 nValue( 0 );
    1236         520 :             aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
    1237         520 :             aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH              ].Value <<= sal_Int32( nValue );
    1238             : 
    1239         520 :             bResult = sal_True;
    1240             :         }
    1241             :     }
    1242             : 
    1243         520 :     return bResult;
    1244             : }
    1245             : 
    1246             : //*****************************************************************************************************************
    1247             : //  private method
    1248             : //*****************************************************************************************************************
    1249           2 : sal_Bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
    1250             : {
    1251           2 :     Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
    1252             : 
    1253             :     // Init the property value sequence
    1254           2 :     aMenuItem[ OFFSET_MENUITEM_URL              ].Name = PROPERTYNAME_URL;
    1255           2 :     aMenuItem[ OFFSET_MENUITEM_TITLE            ].Name = PROPERTYNAME_TITLE;
    1256           2 :     aMenuItem[ OFFSET_MENUITEM_TARGET           ].Name = PROPERTYNAME_TARGET;
    1257           2 :     aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER  ].Name = PROPERTYNAME_IMAGEIDENTIFIER;
    1258           2 :     aMenuItem[ OFFSET_MENUITEM_CONTEXT          ].Name = PROPERTYNAME_CONTEXT;
    1259           2 :     aMenuItem[ OFFSET_MENUITEM_SUBMENU          ].Name = PROPERTYNAME_SUBMENU;  // Submenu set!
    1260             : 
    1261           2 :     sal_uInt32 nIndex = 0;
    1262           2 :     sal_uInt32 nCount = aSubMenuNodeNames.getLength();
    1263           6 :     for ( sal_uInt32 n = 0; n < nCount; n++ )
    1264             :     {
    1265           4 :         if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
    1266             :         {
    1267           4 :             sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
    1268           4 :             rSubMenuSeq.realloc( nSubMenuCount );
    1269           4 :             rSubMenuSeq[nIndex++] = aMenuItem;
    1270             :         }
    1271             :     }
    1272             : 
    1273           2 :     return sal_True;
    1274             : }
    1275             : 
    1276             : //*****************************************************************************************************************
    1277             : //  private method
    1278             : //*****************************************************************************************************************
    1279         470 : sal_Bool AddonsOptions_Impl::HasAssociatedImages( const ::rtl::OUString& aURL )
    1280             : {
    1281         470 :     ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
    1282         470 :     return ( pIter != m_aImageManager.end() );
    1283             : }
    1284             : 
    1285             : //*****************************************************************************************************************
    1286             : //  private method
    1287             : //*****************************************************************************************************************
    1288        1880 : void AddonsOptions_Impl::SubstituteVariables( ::rtl::OUString& aURL )
    1289             : {
    1290        2824 :     if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
    1291         944 :         m_xMacroExpander.is() )
    1292             :     {
    1293             :         // cut protocol
    1294         944 :         ::rtl::OUString macro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
    1295             :         // decode uric class chars
    1296             :         macro = ::rtl::Uri::decode(
    1297         944 :             macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
    1298             :         // expand macro string
    1299         944 :         aURL = m_xMacroExpander->expandMacros( macro );
    1300             :     }
    1301        1880 : }
    1302             : 
    1303             : //*****************************************************************************************************************
    1304             : //  private method
    1305             : //*****************************************************************************************************************
    1306        1880 : void AddonsOptions_Impl::ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aImageURL, Image& aImage, Image& aImageNoScale )
    1307             : {
    1308        1880 :     SvStream* pStream = UcbStreamHelper::CreateStream( aImageURL, STREAM_STD_READ );
    1309        1880 :     if ( pStream && ( pStream->GetErrorCode() == 0 ))
    1310             :     {
    1311             :         // Use graphic class to also support more graphic formats (bmp,png,...)
    1312          76 :         Graphic aGraphic;
    1313             : 
    1314          76 :         GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
    1315          76 :         rGF.ImportGraphic( aGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW );
    1316             : 
    1317          76 :         BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
    1318             : 
    1319          76 :         const Size aSize = ( nImageSize == IMGSIZE_SMALL ) ? aImageSizeSmall : aImageSizeBig; // Sizes used for menu/toolbox images
    1320             : 
    1321          76 :         Size aBmpSize = aBitmapEx.GetSizePixel();
    1322          76 :         if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
    1323             :         {
    1324             :             // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
    1325          76 :             if( !aBitmapEx.IsTransparent() )
    1326           0 :                 aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
    1327             : 
    1328             :             // A non-scaled bitmap can have a flexible width, but must have a defined height!
    1329          76 :             Size aNoScaleSize( aBmpSize.Width(), aSize.Height() );
    1330          76 :             if ( aBmpSize != aNoScaleSize )
    1331             :             {
    1332          18 :                 BitmapEx aNoScaleBmp( aBitmapEx );
    1333          18 :                 aNoScaleBmp.Scale( aNoScaleSize, BMP_SCALE_BEST );
    1334             :             }
    1335             :             else
    1336          58 :                 aImageNoScale = Image( aBitmapEx );
    1337             : 
    1338          76 :             if ( aBmpSize != aSize )
    1339          18 :                 aBitmapEx.Scale( aSize, BMP_SCALE_BEST );
    1340             : 
    1341          76 :             aImage = Image( aBitmapEx );
    1342          76 :         }
    1343             :     }
    1344             : 
    1345        1880 :     delete pStream;
    1346        1880 : }
    1347             : 
    1348             : //*****************************************************************************************************************
    1349             : //  private method
    1350             : //*****************************************************************************************************************
    1351         522 : void AddonsOptions_Impl::ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId )
    1352             : {
    1353         522 :     const int   MAX_NUM_IMAGES = 2;
    1354         522 :     const char* aExtArray[MAX_NUM_IMAGES] = { "_16", "_26" };
    1355         522 :     const char* pBmpExt = ".bmp";
    1356             : 
    1357         522 :     if ( aImageId.isEmpty() )
    1358         522 :         return;
    1359             : 
    1360           0 :     bool        bImageFound = true;
    1361           0 :     ImageEntry  aImageEntry;
    1362           0 :     ::rtl::OUString    aImageURL( aImageId );
    1363             : 
    1364           0 :     SubstituteVariables( aImageURL );
    1365             : 
    1366             :     // Loop to create the four possible image names and try to read the bitmap files
    1367           0 :     for ( int i = 0; i < MAX_NUM_IMAGES; i++ )
    1368             :     {
    1369           0 :         ::rtl::OUStringBuffer aFileURL( aImageURL );
    1370           0 :         aFileURL.appendAscii( aExtArray[i] );
    1371           0 :         aFileURL.appendAscii( pBmpExt );
    1372             : 
    1373           0 :         Image aImage;
    1374           0 :         Image aImageNoScale;
    1375           0 :         ReadImageFromURL( ((i==0)||(i==2)) ? IMGSIZE_SMALL : IMGSIZE_BIG, aFileURL.makeStringAndClear(), aImage, aImageNoScale );
    1376           0 :         if ( !!aImage )
    1377             :         {
    1378           0 :             bImageFound = true;
    1379           0 :             switch ( i )
    1380             :             {
    1381             :                 case 0:
    1382           0 :                     aImageEntry.aImageSmall          = aImage;
    1383           0 :                     aImageEntry.aImageSmallNoScale   = aImageNoScale;
    1384           0 :                     break;
    1385             :                 case 1:
    1386           0 :                     aImageEntry.aImageBig            = aImage;
    1387           0 :                     aImageEntry.aImageBigNoScale     = aImageNoScale;
    1388           0 :                     break;
    1389             :             }
    1390             :         }
    1391           0 :     }
    1392             : 
    1393           0 :     if ( bImageFound )
    1394           0 :         m_aImageManager.insert( ImageManager::value_type( aURL, aImageEntry ));
    1395             : }
    1396             : 
    1397             : //*****************************************************************************************************************
    1398             : //  private method
    1399             : //*****************************************************************************************************************
    1400         470 : AddonsOptions_Impl::ImageEntry* AddonsOptions_Impl::ReadImageData( const ::rtl::OUString& aImagesNodeName )
    1401             : {
    1402         470 :     Sequence< ::rtl::OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
    1403         470 :     Sequence< Any >      aPropertyData;
    1404         470 :     Sequence< sal_Int8 > aImageDataSeq;
    1405         470 :     ::rtl::OUString             aImageURL;
    1406             : 
    1407         470 :     ImageEntry* pEntry = NULL;
    1408             : 
    1409             :     // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
    1410             :     // same time. Embedded image data has a higher priority.
    1411         470 :     aPropertyData = GetProperties( aImageDataNodeNames );
    1412        4230 :     for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
    1413             :     {
    1414        3760 :         if ( i < PROPERTYCOUNT_EMBEDDED_IMAGES )
    1415             :         {
    1416             :             // Extract image data from the embedded hex binary sequence
    1417        1880 :             Image aImage;
    1418        1880 :             if (( aPropertyData[i] >>= aImageDataSeq ) &&
    1419           0 :                 aImageDataSeq.getLength() > 0 &&
    1420             :                 ( CreateImageFromSequence( aImage,
    1421             :                                         ( i == OFFSET_IMAGES_BIG ),
    1422           0 :                                         aImageDataSeq )) )
    1423             :             {
    1424           0 :                 if ( !pEntry )
    1425           0 :                     pEntry = new ImageEntry;
    1426             : 
    1427           0 :                 if ( i == OFFSET_IMAGES_SMALL )
    1428           0 :                     pEntry->aImageSmall = aImage;
    1429           0 :                 else if ( i == OFFSET_IMAGES_BIG )
    1430           0 :                     pEntry->aImageBig = aImage;
    1431        1880 :             }
    1432             :         }
    1433             :         else
    1434             :         {
    1435             :             // Retrieve image data from a external bitmap file. Make sure that embedded image data
    1436             :             // has a higher priority.
    1437        1880 :             aPropertyData[i] >>= aImageURL;
    1438             : 
    1439        1880 :             if ( !aImageURL.isEmpty() )
    1440             :             {
    1441        1880 :                 Image aImage;
    1442        1880 :                 Image aImageNoScale;
    1443             : 
    1444        1880 :                 SubstituteVariables( aImageURL );
    1445             :                 ReadImageFromURL( ((i==OFFSET_IMAGES_SMALL_URL)||(i==OFFSET_IMAGES_SMALLHC_URL)) ? IMGSIZE_SMALL : IMGSIZE_BIG,
    1446        1880 :                                   aImageURL, aImage, aImageNoScale );
    1447        1880 :                 if ( !!aImage )
    1448             :                 {
    1449          76 :                     if ( !pEntry )
    1450          20 :                         pEntry = new ImageEntry;
    1451             : 
    1452          76 :                     if ( i == OFFSET_IMAGES_SMALL_URL && !pEntry->aImageSmall )
    1453             :                     {
    1454          20 :                         pEntry->aImageSmall = aImage;
    1455          20 :                         pEntry->aImageSmallNoScale = aImageNoScale;
    1456             :                     }
    1457          56 :                     else if ( !pEntry->aImageBig )
    1458             :                     {
    1459          20 :                         pEntry->aImageBig = aImage;
    1460          20 :                         pEntry->aImageBigNoScale = aImageNoScale;
    1461             :                     }
    1462        1880 :                 }
    1463             :             }
    1464             :         }
    1465             :     }
    1466             : 
    1467         470 :     return pEntry;
    1468             : }
    1469             : 
    1470             : //*****************************************************************************************************************
    1471             : //  private method
    1472             : //*****************************************************************************************************************
    1473           0 : sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const
    1474             : {
    1475           0 :     sal_Bool    bResult = sal_False;
    1476           0 :     Size        aSize = bBig ? aImageSizeBig : aImageSizeSmall; // Sizes used for menu/toolbox images
    1477             : 
    1478           0 :     if ( rBitmapDataSeq.getLength() > 0 )
    1479             :     {
    1480           0 :         SvMemoryStream  aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ );
    1481           0 :         BitmapEx        aBitmapEx;
    1482             : 
    1483           0 :         aMemStream >> aBitmapEx;
    1484             : 
    1485             :         // Scale bitmap to fit the correct size for the menu/toolbar. Use best quality
    1486           0 :         if ( aBitmapEx.GetSizePixel() != aSize )
    1487           0 :             aBitmapEx.Scale( aSize, BMP_SCALE_BEST );
    1488             : 
    1489           0 :         if( !aBitmapEx.IsTransparent() )
    1490             :         {
    1491             :             // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
    1492           0 :             aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
    1493             :         }
    1494             : 
    1495           0 :         rImage = Image( aBitmapEx );
    1496           0 :         bResult = sal_True;
    1497             :     }
    1498             : 
    1499           0 :     return bResult;
    1500             : }
    1501             : 
    1502           4 : Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const
    1503             : {
    1504           4 :     Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MENUITEM );
    1505             : 
    1506             :     // Create property names dependent from the root node name
    1507           4 :     lResult[OFFSET_MENUITEM_URL]             = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL          ] );
    1508           4 :     lResult[OFFSET_MENUITEM_TITLE]           = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE            ] );
    1509           4 :     lResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ] );
    1510           4 :     lResult[OFFSET_MENUITEM_TARGET]          = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET           ] );
    1511           4 :     lResult[OFFSET_MENUITEM_CONTEXT]         = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT      ] );
    1512           4 :     lResult[OFFSET_MENUITEM_SUBMENU]         = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU      ] );
    1513             : 
    1514           4 :     return lResult;
    1515             : }
    1516             : 
    1517             : //*****************************************************************************************************************
    1518             : //  private method
    1519             : //*****************************************************************************************************************
    1520           0 : Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const
    1521             : {
    1522             :     // The URL is automatically set and not read from the configuration.
    1523           0 :     Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
    1524             : 
    1525             :     // Create property names dependent from the root node name
    1526           0 :     lResult[OFFSET_POPUPMENU_TITLE]   = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE  ] );
    1527           0 :     lResult[OFFSET_POPUPMENU_CONTEXT] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT    ] );
    1528           0 :     lResult[OFFSET_POPUPMENU_SUBMENU] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU    ] );
    1529             : 
    1530           0 :     return lResult;
    1531             : }
    1532             : 
    1533             : //*****************************************************************************************************************
    1534             : //  private method
    1535             : //*****************************************************************************************************************
    1536         520 : Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const
    1537             : {
    1538         520 :     Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
    1539             : 
    1540             :     // Create property names dependent from the root node name
    1541         520 :     lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL             ] );
    1542         520 :     lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE       ] );
    1543         520 :     lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER] );
    1544         520 :     lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET          ] );
    1545         520 :     lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT         ] );
    1546         520 :     lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE     ] );
    1547         520 :     lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH       ] );
    1548             : 
    1549         520 :     return lResult;
    1550             : }
    1551             : 
    1552             : //*****************************************************************************************************************
    1553             : //  private method
    1554             : //*****************************************************************************************************************
    1555         470 : Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const
    1556             : {
    1557         470 :     Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_IMAGES );
    1558             : 
    1559             :     // Create property names dependent from the root node name
    1560         470 :     lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL       ] );
    1561         470 :     lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG     ] );
    1562         470 :     lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] );
    1563         470 :     lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC       ] );
    1564         470 :     lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL  ] );
    1565         470 :     lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] );
    1566         470 :     lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL] );
    1567         470 :     lResult[7] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL   ] );
    1568             : 
    1569         470 :     return lResult;
    1570             : }
    1571             : 
    1572             : //*****************************************************************************************************************
    1573             : //  initialize static member
    1574             : //  DON'T DO IT IN YOUR HEADER!
    1575             : //  see definition for further informations
    1576             : //*****************************************************************************************************************
    1577             : AddonsOptions_Impl*     AddonsOptions::m_pDataContainer = NULL  ;
    1578             : sal_Int32               AddonsOptions::m_nRefCount      = 0     ;
    1579             : 
    1580             : //*****************************************************************************************************************
    1581             : //  constructor
    1582             : //*****************************************************************************************************************
    1583        5312 : AddonsOptions::AddonsOptions()
    1584             : {
    1585             :     // Global access, must be guarded (multithreading!).
    1586        5312 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1587             :     // Increase ouer refcount ...
    1588        5312 :     ++m_nRefCount;
    1589             :     // ... and initialize ouer data container only if it not already exist!
    1590        5312 :     if( m_pDataContainer == NULL )
    1591             :     {
    1592          54 :         m_pDataContainer = new AddonsOptions_Impl;
    1593        5312 :     }
    1594        5312 : }
    1595             : 
    1596             : //*****************************************************************************************************************
    1597             : //  destructor
    1598             : //*****************************************************************************************************************
    1599        4894 : AddonsOptions::~AddonsOptions()
    1600             : {
    1601             :     // Global access, must be guarded (multithreading!)
    1602        4894 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1603             :     // Decrease ouer refcount.
    1604        4894 :     --m_nRefCount;
    1605             :     // If last instance was deleted ...
    1606             :     // we must destroy ouer static data container!
    1607        4894 :     if( m_nRefCount <= 0 )
    1608             :     {
    1609          32 :         delete m_pDataContainer;
    1610          32 :         m_pDataContainer = NULL;
    1611        4894 :     }
    1612        4894 : }
    1613             : 
    1614             : //*****************************************************************************************************************
    1615             : //  public method
    1616             : //*****************************************************************************************************************
    1617           2 : sal_Bool AddonsOptions::HasAddonsMenu() const
    1618             : {
    1619           2 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1620           2 :     return m_pDataContainer->HasAddonsMenu();
    1621             : }
    1622             : 
    1623             : //*****************************************************************************************************************
    1624             : //  public method
    1625             : //*****************************************************************************************************************
    1626             : 
    1627        1032 : sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
    1628             : {
    1629        1032 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1630        1032 :     return m_pDataContainer->GetAddonsToolBarCount();
    1631             : }
    1632             : 
    1633             : //*****************************************************************************************************************
    1634             : //  public method
    1635             : //*****************************************************************************************************************
    1636           0 : const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
    1637             : {
    1638           0 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1639           0 :     return m_pDataContainer->GetAddonsMenu();
    1640             : }
    1641             : 
    1642             : //*****************************************************************************************************************
    1643             : //  public method
    1644             : //*****************************************************************************************************************
    1645           2 : const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
    1646             : {
    1647           2 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1648           2 :     return m_pDataContainer->GetAddonsMenuBarPart();
    1649             : }
    1650             : 
    1651             : //*****************************************************************************************************************
    1652             : //  public method
    1653             : //*****************************************************************************************************************
    1654        1016 : const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
    1655             : {
    1656        1016 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1657        1016 :     return m_pDataContainer->GetAddonsToolBarPart( nIndex );
    1658             : }
    1659             : 
    1660             : //*****************************************************************************************************************
    1661             : //  public method
    1662             : //*****************************************************************************************************************
    1663        1016 : const ::rtl::OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
    1664             : {
    1665        1016 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1666        1016 :     return m_pDataContainer->GetAddonsToolbarResourceName( nIndex );
    1667             : }
    1668             : 
    1669             : //*****************************************************************************************************************
    1670             : //  public method
    1671             : //*****************************************************************************************************************
    1672           2 : const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
    1673             : {
    1674           2 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1675           2 :     return m_pDataContainer->GetAddonsHelpMenu();
    1676             : }
    1677             : 
    1678             : //*****************************************************************************************************************
    1679             : //  public method
    1680             : //*****************************************************************************************************************
    1681           2 : const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
    1682             : {
    1683           2 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1684           2 :     return m_pDataContainer->GetMergeMenuInstructions();
    1685             : }
    1686             : 
    1687             : //*****************************************************************************************************************
    1688             : //  public method
    1689             : //*****************************************************************************************************************
    1690           4 : bool AddonsOptions::GetMergeToolbarInstructions(
    1691             :     const ::rtl::OUString& rToolbarName,
    1692             :     MergeToolbarInstructionContainer& rToolbarInstructions ) const
    1693             : {
    1694           4 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1695             :     return m_pDataContainer->GetMergeToolbarInstructions(
    1696           4 :         rToolbarName, rToolbarInstructions );
    1697             : }
    1698             : 
    1699             : //*****************************************************************************************************************
    1700             : //  public method
    1701             : //*****************************************************************************************************************
    1702        4782 : Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const
    1703             : {
    1704        4782 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1705        4782 :     return m_pDataContainer->GetImageFromURL( aURL, bBig, bNoScale );
    1706             : }
    1707             : 
    1708             : //*****************************************************************************************************************
    1709             : //  public method
    1710             : //*****************************************************************************************************************
    1711        4782 : Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig ) const
    1712             : {
    1713        4782 :     return GetImageFromURL( aURL, bBig, sal_False );
    1714             : }
    1715             : 
    1716             : //*****************************************************************************************************************
    1717             : //  private method
    1718             : //*****************************************************************************************************************
    1719       18064 : Mutex& AddonsOptions::GetOwnStaticMutex()
    1720             : {
    1721             :     // Initialize static mutex only for one time!
    1722             :     static Mutex* pMutex = NULL;
    1723             :     // If these method first called (Mutex not already exist!) ...
    1724       18064 :     if( pMutex == NULL )
    1725             :     {
    1726             :         // ... we must create a new one. Protect follow code with the global mutex -
    1727             :         // It must be - we create a static variable!
    1728          46 :         MutexGuard aGuard( Mutex::getGlobalMutex() );
    1729             :         // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
    1730          46 :         if( pMutex == NULL )
    1731             :         {
    1732             :             // Create the new mutex and set it for return on static variable.
    1733          46 :             static Mutex aMutex;
    1734          46 :             pMutex = &aMutex;
    1735          46 :         }
    1736             :     }
    1737             :     // Return new created or already existing mutex object.
    1738       18064 :     return *pMutex;
    1739             : }
    1740             : 
    1741             : //*****************************************************************************************************************
    1742             : //  private method
    1743             : //*****************************************************************************************************************
    1744           0 : IMPL_STATIC_LINK_NOINSTANCE( AddonsOptions, Notify, void*, EMPTYARG )
    1745             : {
    1746           0 :     MutexGuard aGuard( GetOwnStaticMutex() );
    1747           0 :     m_pDataContainer->ReadConfigurationData();
    1748           0 :     return 0;
    1749             : }
    1750             : 
    1751         234 : }
    1752             : 
    1753             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10