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

Generated by: LCOV version 1.11