LCOV - code coverage report
Current view: top level - framework/source/fwe/classes - addonsoptions.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 367 774 47.4 %
Date: 2014-04-11 Functions: 49 69 71.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10