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

Generated by: LCOV version 1.10