1956 lines
88 KiB
C++
1956 lines
88 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <com/sun/star/beans/PropertyValue.hpp>
|
|
#include <framework/addonsoptions.hxx>
|
|
#include <o3tl/safeint.hxx>
|
|
#include <unotools/configmgr.hxx>
|
|
#include <unotools/configitem.hxx>
|
|
#include <unotools/ucbstreamhelper.hxx>
|
|
#include <tools/stream.hxx>
|
|
#include <com/sun/star/uno/Any.hxx>
|
|
#include <com/sun/star/uno/Sequence.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <comphelper/getexpandeduri.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <vcl/dibtools.hxx>
|
|
#include <vcl/graph.hxx>
|
|
#include <vcl/graphicfilter.hxx>
|
|
#include <vcl/toolbox.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#include <algorithm>
|
|
#include <string_view>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
// namespaces
|
|
|
|
using namespace ::utl;
|
|
using namespace ::osl;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::beans;
|
|
using namespace ::com::sun::star::lang;
|
|
using namespace ::com::sun::star;
|
|
|
|
constexpr OUStringLiteral ROOTNODE_ADDONMENU = u"Office.Addons";
|
|
constexpr OUStringLiteral PATHDELIMITER = u"/";
|
|
constexpr OUString SEPARATOR_URL = u"private:separator"_ustr;
|
|
|
|
#define PROPERTYNAME_URL ADDONSMENUITEM_STRING_URL
|
|
#define PROPERTYNAME_TITLE ADDONSMENUITEM_STRING_TITLE
|
|
#define PROPERTYNAME_TARGET ADDONSMENUITEM_STRING_TARGET
|
|
#define PROPERTYNAME_IMAGEIDENTIFIER ADDONSMENUITEM_STRING_IMAGEIDENTIFIER
|
|
#define PROPERTYNAME_CONTEXT ADDONSMENUITEM_STRING_CONTEXT
|
|
#define PROPERTYNAME_SUBMENU ADDONSMENUITEM_STRING_SUBMENU
|
|
|
|
constexpr OUStringLiteral IMAGES_NODENAME = u"UserDefinedImages";
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define INDEX_URL 0
|
|
#define INDEX_TITLE 1
|
|
#define INDEX_IMAGEIDENTIFIER 2
|
|
#define INDEX_TARGET 3
|
|
#define INDEX_CONTEXT 4
|
|
#define INDEX_SUBMENU 5
|
|
#define INDEX_CONTROLTYPE 6
|
|
#define INDEX_WIDTH 7
|
|
#define INDEX_ALIGN 8
|
|
#define INDEX_AUTOSIZE 9
|
|
#define INDEX_OWNERDRAW 10
|
|
#define INDEX_MANDATORY 11
|
|
#define INDEX_STYLE 12
|
|
#define PROPERTYCOUNT_INDEX 13
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define PROPERTYCOUNT_MENUITEM 6
|
|
#define OFFSET_MENUITEM_URL 0
|
|
#define OFFSET_MENUITEM_TITLE 1
|
|
#define OFFSET_MENUITEM_IMAGEIDENTIFIER 2
|
|
#define OFFSET_MENUITEM_TARGET 3
|
|
#define OFFSET_MENUITEM_CONTEXT 4
|
|
#define OFFSET_MENUITEM_SUBMENU 5
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define PROPERTYCOUNT_POPUPMENU 4
|
|
#define OFFSET_POPUPMENU_TITLE 0
|
|
#define OFFSET_POPUPMENU_CONTEXT 1
|
|
#define OFFSET_POPUPMENU_SUBMENU 2
|
|
#define OFFSET_POPUPMENU_URL 3 // Used for property set
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define PROPERTYCOUNT_TOOLBARITEM 7
|
|
#define OFFSET_TOOLBARITEM_URL 0
|
|
#define OFFSET_TOOLBARITEM_TITLE 1
|
|
#define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER 2
|
|
#define OFFSET_TOOLBARITEM_TARGET 3
|
|
#define OFFSET_TOOLBARITEM_CONTEXT 4
|
|
#define OFFSET_TOOLBARITEM_CONTROLTYPE 5
|
|
#define OFFSET_TOOLBARITEM_WIDTH 6
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define PROPERTYCOUNT_NOTEBOOKBARITEM 8
|
|
#define OFFSET_NOTEBOOKBARITEM_URL 0
|
|
#define OFFSET_NOTEBOOKBARITEM_TITLE 1
|
|
#define OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER 2
|
|
#define OFFSET_NOTEBOOKBARITEM_TARGET 3
|
|
#define OFFSET_NOTEBOOKBARITEM_CONTEXT 4
|
|
#define OFFSET_NOTEBOOKBARITEM_CONTROLTYPE 5
|
|
#define OFFSET_NOTEBOOKBARITEM_WIDTH 6
|
|
#define OFFSET_NOTEBOOKBARITEM_STYLE 7
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define PROPERTYCOUNT_STATUSBARITEM 8
|
|
#define OFFSET_STATUSBARITEM_URL 0
|
|
#define OFFSET_STATUSBARITEM_TITLE 1
|
|
#define OFFSET_STATUSBARITEM_CONTEXT 2
|
|
#define OFFSET_STATUSBARITEM_ALIGN 3
|
|
#define OFFSET_STATUSBARITEM_AUTOSIZE 4
|
|
#define OFFSET_STATUSBARITEM_OWNERDRAW 5
|
|
#define OFFSET_STATUSBARITEM_MANDATORY 6
|
|
#define OFFSET_STATUSBARITEM_WIDTH 7
|
|
|
|
// The following order is mandatory. Please add properties at the end!
|
|
#define PROPERTYCOUNT_IMAGES 8
|
|
#define PROPERTYCOUNT_EMBEDDED_IMAGES 2
|
|
#define OFFSET_IMAGES_SMALL 0
|
|
#define OFFSET_IMAGES_BIG 1
|
|
#define OFFSET_IMAGES_SMALLHC 2
|
|
#define OFFSET_IMAGES_BIGHC 3
|
|
#define OFFSET_IMAGES_SMALL_URL 4
|
|
#define OFFSET_IMAGES_BIG_URL 5
|
|
#define OFFSET_IMAGES_SMALLHC_URL 6
|
|
#define OFFSET_IMAGES_BIGHC_URL 7
|
|
|
|
#define PROPERTYCOUNT_MERGE_MENUBAR 6
|
|
#define OFFSET_MERGEMENU_MERGEPOINT 0
|
|
#define OFFSET_MERGEMENU_MERGECOMMAND 1
|
|
#define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER 2
|
|
#define OFFSET_MERGEMENU_MERGEFALLBACK 3
|
|
#define OFFSET_MERGEMENU_MERGECONTEXT 4
|
|
#define OFFSET_MERGEMENU_MENUITEMS 5
|
|
|
|
#define PROPERTYCOUNT_MERGE_TOOLBAR 7
|
|
#define OFFSET_MERGETOOLBAR_TOOLBAR 0
|
|
#define OFFSET_MERGETOOLBAR_MERGEPOINT 1
|
|
#define OFFSET_MERGETOOLBAR_MERGECOMMAND 2
|
|
#define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER 3
|
|
#define OFFSET_MERGETOOLBAR_MERGEFALLBACK 4
|
|
#define OFFSET_MERGETOOLBAR_MERGECONTEXT 5
|
|
#define OFFSET_MERGETOOLBAR_TOOLBARITEMS 6
|
|
|
|
#define PROPERTYCOUNT_MERGE_NOTEBOOKBAR 7
|
|
#define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR 0
|
|
#define OFFSET_MERGENOTEBOOKBAR_MERGEPOINT 1
|
|
#define OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND 2
|
|
#define OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER 3
|
|
#define OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK 4
|
|
#define OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT 5
|
|
#define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS 6
|
|
|
|
#define PROPERTYCOUNT_MERGE_STATUSBAR 6
|
|
#define OFFSET_MERGESTATUSBAR_MERGEPOINT 0
|
|
#define OFFSET_MERGESTATUSBAR_MERGECOMMAND 1
|
|
#define OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER 2
|
|
#define OFFSET_MERGESTATUSBAR_MERGEFALLBACK 3
|
|
#define OFFSET_MERGESTATUSBAR_MERGECONTEXT 4
|
|
#define OFFSET_MERGESTATUSBAR_STATUSBARITEMS 5
|
|
|
|
// private declarations!
|
|
|
|
/*-****************************************************************************************************************
|
|
@descr struct to hold information about one menu entry.
|
|
****************************************************************************************************************-*/
|
|
|
|
namespace framework
|
|
{
|
|
|
|
class AddonsOptions_Impl : public ConfigItem
|
|
{
|
|
|
|
// public methods
|
|
|
|
public:
|
|
|
|
// constructor / destructor
|
|
|
|
AddonsOptions_Impl();
|
|
virtual ~AddonsOptions_Impl() override;
|
|
|
|
// overridden methods of baseclass
|
|
|
|
/*-****************************************************************************************************
|
|
@short called for notify of configmanager
|
|
@descr This method is called from the ConfigManager before application ends or from the
|
|
PropertyChangeListener if the sub tree broadcasts changes. You must update your
|
|
internal values.
|
|
|
|
@seealso baseclass ConfigItem
|
|
|
|
@param "lPropertyNames" is the list of properties which should be updated.
|
|
*//*-*****************************************************************************************************/
|
|
|
|
virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
|
|
|
|
// public interface
|
|
|
|
/*-****************************************************************************************************
|
|
@short base implementation of public interface for "SvtDynamicMenuOptions"!
|
|
@descr These class is used as static member of "SvtDynamicMenuOptions" ...
|
|
=> The code exist only for one time and isn't duplicated for every instance!
|
|
*//*-*****************************************************************************************************/
|
|
|
|
bool HasAddonsMenu () const;
|
|
sal_Int32 GetAddonsToolBarCount() const;
|
|
sal_Int32 GetAddonsNotebookBarCount() const;
|
|
const Sequence< Sequence< PropertyValue > >& GetAddonsMenu () const { return m_aCachedMenuProperties;}
|
|
const Sequence< Sequence< PropertyValue > >& GetAddonsMenuBarPart () const { return m_aCachedMenuBarPartProperties;}
|
|
const Sequence< Sequence< PropertyValue > >& GetAddonsToolBarPart ( sal_uInt32 nIndex ) const;
|
|
const Sequence< Sequence< PropertyValue > >& GetAddonsNotebookBarPart ( sal_uInt32 nIndex ) const;
|
|
const OUString & GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
|
|
const OUString & GetAddonsNotebookBarResourceName( sal_uInt32 nIndex ) const;
|
|
const Sequence< Sequence< PropertyValue > >& GetAddonsHelpMenu () const { return m_aCachedHelpMenuProperties;}
|
|
BitmapEx GetImageFromURL( const OUString& aURL, bool bBig, bool bNoScale );
|
|
const MergeMenuInstructionContainer& GetMergeMenuInstructions() const { return m_aCachedMergeMenuInsContainer;}
|
|
bool GetMergeToolbarInstructions( const OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
|
|
bool GetMergeNotebookBarInstructions( const OUString& rNotebookBarName, MergeNotebookBarInstructionContainer& rNotebookBarInstructions ) const;
|
|
const MergeStatusbarInstructionContainer& GetMergeStatusbarInstructions() const { return m_aCachedStatusbarMergingInstructions;}
|
|
void ReadConfigurationData();
|
|
|
|
private:
|
|
enum ImageSize
|
|
{
|
|
IMGSIZE_SMALL = 0,
|
|
IMGSIZE_BIG
|
|
};
|
|
|
|
struct OneImageEntry
|
|
{
|
|
BitmapEx aScaled; ///< cached scaled image
|
|
BitmapEx aImage; ///< original un-scaled image
|
|
OUString aURL; ///< URL in case it is not loaded yet
|
|
};
|
|
|
|
struct ImageEntry
|
|
{
|
|
// if the image is set, it was embedded in some way,
|
|
// otherwise we use the associated URL to load on demand
|
|
|
|
// accessed in this order
|
|
OneImageEntry aSizeEntry[2];
|
|
ImageEntry() {}
|
|
void addImage(ImageSize eSize, const BitmapEx &rImage);
|
|
void addImage(ImageSize eSize, const OUString &rURL);
|
|
};
|
|
|
|
typedef std::unordered_map< OUString, ImageEntry > ImageManager;
|
|
typedef std::unordered_map< OUString, sal_uInt32 > StringToIndexMap;
|
|
typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
|
|
typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonNotebookBars;
|
|
typedef std::unordered_map< OUString, MergeToolbarInstructionContainer > ToolbarMergingInstructions;
|
|
typedef std::unordered_map< OUString, MergeNotebookBarInstructionContainer > NotebookBarMergingInstructions;
|
|
|
|
/*-****************************************************************************************************
|
|
@short return list of key names of our configuration management which represent our module tree
|
|
@descr These methods return the current list of key names! We need it to get needed values from our
|
|
configuration management!
|
|
@param "nCount" , returns count of menu entries for "new"
|
|
@return A list of configuration key names is returned.
|
|
*//*-*****************************************************************************************************/
|
|
|
|
void ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
|
|
void ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
|
|
void ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< OUString >& rAddonOfficeToolBarResNames );
|
|
bool ReadToolBarItemSet( const OUString& rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
|
|
void ReadOfficeNotebookBarSet( AddonNotebookBars& rAddonOfficeNotebookBars, std::vector< OUString >& rAddonOfficeNotebookBarResNames );
|
|
bool ReadNotebookBarItemSet( const OUString& rNotebookBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeNotebookBarSeq );
|
|
|
|
void ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
|
|
void ReadImages( ImageManager& aImageManager );
|
|
void ReadMenuMergeInstructions( MergeMenuInstructionContainer& rContainer );
|
|
void ReadToolbarMergeInstructions( ToolbarMergingInstructions& rToolbarMergeMap );
|
|
void ReadNotebookBarMergeInstructions( NotebookBarMergingInstructions& rNotebookBarMergeMap );
|
|
void ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer& rContainer );
|
|
|
|
void ReadMergeMenuData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
|
|
void ReadMergeToolbarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
|
|
void ReadMergeNotebookBarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeNotebookBarItems );
|
|
void ReadMergeStatusbarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeStatusbar );
|
|
bool ReadMenuItem( std::u16string_view aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, bool bIgnoreSubMenu = false );
|
|
bool ReadPopupMenu( std::u16string_view aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
|
|
static void AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
|
|
bool ReadToolBarItem( std::u16string_view aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
|
|
bool ReadNotebookBarItem( std::u16string_view aNotebookBarItemNodeName, Sequence< PropertyValue >& aNotebookBarItem );
|
|
|
|
bool ReadStatusBarItem( std::u16string_view aStatusbarItemNodeName, Sequence< PropertyValue >& aStatusbarItem );
|
|
std::unique_ptr<ImageEntry> ReadImageData( std::u16string_view aImagesNodeName );
|
|
void ReadAndAssociateImages( const OUString& aURL, const OUString& aImageId );
|
|
static BitmapEx ReadImageFromURL( const OUString& aURL );
|
|
bool HasAssociatedImages( const OUString& aURL );
|
|
static void SubstituteVariables( OUString& aURL );
|
|
|
|
void ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
|
|
OUString GeneratePrefixURL();
|
|
|
|
Sequence< OUString > GetPropertyNamesMenuItem( std::u16string_view aPropertyRootNode )
|
|
const;
|
|
Sequence< OUString > GetPropertyNamesPopupMenu( std::u16string_view aPropertyRootNode )
|
|
const;
|
|
Sequence< OUString > GetPropertyNamesToolBarItem( std::u16string_view aPropertyRootNode )
|
|
const;
|
|
Sequence< OUString > GetPropertyNamesNotebookBarItem( std::u16string_view aPropertyRootNode ) const;
|
|
|
|
Sequence< OUString > GetPropertyNamesStatusbarItem( std::u16string_view aPropertyRootNode ) const;
|
|
Sequence< OUString > GetPropertyNamesImages( std::u16string_view aPropertyRootNode ) const;
|
|
static bool CreateImageFromSequence( BitmapEx& rImage, Sequence< sal_Int8 >& rBitmapDataSeq );
|
|
|
|
DECL_LINK(NotifyEvent, void*, void);
|
|
|
|
virtual void ImplCommit() override;
|
|
|
|
// private member
|
|
|
|
private:
|
|
sal_Int32 m_nRootAddonPopupMenuId;
|
|
OUString m_aPropNames[PROPERTYCOUNT_INDEX];
|
|
OUString m_aPropImagesNames[PROPERTYCOUNT_IMAGES];
|
|
OUString m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR];
|
|
OUString m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR];
|
|
OUString m_aPropMergeNotebookBarNames[PROPERTYCOUNT_MERGE_NOTEBOOKBAR];
|
|
OUString m_aPropMergeStatusbarNames[PROPERTYCOUNT_MERGE_STATUSBAR];
|
|
OUString m_aPathDelimiter;
|
|
OUString m_aRootAddonPopupMenuURLPrexfix;
|
|
Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties;
|
|
Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties;
|
|
AddonToolBars m_aCachedToolBarPartProperties;
|
|
AddonNotebookBars m_aCachedNotebookBarPartProperties;
|
|
std::vector< OUString > m_aCachedToolBarPartResourceNames;
|
|
std::vector< OUString > m_aCachedNotebookBarPartResourceNames;
|
|
Sequence< Sequence< PropertyValue > > m_aCachedHelpMenuProperties;
|
|
ImageManager m_aImageManager;
|
|
Sequence< Sequence< PropertyValue > > m_aEmptyAddonToolBar;
|
|
Sequence< Sequence< PropertyValue > > m_aEmptyAddonNotebookBar;
|
|
MergeMenuInstructionContainer m_aCachedMergeMenuInsContainer;
|
|
ToolbarMergingInstructions m_aCachedToolbarMergingInstructions;
|
|
NotebookBarMergingInstructions m_aCachedNotebookBarMergingInstructions;
|
|
MergeStatusbarInstructionContainer m_aCachedStatusbarMergingInstructions;
|
|
};
|
|
|
|
void AddonsOptions_Impl::ImageEntry::addImage(ImageSize eSize, const BitmapEx& rImage)
|
|
{
|
|
aSizeEntry[static_cast<int>(eSize)].aImage = rImage;
|
|
}
|
|
|
|
void AddonsOptions_Impl::ImageEntry::addImage(ImageSize eSize, const OUString &rURL)
|
|
{
|
|
aSizeEntry[static_cast<int>(eSize)].aURL = rURL;
|
|
}
|
|
|
|
// constructor
|
|
|
|
AddonsOptions_Impl::AddonsOptions_Impl()
|
|
// Init baseclasses first
|
|
: ConfigItem( ROOTNODE_ADDONMENU ),
|
|
m_nRootAddonPopupMenuId( 0 ),
|
|
m_aPathDelimiter( PATHDELIMITER ),
|
|
m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX_STR )
|
|
{
|
|
// initialize array with fixed property names
|
|
m_aPropNames[ INDEX_URL ] = PROPERTYNAME_URL;
|
|
m_aPropNames[ INDEX_TITLE ] = PROPERTYNAME_TITLE;
|
|
m_aPropNames[ INDEX_TARGET ] = PROPERTYNAME_TARGET;
|
|
m_aPropNames[ INDEX_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
|
|
m_aPropNames[ INDEX_CONTEXT ] = PROPERTYNAME_CONTEXT;
|
|
m_aPropNames[ INDEX_SUBMENU ] = PROPERTYNAME_SUBMENU; // Submenu set!
|
|
m_aPropNames[ INDEX_CONTROLTYPE ] = "ControlType";
|
|
m_aPropNames[ INDEX_WIDTH ] = "Width";
|
|
m_aPropNames[ INDEX_ALIGN ] = "Alignment";
|
|
m_aPropNames[ INDEX_AUTOSIZE ] = "AutoSize";
|
|
m_aPropNames[ INDEX_OWNERDRAW ] = "OwnerDraw";
|
|
m_aPropNames[ INDEX_MANDATORY ] = "Mandatory";
|
|
m_aPropNames[ INDEX_STYLE ] = "Style";
|
|
|
|
// initialize array with fixed images property names
|
|
m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] = "ImageSmall";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_BIG ] = "ImageBig";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] = "ImageSmallHC";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] = "ImageBigHC";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] = "ImageSmallURL";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] = "ImageBigURL";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL ] = "ImageSmallHCURL";
|
|
m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] = "ImageBigHCURL";
|
|
|
|
// initialize array with fixed merge menu property names
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] = "MergePoint";
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] = "MergeCommand";
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = "MergeCommandParameter";
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] = "MergeFallback";
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] = "MergeContext";
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] = "MenuItems";
|
|
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] = "MergeToolBar";
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] = "MergePoint";
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] = "MergeCommand";
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] = "MergeCommandParameter";
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] = "MergeFallback";
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] = "MergeContext";
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] = "ToolBarItems";
|
|
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR ] = "MergeNotebookBar";
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_MERGEPOINT ] = "MergePoint";
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND ] = "MergeCommand";
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER ] = "MergeCommandParameter";
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK ] = "MergeFallback";
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT ] = "MergeContext";
|
|
m_aPropMergeNotebookBarNames[ OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS ] = "NotebookBarItems";
|
|
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGEPOINT ] = "MergePoint";
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECOMMAND ] = "MergeCommand";
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER ] = "MergeCommandParameter";
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK ] = "MergeFallback";
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECONTEXT ] = "MergeContext";
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS ] = "StatusBarItems";
|
|
|
|
ReadConfigurationData();
|
|
|
|
// Enable notification mechanism of our baseclass.
|
|
// We need it to get information about changes outside these class on our used configuration keys!
|
|
Sequence<OUString> aNotifySeq { u"AddonUI"_ustr };
|
|
EnableNotification( aNotifySeq );
|
|
}
|
|
|
|
// destructor
|
|
|
|
AddonsOptions_Impl::~AddonsOptions_Impl()
|
|
{
|
|
assert(!IsModified()); // should have been committed
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadConfigurationData()
|
|
{
|
|
// reset members to be read again from configuration
|
|
m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
|
|
m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
|
|
m_aCachedToolBarPartProperties = AddonToolBars();
|
|
m_aCachedNotebookBarPartProperties = AddonNotebookBars();
|
|
m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
|
|
m_aCachedToolBarPartResourceNames.clear();
|
|
m_aCachedNotebookBarPartResourceNames.clear();
|
|
m_aImageManager = ImageManager();
|
|
|
|
ReadAddonMenuSet( m_aCachedMenuProperties );
|
|
ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties );
|
|
ReadOfficeToolBarSet( m_aCachedToolBarPartProperties, m_aCachedToolBarPartResourceNames );
|
|
ReadOfficeNotebookBarSet( m_aCachedNotebookBarPartProperties, m_aCachedNotebookBarPartResourceNames );
|
|
|
|
ReadOfficeHelpSet( m_aCachedHelpMenuProperties );
|
|
ReadImages( m_aImageManager );
|
|
|
|
m_aCachedMergeMenuInsContainer.clear();
|
|
m_aCachedToolbarMergingInstructions.clear();
|
|
m_aCachedNotebookBarMergingInstructions.clear();
|
|
m_aCachedStatusbarMergingInstructions.clear();
|
|
|
|
ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer );
|
|
ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions );
|
|
ReadNotebookBarMergeInstructions( m_aCachedNotebookBarMergingInstructions );
|
|
ReadStatusbarMergeInstructions( m_aCachedStatusbarMergingInstructions );
|
|
}
|
|
|
|
// public method
|
|
|
|
void AddonsOptions_Impl::Notify( const Sequence< OUString >& /*lPropertyNames*/ )
|
|
{
|
|
Application::PostUserEvent(LINK(this, AddonsOptions_Impl, NotifyEvent));
|
|
}
|
|
|
|
// public method
|
|
|
|
void AddonsOptions_Impl::ImplCommit()
|
|
{
|
|
SAL_WARN("fwk", "AddonsOptions_Impl::ImplCommit(): Not implemented yet!");
|
|
}
|
|
|
|
// public method
|
|
|
|
bool AddonsOptions_Impl::HasAddonsMenu() const
|
|
{
|
|
return m_aCachedMenuProperties.hasElements();
|
|
}
|
|
|
|
// public method
|
|
|
|
sal_Int32 AddonsOptions_Impl::GetAddonsToolBarCount() const
|
|
{
|
|
return m_aCachedToolBarPartProperties.size();
|
|
}
|
|
|
|
// public method
|
|
|
|
sal_Int32 AddonsOptions_Impl::GetAddonsNotebookBarCount() const
|
|
{
|
|
return m_aCachedNotebookBarPartProperties.size();
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
|
|
{
|
|
if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
|
|
return m_aCachedToolBarPartProperties[nIndex];
|
|
else
|
|
return m_aEmptyAddonToolBar;
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsNotebookBarPart( sal_uInt32 nIndex ) const
|
|
{
|
|
if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedNotebookBarPartProperties.size() )
|
|
return m_aCachedNotebookBarPartProperties[nIndex];
|
|
else
|
|
return m_aEmptyAddonNotebookBar;
|
|
}
|
|
|
|
// public method
|
|
|
|
const OUString & AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
|
|
{
|
|
if ( nIndex < m_aCachedToolBarPartResourceNames.size() )
|
|
return m_aCachedToolBarPartResourceNames[nIndex];
|
|
else
|
|
return EMPTY_OUSTRING;
|
|
}
|
|
|
|
// public method
|
|
|
|
const OUString & AddonsOptions_Impl::GetAddonsNotebookBarResourceName( sal_uInt32 nIndex ) const
|
|
{
|
|
if ( nIndex < m_aCachedNotebookBarPartResourceNames.size() )
|
|
return m_aCachedNotebookBarPartResourceNames[nIndex];
|
|
else
|
|
return EMPTY_OUSTRING;
|
|
}
|
|
|
|
// public method
|
|
|
|
bool AddonsOptions_Impl::GetMergeToolbarInstructions(
|
|
const OUString& rToolbarName,
|
|
MergeToolbarInstructionContainer& rToolbarInstructions ) const
|
|
{
|
|
ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
|
|
if ( pIter != m_aCachedToolbarMergingInstructions.end() )
|
|
{
|
|
rToolbarInstructions = pIter->second;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// public method
|
|
|
|
bool AddonsOptions_Impl::GetMergeNotebookBarInstructions(
|
|
const OUString& rNotebookBarName,
|
|
MergeNotebookBarInstructionContainer& rNotebookBarInstructions ) const
|
|
{
|
|
NotebookBarMergingInstructions::const_iterator pIter = m_aCachedNotebookBarMergingInstructions.find( rNotebookBarName );
|
|
if ( pIter != m_aCachedNotebookBarMergingInstructions.end() )
|
|
{
|
|
rNotebookBarInstructions = pIter->second;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// public method
|
|
|
|
static BitmapEx ScaleImage( const BitmapEx &rImage, bool bBig )
|
|
{
|
|
Size aSize = ToolBox::GetDefaultImageSize(bBig ? ToolBoxButtonSize::Large : ToolBoxButtonSize::Small);
|
|
BitmapEx aScaleBmp(rImage);
|
|
SAL_INFO("fwk", "Addons: expensive scale image from "
|
|
<< aScaleBmp.GetSizePixel() << " to " << aSize);
|
|
aScaleBmp.Scale(aSize, BmpScaleFlag::BestQuality);
|
|
return aScaleBmp;
|
|
}
|
|
|
|
BitmapEx AddonsOptions_Impl::GetImageFromURL( const OUString& aURL, bool bBig, bool bNoScale )
|
|
{
|
|
BitmapEx aImage;
|
|
|
|
SAL_INFO("fwk", "Expensive: Addons GetImageFromURL " << aURL <<
|
|
" big " << (bBig?"big":"little") <<
|
|
" scale " << (bNoScale ? "noscale" : "scale"));
|
|
|
|
ImageManager::iterator pIter = m_aImageManager.find(aURL);
|
|
if ( pIter != m_aImageManager.end() )
|
|
{
|
|
ImageSize eSize = bBig ? IMGSIZE_BIG : IMGSIZE_SMALL;
|
|
int nIdx = static_cast<int>(eSize);
|
|
int nOtherIdx = nIdx ? 0 : 1;
|
|
|
|
OneImageEntry& rSizeEntry = pIter->second.aSizeEntry[nIdx];
|
|
OneImageEntry& rOtherEntry = pIter->second.aSizeEntry[nOtherIdx];
|
|
// actually read the image ...
|
|
if (rSizeEntry.aImage.IsEmpty())
|
|
rSizeEntry.aImage = ReadImageFromURL(rSizeEntry.aURL);
|
|
|
|
if (rSizeEntry.aImage.IsEmpty())
|
|
{ // try the other size and scale it
|
|
aImage = ScaleImage(ReadImageFromURL(rOtherEntry.aURL), bBig);
|
|
rSizeEntry.aImage = aImage;
|
|
if (rSizeEntry.aImage.IsEmpty())
|
|
SAL_WARN("fwk", "failed to load addons image " << aURL);
|
|
}
|
|
|
|
// FIXME: bNoScale is not terribly meaningful or useful
|
|
|
|
if (aImage.IsEmpty() && bNoScale)
|
|
aImage = rSizeEntry.aImage;
|
|
|
|
if (aImage.IsEmpty() && !rSizeEntry.aScaled.IsEmpty())
|
|
aImage = rSizeEntry.aScaled;
|
|
|
|
else // scale to the correct size for the theme / toolbox
|
|
{
|
|
aImage = rSizeEntry.aImage;
|
|
if (aImage.IsEmpty()) // use and scale the other if one size is missing
|
|
aImage = rOtherEntry.aImage;
|
|
|
|
aImage = ScaleImage(aImage, bBig);
|
|
rSizeEntry.aScaled = aImage; // cache for next time
|
|
}
|
|
}
|
|
|
|
return aImage;
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
|
|
{
|
|
// Read the AddonMenu set and fill property sequences
|
|
OUString aAddonMenuNodeName( u"AddonUI/AddonMenu"_ustr );
|
|
Sequence< OUString > aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
|
|
OUString aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
|
|
|
|
sal_uInt32 nCount = aAddonMenuNodeSeq.getLength();
|
|
sal_uInt32 nIndex = 0;
|
|
Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
|
|
auto pMenuItem = aMenuItem.getArray();
|
|
// Init the property value sequence
|
|
pMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
|
|
pMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
|
|
pMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
|
|
pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
|
|
pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
|
|
pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
|
|
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
|
|
|
|
// Read the MenuItem
|
|
if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
|
|
{
|
|
// Successfully read a menu item, append to our list
|
|
sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
|
|
rAddonMenuSeq.realloc( nMenuItemCount );
|
|
rAddonMenuSeq.getArray()[nIndex++] = aMenuItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
|
|
{
|
|
// Read the AddonMenu set and fill property sequences
|
|
OUString aAddonHelpMenuNodeName( u"AddonUI/OfficeHelp"_ustr );
|
|
Sequence< OUString > aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
|
|
OUString aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
|
|
|
|
sal_uInt32 nCount = aAddonHelpMenuNodeSeq.getLength();
|
|
sal_uInt32 nIndex = 0;
|
|
Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
|
|
auto pMenuItem = aMenuItem.getArray();
|
|
// Init the property value sequence
|
|
pMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
|
|
pMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
|
|
pMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
|
|
pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
|
|
pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
|
|
pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
|
|
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
|
|
|
|
// Read the MenuItem
|
|
if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, true ) )
|
|
{
|
|
// Successfully read a menu item, append to our list
|
|
sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
|
|
rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
|
|
rAddonOfficeHelpMenuSeq.getArray()[nIndex++] = aMenuItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
|
|
{
|
|
// Read the OfficeMenuBar set and fill property sequences
|
|
OUString aAddonMenuBarNodeName( u"AddonUI/OfficeMenuBar"_ustr );
|
|
Sequence< OUString > aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
|
|
OUString aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
|
|
|
|
sal_uInt32 nCount = aAddonMenuBarNodeSeq.getLength();
|
|
sal_uInt32 nIndex = 0;
|
|
Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
|
|
auto pPopupMenu = aPopupMenu.getArray();
|
|
// Init the property value sequence
|
|
pPopupMenu[ OFFSET_POPUPMENU_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
|
|
pPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT];
|
|
pPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU];
|
|
pPopupMenu[ OFFSET_POPUPMENU_URL ].Name = m_aPropNames[ INDEX_URL ];
|
|
|
|
StringToIndexMap aTitleToIndexMap;
|
|
auto pAddonOfficeMenuBarSeq = rAddonOfficeMenuBarSeq.getArray();
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
|
|
|
|
// Read the MenuItem
|
|
if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
|
|
{
|
|
// Successfully read a popup menu, append to our list
|
|
OUString aPopupTitle;
|
|
if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
|
|
{
|
|
StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
|
|
if ( pIter != aTitleToIndexMap.end() )
|
|
{
|
|
// title already there => concat both popup menus
|
|
Sequence< PropertyValue >& rOldPopupMenu = pAddonOfficeMenuBarSeq[pIter->second];
|
|
AppendPopupMenu( rOldPopupMenu, aPopupMenu );
|
|
}
|
|
else
|
|
{
|
|
// not found
|
|
sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
|
|
rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
|
|
pAddonOfficeMenuBarSeq = rAddonOfficeMenuBarSeq.getArray();
|
|
pAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
|
|
aTitleToIndexMap.emplace( aPopupTitle, nIndex );
|
|
++nIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< OUString >& rAddonOfficeToolBarResNames )
|
|
{
|
|
// Read the OfficeToolBar set and fill property sequences
|
|
OUString aAddonToolBarNodeName( u"AddonUI/OfficeToolBar"_ustr );
|
|
Sequence< OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
|
|
OUString aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
|
|
|
|
sal_uInt32 nCount = aAddonToolBarNodeSeq.getLength();
|
|
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aToolBarItemNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] );
|
|
rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
|
|
rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
|
|
ReadToolBarItemSet( aToolBarItemNode, rAddonOfficeToolBars[n] );
|
|
}
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadToolBarItemSet( const OUString& rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
|
|
{
|
|
sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
|
|
OUString aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
|
|
Sequence< OUString > aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
|
|
Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
|
|
auto pToolBarItem = aToolBarItem.getArray();
|
|
// Init the property value sequence
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Name = m_aPropNames[ INDEX_CONTROLTYPE ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
|
|
|
|
sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
|
|
|
|
// Read the ToolBarItem
|
|
if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
|
|
{
|
|
// Successfully read a toolbar item, append to our list
|
|
sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
|
|
rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
|
|
rAddonOfficeToolBarSeq.getArray()[nAddonCount] = aToolBarItem;
|
|
}
|
|
}
|
|
|
|
return ( o3tl::make_unsigned(rAddonOfficeToolBarSeq.getLength()) > nToolBarItemCount );
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadOfficeNotebookBarSet(
|
|
AddonNotebookBars& rAddonOfficeNotebookBars,
|
|
std::vector<OUString>& rAddonOfficeNotebookBarResNames)
|
|
{
|
|
// Read the OfficeToolBar set and fill property sequences
|
|
OUString aAddonNotebookBarNodeName(u"AddonUI/OfficeNotebookBar"_ustr);
|
|
Sequence<OUString> aAddonNotebookBarNodeSeq = GetNodeNames(aAddonNotebookBarNodeName);
|
|
OUString aAddonNotebookBarNode(aAddonNotebookBarNodeName + m_aPathDelimiter);
|
|
|
|
sal_uInt32 nCount = aAddonNotebookBarNodeSeq.getLength();
|
|
|
|
for (sal_uInt32 n = 0; n < nCount; n++)
|
|
{
|
|
OUString aNotebookBarItemNode(aAddonNotebookBarNode + aAddonNotebookBarNodeSeq[n]);
|
|
rAddonOfficeNotebookBarResNames.push_back(aAddonNotebookBarNodeSeq[n]);
|
|
rAddonOfficeNotebookBars.push_back(m_aEmptyAddonNotebookBar);
|
|
ReadNotebookBarItemSet(aNotebookBarItemNode, rAddonOfficeNotebookBars[n]);
|
|
}
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadNotebookBarItemSet(
|
|
const OUString& rNotebookBarItemSetNodeName,
|
|
Sequence<Sequence<PropertyValue>>& rAddonOfficeNotebookBarSeq)
|
|
{
|
|
sal_uInt32 nNotebookBarItemCount = rAddonOfficeNotebookBarSeq.getLength();
|
|
OUString aAddonNotebookBarItemSetNode(rNotebookBarItemSetNodeName + m_aPathDelimiter);
|
|
Sequence<OUString> aAddonNotebookBarItemSetNodeSeq = GetNodeNames(rNotebookBarItemSetNodeName);
|
|
Sequence<PropertyValue> aNotebookBarItem(PROPERTYCOUNT_NOTEBOOKBARITEM);
|
|
auto pNotebookBarItem = aNotebookBarItem.getArray();
|
|
// Init the property value sequence
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_URL].Name = m_aPropNames[INDEX_URL];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_TITLE].Name = m_aPropNames[INDEX_TITLE];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER].Name
|
|
= m_aPropNames[INDEX_IMAGEIDENTIFIER];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_TARGET].Name = m_aPropNames[INDEX_TARGET];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_CONTEXT].Name = m_aPropNames[INDEX_CONTEXT];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_CONTROLTYPE].Name = m_aPropNames[INDEX_CONTROLTYPE];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_WIDTH].Name = m_aPropNames[INDEX_WIDTH];
|
|
pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_STYLE].Name = m_aPropNames[INDEX_STYLE];
|
|
|
|
sal_uInt32 nCount = aAddonNotebookBarItemSetNodeSeq.getLength();
|
|
for (sal_uInt32 n = 0; n < nCount; n++)
|
|
{
|
|
OUString aNotebookBarItemNode(aAddonNotebookBarItemSetNode
|
|
+ aAddonNotebookBarItemSetNodeSeq[n]);
|
|
// Read the NotebookBarItem
|
|
if (ReadNotebookBarItem(aNotebookBarItemNode, aNotebookBarItem))
|
|
{
|
|
// Successfully read a toolbar item, append to our list
|
|
sal_uInt32 nAddonCount = rAddonOfficeNotebookBarSeq.getLength();
|
|
rAddonOfficeNotebookBarSeq.realloc(nAddonCount + 1);
|
|
rAddonOfficeNotebookBarSeq.getArray()[nAddonCount] = aNotebookBarItem;
|
|
}
|
|
}
|
|
|
|
return (o3tl::make_unsigned(rAddonOfficeNotebookBarSeq.getLength())
|
|
> nNotebookBarItemCount);
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadImages( ImageManager& aImageManager )
|
|
{
|
|
// Read the user-defined Images set and fill image manager
|
|
OUString aAddonImagesNodeName( u"AddonUI/Images"_ustr );
|
|
Sequence< OUString > aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
|
|
OUString aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
|
|
|
|
sal_uInt32 nCount = aAddonImagesNodeSeq.getLength();
|
|
|
|
// Init the property value sequence
|
|
OUString aURL;
|
|
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
|
|
|
|
// Create sequence for data access
|
|
Sequence< OUString > aAddonImageItemNodePropNames = { aImagesItemNode +
|
|
m_aPathDelimiter +
|
|
m_aPropNames[ OFFSET_MENUITEM_URL ] };
|
|
|
|
Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
|
|
|
|
// An user-defined image entry must have a URL. As "ImageIdentifier" has a higher priority
|
|
// we also check if we already have an images association.
|
|
if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
|
|
!aURL.isEmpty() &&
|
|
!HasAssociatedImages( aURL ))
|
|
{
|
|
OUString aImagesUserDefinedItemNode = aImagesItemNode +
|
|
m_aPathDelimiter +
|
|
IMAGES_NODENAME +
|
|
m_aPathDelimiter;
|
|
|
|
// Read a user-defined images data
|
|
std::unique_ptr<ImageEntry> pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
|
|
if ( pImageEntry )
|
|
{
|
|
// Successfully read a user-defined images item, put it into our image manager
|
|
aImageManager.emplace( aURL, std::move(*pImageEntry) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
OUString AddonsOptions_Impl::GeneratePrefixURL()
|
|
{
|
|
// Create a unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
|
|
return m_aRootAddonPopupMenuURLPrexfix + OUString::number( ++m_nRootAddonPopupMenuId );
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer& aContainer )
|
|
{
|
|
static constexpr OUString aMenuMergeRootName( u"AddonUI/OfficeMenuBarMerging/"_ustr );
|
|
|
|
Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
|
|
|
|
sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
|
|
|
|
// Init the property value sequence
|
|
Sequence< OUString > aNodePropNames( 5 );
|
|
auto pNodePropNames = aNodePropNames.getArray();
|
|
|
|
for ( sal_uInt32 i = 0; i < nCount; i++ )
|
|
{
|
|
OUString aMergeAddonInstructions( aMenuMergeRootName + aAddonMergeNodesSeq[i] );
|
|
|
|
Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
|
|
sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
|
|
|
|
for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
|
|
{
|
|
OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
|
|
m_aPathDelimiter +
|
|
aAddonInstMergeNodesSeq[j] +
|
|
m_aPathDelimiter;
|
|
|
|
// Create sequence for data access
|
|
pNodePropNames[0] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ];
|
|
|
|
pNodePropNames[1] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ];
|
|
|
|
pNodePropNames[2] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ];
|
|
|
|
pNodePropNames[3] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ];
|
|
|
|
pNodePropNames[4] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ];
|
|
|
|
Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
|
|
|
|
MergeMenuInstruction aMergeMenuInstruction;
|
|
aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
|
|
aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
|
|
aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
|
|
aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
|
|
aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
|
|
|
|
ReadMergeMenuData( aMergeAddonInstructionBase, aMergeMenuInstruction.aMergeMenu );
|
|
|
|
aContainer.push_back( aMergeMenuInstruction );
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadMergeMenuData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
|
|
{
|
|
OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
|
|
|
|
Sequence< OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
|
|
aMergeMenuBaseNode += m_aPathDelimiter;
|
|
|
|
// extend the node names to have full path strings
|
|
for ( OUString& rName : asNonConstRange(aSubMenuNodeNames) )
|
|
rName = aMergeMenuBaseNode + rName;
|
|
|
|
ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions& rCachedToolbarMergingInstructions )
|
|
{
|
|
static constexpr OUString aToolbarMergeRootName( u"AddonUI/OfficeToolbarMerging/"_ustr );
|
|
|
|
Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
|
|
sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
|
|
|
|
// Init the property value sequence
|
|
Sequence< OUString > aNodePropNames( 6 );
|
|
auto pNodePropNames = aNodePropNames.getArray();
|
|
|
|
for ( sal_uInt32 i = 0; i < nCount; i++ )
|
|
{
|
|
OUString aMergeAddonInstructions( aToolbarMergeRootName + aAddonMergeNodesSeq[i] );
|
|
|
|
Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
|
|
sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
|
|
|
|
for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
|
|
{
|
|
OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
|
|
m_aPathDelimiter +
|
|
aAddonInstMergeNodesSeq[j] +
|
|
m_aPathDelimiter;
|
|
|
|
// Create sequence for data access
|
|
pNodePropNames[0] = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ];
|
|
|
|
pNodePropNames[1] = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ];
|
|
|
|
pNodePropNames[2] = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ];
|
|
|
|
pNodePropNames[3] = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ];
|
|
|
|
pNodePropNames[4] = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ];
|
|
|
|
pNodePropNames[5] = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ];
|
|
|
|
Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
|
|
|
|
MergeToolbarInstruction aMergeToolbarInstruction;
|
|
aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
|
|
aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
|
|
aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
|
|
aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
|
|
aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
|
|
aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
|
|
|
|
ReadMergeToolbarData( aMergeAddonInstructionBase,
|
|
aMergeToolbarInstruction.aMergeToolbarItems );
|
|
|
|
MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
|
|
rVector.push_back( aMergeToolbarInstruction );
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadMergeToolbarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
|
|
{
|
|
OUString aMergeToolbarBaseNode = aMergeAddonInstructionBase +
|
|
m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ];
|
|
|
|
ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadNotebookBarMergeInstructions(
|
|
NotebookBarMergingInstructions& rCachedNotebookBarMergingInstructions)
|
|
{
|
|
static constexpr OUString aNotebookBarMergeRootName(u"AddonUI/OfficeNotebookBarMerging/"_ustr);
|
|
|
|
Sequence<OUString> aAddonMergeNodesSeq = GetNodeNames(aNotebookBarMergeRootName);
|
|
sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
|
|
|
|
// Init the property value sequence
|
|
Sequence<OUString> aNodePropNames(6);
|
|
auto pNodePropNames = aNodePropNames.getArray();
|
|
|
|
for (sal_uInt32 i = 0; i < nCount; i++)
|
|
{
|
|
OUString aMergeAddonInstructions(aNotebookBarMergeRootName + aAddonMergeNodesSeq[i]);
|
|
|
|
Sequence<OUString> aAddonInstMergeNodesSeq = GetNodeNames(aMergeAddonInstructions);
|
|
sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
|
|
|
|
for (sal_uInt32 j = 0; j < nCountAddons; j++)
|
|
{
|
|
OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
|
|
m_aPathDelimiter +
|
|
aAddonInstMergeNodesSeq[j] +
|
|
m_aPathDelimiter;
|
|
|
|
// Create sequence for data access
|
|
pNodePropNames[0] = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR];
|
|
|
|
pNodePropNames[1] = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_MERGEPOINT];
|
|
|
|
pNodePropNames[2] = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND];
|
|
|
|
pNodePropNames[3] = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER];
|
|
|
|
pNodePropNames[4] = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK];
|
|
|
|
pNodePropNames[5] = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT];
|
|
|
|
Sequence<Any> aNodePropValues = GetProperties(aNodePropNames);
|
|
|
|
MergeNotebookBarInstruction aMergeNotebookBarInstruction;
|
|
aNodePropValues[0] >>= aMergeNotebookBarInstruction.aMergeNotebookBar;
|
|
aNodePropValues[1] >>= aMergeNotebookBarInstruction.aMergePoint;
|
|
aNodePropValues[2] >>= aMergeNotebookBarInstruction.aMergeCommand;
|
|
aNodePropValues[3] >>= aMergeNotebookBarInstruction.aMergeCommandParameter;
|
|
aNodePropValues[4] >>= aMergeNotebookBarInstruction.aMergeFallback;
|
|
aNodePropValues[5] >>= aMergeNotebookBarInstruction.aMergeContext;
|
|
|
|
ReadMergeNotebookBarData(aMergeAddonInstructionBase,
|
|
aMergeNotebookBarInstruction.aMergeNotebookBarItems);
|
|
|
|
MergeNotebookBarInstructionContainer& rVector
|
|
= rCachedNotebookBarMergingInstructions[aMergeNotebookBarInstruction
|
|
.aMergeNotebookBar];
|
|
rVector.push_back(aMergeNotebookBarInstruction);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadMergeNotebookBarData(
|
|
std::u16string_view aMergeAddonInstructionBase,
|
|
Sequence<Sequence<PropertyValue>>& rMergeNotebookBarItems)
|
|
{
|
|
OUString aMergeNotebookBarBaseNode = aMergeAddonInstructionBase +
|
|
m_aPropMergeNotebookBarNames[OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS];
|
|
|
|
ReadNotebookBarItemSet(aMergeNotebookBarBaseNode, rMergeNotebookBarItems);
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer& aContainer )
|
|
{
|
|
static constexpr OUString aStatusbarMergeRootName( u"AddonUI/OfficeStatusbarMerging/"_ustr );
|
|
|
|
Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aStatusbarMergeRootName );
|
|
sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
|
|
|
|
Sequence< OUString > aNodePropNames( 5 );
|
|
auto pNodePropNames = aNodePropNames.getArray();
|
|
|
|
for ( sal_uInt32 i = 0; i < nCount; i++ )
|
|
{
|
|
OUString aMergeAddonInstructions( aStatusbarMergeRootName + aAddonMergeNodesSeq[i] );
|
|
|
|
Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
|
|
sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
|
|
|
|
for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
|
|
{
|
|
OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
|
|
m_aPathDelimiter +
|
|
aAddonInstMergeNodesSeq[j] +
|
|
m_aPathDelimiter;
|
|
|
|
// Create sequence for data access
|
|
pNodePropNames[0] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGEPOINT ];
|
|
|
|
pNodePropNames[1] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECOMMAND ];
|
|
|
|
pNodePropNames[2] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER ];
|
|
|
|
pNodePropNames[3] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK ];
|
|
|
|
pNodePropNames[4] = aMergeAddonInstructionBase +
|
|
m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECONTEXT ];
|
|
|
|
Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
|
|
|
|
MergeStatusbarInstruction aMergeStatusbarInstruction;
|
|
aNodePropValues[0] >>= aMergeStatusbarInstruction.aMergePoint;
|
|
aNodePropValues[1] >>= aMergeStatusbarInstruction.aMergeCommand;
|
|
aNodePropValues[2] >>= aMergeStatusbarInstruction.aMergeCommandParameter;
|
|
// aNodePropValues[3] >>= aMergeStatusbarInstruction.aMergeFallback;
|
|
aNodePropValues[4] >>= aMergeStatusbarInstruction.aMergeContext;
|
|
|
|
ReadMergeStatusbarData( aMergeAddonInstructionBase,
|
|
aMergeStatusbarInstruction.aMergeStatusbarItems );
|
|
|
|
aContainer.push_back( aMergeStatusbarInstruction );
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadMergeStatusbarData(
|
|
std::u16string_view aMergeAddonInstructionBase,
|
|
Sequence< Sequence< PropertyValue > >& rMergeStatusbarItems )
|
|
{
|
|
OUString aMergeStatusbarBaseNode = aMergeAddonInstructionBase +
|
|
m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS ];
|
|
|
|
OUString aAddonStatusbarItemSetNode( aMergeStatusbarBaseNode + m_aPathDelimiter );
|
|
Sequence< OUString > aAddonStatusbarItemSetNodeSeq = GetNodeNames( aMergeStatusbarBaseNode );
|
|
|
|
Sequence< PropertyValue > aStatusbarItem( PROPERTYCOUNT_STATUSBARITEM );
|
|
auto pStatusbarItem = aStatusbarItem.getArray();
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN ].Name = m_aPropNames[ INDEX_ALIGN ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE ].Name = m_aPropNames[ INDEX_AUTOSIZE ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW ].Name = m_aPropNames[ INDEX_OWNERDRAW ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_MANDATORY ].Name = m_aPropNames[ INDEX_MANDATORY ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
|
|
|
|
sal_uInt32 nCount = aAddonStatusbarItemSetNodeSeq.getLength();
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
OUString aStatusbarItemNode( aAddonStatusbarItemSetNode + aAddonStatusbarItemSetNodeSeq[n] );
|
|
|
|
if ( ReadStatusBarItem( aStatusbarItemNode, aStatusbarItem ) )
|
|
{
|
|
sal_uInt32 nAddonCount = rMergeStatusbarItems.getLength();
|
|
rMergeStatusbarItems.realloc( nAddonCount+1 );
|
|
rMergeStatusbarItems.getArray()[nAddonCount] = aStatusbarItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadStatusBarItem(
|
|
std::u16string_view aStatusarItemNodeName,
|
|
Sequence< PropertyValue >& aStatusbarItem )
|
|
{
|
|
bool bResult( false );
|
|
OUString aURL;
|
|
OUString aAddonStatusbarItemTreeNode( aStatusarItemNodeName + m_aPathDelimiter );
|
|
|
|
Sequence< Any > aStatusbarItemNodePropValues = GetProperties( GetPropertyNamesStatusbarItem( aAddonStatusbarItemTreeNode ) );
|
|
|
|
// Command URL is required
|
|
if (( aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
|
|
{
|
|
auto pStatusbarItem = aStatusbarItem.getArray();
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_URL ].Value <<= aURL;
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_TITLE ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_TITLE ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_CONTEXT ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_ALIGN ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_AUTOSIZE ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_OWNERDRAW ];
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_MANDATORY ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_MANDATORY ];
|
|
|
|
// Configuration uses hyper for long. Therefore transform into sal_Int32
|
|
sal_Int64 nValue( 0 );
|
|
aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_WIDTH ] >>= nValue;
|
|
pStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
|
|
|
|
bResult = true;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadMenuItem( std::u16string_view aMenuNodeName, Sequence< PropertyValue >& aMenuItem, bool bIgnoreSubMenu )
|
|
{
|
|
bool bResult = false;
|
|
OUString aStrValue;
|
|
OUString aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
|
|
|
|
Sequence< Any > aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
|
|
if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && !aStrValue.isEmpty() )
|
|
{
|
|
auto pMenuItem = aMenuItem.getArray();
|
|
pMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
|
|
|
|
OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
|
|
Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
|
|
if ( aRootSubMenuNodeNames.hasElements() && !bIgnoreSubMenu )
|
|
{
|
|
// Set a unique prefixed Add-On popup menu URL so it can be identified later
|
|
OUString aPopupMenuURL = GeneratePrefixURL();
|
|
OUString aPopupMenuImageId;
|
|
|
|
aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
|
|
ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
|
|
|
|
// A popup menu must have a title and can have a URL and ImageIdentifier
|
|
// Set the other property values to empty
|
|
pMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aPopupMenuURL;
|
|
pMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= OUString();
|
|
pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aPopupMenuImageId;
|
|
pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value = aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
|
|
|
|
// Continue to read the sub menu nodes
|
|
Sequence< Sequence< PropertyValue > > aSubMenuSeq;
|
|
OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
|
|
for ( OUString& rName : asNonConstRange(aRootSubMenuNodeNames) )
|
|
rName = aSubMenuRootNodeName + rName;
|
|
ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
|
|
pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
|
|
bResult = true;
|
|
}
|
|
else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && !aStrValue.isEmpty() )
|
|
{
|
|
// A simple menu item => read the other properties;
|
|
OUString aMenuImageId;
|
|
|
|
aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
|
|
ReadAndAssociateImages( aStrValue, aMenuImageId );
|
|
|
|
pMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
|
|
pMenuItem[ OFFSET_MENUITEM_TARGET ].Value = aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET ];
|
|
pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aMenuImageId;
|
|
pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value = aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
|
|
pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
|
|
|
|
bResult = true;
|
|
}
|
|
}
|
|
else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
|
|
aStrValue == SEPARATOR_URL )
|
|
{
|
|
auto pMenuItem = aMenuItem.getArray();
|
|
|
|
// Separator
|
|
pMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
|
|
pMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= OUString();
|
|
pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= OUString();
|
|
pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= OUString();
|
|
pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
|
|
bResult = true;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadPopupMenu( std::u16string_view aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
|
|
{
|
|
bool bResult = false;
|
|
OUString aStrValue;
|
|
OUString aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
|
|
|
|
Sequence< Any > aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
|
|
if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
|
|
!aStrValue.isEmpty() )
|
|
{
|
|
auto pPopupMenu = aPopupMenu.getArray();
|
|
pPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
|
|
|
|
OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
|
|
Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
|
|
if ( aRootSubMenuNodeNames.hasElements() )
|
|
{
|
|
// A top-level popup menu needs a title
|
|
// Set a unique prefixed Add-On popup menu URL so it can be identified later
|
|
OUString aPopupMenuURL = GeneratePrefixURL();
|
|
|
|
pPopupMenu[ OFFSET_POPUPMENU_URL ].Value <<= aPopupMenuURL;
|
|
pPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Value = aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
|
|
|
|
// Continue to read the sub menu nodes
|
|
Sequence< Sequence< PropertyValue > > aSubMenuSeq;
|
|
OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
|
|
for ( OUString& rName : asNonConstRange(aRootSubMenuNodeNames) )
|
|
rName = aSubMenuRootNodeName + rName;
|
|
ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
|
|
pPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// static
|
|
void AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
|
|
{
|
|
Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
|
|
Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
|
|
|
|
if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
|
|
( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
|
|
{
|
|
sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
|
|
aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
|
|
auto pTargetSubMenuSeq = aTargetSubMenuSeq.getArray();
|
|
for (Sequence<PropertyValue> const& rSeq : aSourceSubMenuSeq)
|
|
pTargetSubMenuSeq[nIndex++] = rSeq;
|
|
rTargetPopupMenu.getArray()[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
|
|
}
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadToolBarItem( std::u16string_view aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
|
|
{
|
|
bool bResult = false;
|
|
OUString aURL;
|
|
OUString aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
|
|
|
|
Sequence< Any > aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
|
|
|
|
// A toolbar item must have a command URL
|
|
if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && !aURL.isEmpty() )
|
|
{
|
|
OUString aTitle;
|
|
if ( aURL == SEPARATOR_URL )
|
|
{
|
|
auto pToolBarItem = aToolBarItem.getArray();
|
|
|
|
// A separator toolbar item only needs a URL
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= OUString();
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= OUString();
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= OUString();
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= OUString();
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= OUString();
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
|
|
|
|
bResult = true;
|
|
}
|
|
else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE ] >>= aTitle ) && !aTitle.isEmpty() )
|
|
{
|
|
auto pToolBarItem = aToolBarItem.getArray();
|
|
|
|
// A normal toolbar item must also have title => read the other properties;
|
|
OUString aImageId;
|
|
|
|
// Try to map a user-defined image URL to our internal private image URL
|
|
aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
|
|
ReadAndAssociateImages( aURL, aImageId );
|
|
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= aTitle;
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value = aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value = aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT ];
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value = aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
|
|
|
|
// Configuration uses hyper for long. Therefore transform into sal_Int32
|
|
sal_Int64 nValue( 0 );
|
|
aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
|
|
pToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
|
|
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
bool AddonsOptions_Impl::ReadNotebookBarItem( std::u16string_view aNotebookBarItemNodeName, Sequence< PropertyValue >& aNotebookBarItem )
|
|
{
|
|
bool bResult = false;
|
|
OUString aURL;
|
|
OUString aAddonNotebookBarItemTreeNode( aNotebookBarItemNodeName + m_aPathDelimiter );
|
|
|
|
Sequence< Any > aNotebookBarItemNodePropValues = GetProperties( GetPropertyNamesNotebookBarItem( aAddonNotebookBarItemTreeNode ) );
|
|
|
|
// A toolbar item must have a command URL
|
|
if (( aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_URL ] >>= aURL ) && !aURL.isEmpty() )
|
|
{
|
|
OUString aTitle;
|
|
if ( aURL == SEPARATOR_URL )
|
|
{
|
|
auto pNotebookBarItem = aNotebookBarItem.getArray();
|
|
|
|
// A separator toolbar item only needs a URL
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_URL ].Value <<= aURL;
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TITLE ].Value <<= OUString();
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TARGET ].Value <<= OUString();
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER ].Value <<= OUString();
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTEXT ].Value <<= OUString();
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE ].Value <<= OUString();
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_STYLE ].Value <<= OUString();
|
|
|
|
bResult = true;
|
|
}
|
|
else if (( aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_TITLE ] >>= aTitle ) && !aTitle.isEmpty() )
|
|
{
|
|
auto pNotebookBarItem = aNotebookBarItem.getArray();
|
|
|
|
// A normal toolbar item must also have title => read the other properties;
|
|
OUString aImageId;
|
|
|
|
// Try to map a user-defined image URL to our internal private image URL
|
|
aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
|
|
ReadAndAssociateImages( aURL, aImageId );
|
|
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_URL ].Value <<= aURL;
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TITLE ].Value <<= aTitle;
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TARGET ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_TARGET ];
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTEXT ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_CONTEXT ];
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE ];
|
|
|
|
// Configuration uses hyper for long. Therefore transform into sal_Int32
|
|
sal_Int64 nValue( 0 );
|
|
aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_WIDTH ] >>= nValue;
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
|
|
pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_STYLE ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_STYLE ];
|
|
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
|
|
{
|
|
Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
|
|
auto pMenuItem = aMenuItem.getArray();
|
|
|
|
// Init the property value sequence
|
|
pMenuItem[ OFFSET_MENUITEM_URL ].Name = PROPERTYNAME_URL;
|
|
pMenuItem[ OFFSET_MENUITEM_TITLE ].Name = PROPERTYNAME_TITLE;
|
|
pMenuItem[ OFFSET_MENUITEM_TARGET ].Name = PROPERTYNAME_TARGET;
|
|
pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER;
|
|
pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = PROPERTYNAME_CONTEXT;
|
|
pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = PROPERTYNAME_SUBMENU; // Submenu set!
|
|
|
|
sal_uInt32 nIndex = 0;
|
|
sal_uInt32 nCount = aSubMenuNodeNames.getLength();
|
|
for ( sal_uInt32 n = 0; n < nCount; n++ )
|
|
{
|
|
if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
|
|
{
|
|
sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
|
|
rSubMenuSeq.realloc( nSubMenuCount );
|
|
rSubMenuSeq.getArray()[nIndex++] = aMenuItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AddonsOptions_Impl::HasAssociatedImages( const OUString& aURL )
|
|
{
|
|
// FIXME: potentially this is not so useful in a world of delayed image loading
|
|
ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
|
|
return ( pIter != m_aImageManager.end() );
|
|
}
|
|
|
|
// static
|
|
void AddonsOptions_Impl::SubstituteVariables( OUString& aURL )
|
|
{
|
|
aURL = comphelper::getExpandedUri(
|
|
comphelper::getProcessComponentContext(), aURL);
|
|
}
|
|
|
|
// static
|
|
BitmapEx AddonsOptions_Impl::ReadImageFromURL(const OUString& aImageURL)
|
|
{
|
|
BitmapEx aImage;
|
|
|
|
std::unique_ptr<SvStream> pStream = UcbStreamHelper::CreateStream( aImageURL, StreamMode::STD_READ );
|
|
if ( pStream && ( pStream->GetErrorCode() == ERRCODE_NONE ))
|
|
{
|
|
// Use graphic class to also support more graphic formats (bmp,png,...)
|
|
Graphic aGraphic;
|
|
|
|
GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
|
|
rGF.ImportGraphic( aGraphic, u"", *pStream );
|
|
|
|
BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
|
|
|
|
Size aBmpSize = aBitmapEx.GetSizePixel();
|
|
if ( !aBmpSize.IsEmpty() )
|
|
{
|
|
// Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
|
|
if( !aBitmapEx.IsAlpha() )
|
|
aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
|
|
|
|
aImage = aBitmapEx;
|
|
}
|
|
}
|
|
|
|
return aImage;
|
|
}
|
|
|
|
void AddonsOptions_Impl::ReadAndAssociateImages( const OUString& aURL, const OUString& aImageId )
|
|
{
|
|
if ( aImageId.isEmpty() )
|
|
return;
|
|
|
|
ImageEntry aImageEntry;
|
|
OUString aImageURL( aImageId );
|
|
|
|
SubstituteVariables( aImageURL );
|
|
|
|
// Loop to create the two possible image names and try to read the bitmap files
|
|
static const char* aExtArray[] = { "_16", "_26" };
|
|
for ( size_t i = 0; i < std::size(aExtArray); i++ )
|
|
{
|
|
OUStringBuffer aFileURL( aImageURL );
|
|
aFileURL.appendAscii( aExtArray[i] );
|
|
aFileURL.append( ".bmp" );
|
|
|
|
aImageEntry.addImage( !i ? IMGSIZE_SMALL : IMGSIZE_BIG, aFileURL.makeStringAndClear() );
|
|
}
|
|
|
|
m_aImageManager.emplace( aURL, aImageEntry );
|
|
}
|
|
|
|
std::unique_ptr<AddonsOptions_Impl::ImageEntry> AddonsOptions_Impl::ReadImageData( std::u16string_view aImagesNodeName )
|
|
{
|
|
Sequence< OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
|
|
Sequence< Any > aPropertyData;
|
|
Sequence< sal_Int8 > aImageDataSeq;
|
|
OUString aImageURL;
|
|
|
|
std::unique_ptr<ImageEntry> pEntry;
|
|
|
|
// It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
|
|
// same time. Embedded image data has a higher priority.
|
|
aPropertyData = GetProperties( aImageDataNodeNames );
|
|
for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
|
|
{
|
|
if ( i < PROPERTYCOUNT_EMBEDDED_IMAGES )
|
|
{
|
|
// Extract image data from the embedded hex binary sequence
|
|
BitmapEx aImage;
|
|
if (( aPropertyData[i] >>= aImageDataSeq ) &&
|
|
aImageDataSeq.hasElements() &&
|
|
( CreateImageFromSequence( aImage, aImageDataSeq ) ) )
|
|
{
|
|
if ( !pEntry )
|
|
pEntry.reset(new ImageEntry);
|
|
pEntry->addImage(i == OFFSET_IMAGES_SMALL ? IMGSIZE_SMALL : IMGSIZE_BIG, aImage);
|
|
}
|
|
}
|
|
else if ( i == OFFSET_IMAGES_SMALL_URL || i == OFFSET_IMAGES_BIG_URL )
|
|
{
|
|
if(!pEntry)
|
|
pEntry.reset(new ImageEntry());
|
|
|
|
// Retrieve image data from an external bitmap file. Make sure that embedded image data
|
|
// has a higher priority.
|
|
if (aPropertyData[i] >>= aImageURL)
|
|
{
|
|
SubstituteVariables(aImageURL);
|
|
pEntry->addImage(i == OFFSET_IMAGES_SMALL_URL ? IMGSIZE_SMALL : IMGSIZE_BIG, aImageURL);
|
|
}
|
|
}
|
|
}
|
|
|
|
return pEntry;
|
|
}
|
|
|
|
// static
|
|
bool AddonsOptions_Impl::CreateImageFromSequence( BitmapEx& rImage, Sequence< sal_Int8 >& rBitmapDataSeq )
|
|
{
|
|
bool bResult = false;
|
|
|
|
if ( rBitmapDataSeq.hasElements() )
|
|
{
|
|
SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), StreamMode::STD_READ );
|
|
|
|
ReadDIBBitmapEx(rImage, aMemStream);
|
|
|
|
if( !rImage.IsAlpha() )
|
|
{
|
|
// Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
|
|
rImage = BitmapEx( rImage.GetBitmap(), COL_LIGHTMAGENTA );
|
|
}
|
|
|
|
bResult = true;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( std::u16string_view aPropertyRootNode ) const
|
|
{
|
|
Sequence< OUString > lResult( PROPERTYCOUNT_MENUITEM );
|
|
auto plResult = lResult.getArray();
|
|
|
|
// Create property names dependent from the root node name
|
|
plResult[OFFSET_MENUITEM_URL] = aPropertyRootNode + m_aPropNames[ INDEX_URL ];
|
|
plResult[OFFSET_MENUITEM_TITLE] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
|
|
plResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ];
|
|
plResult[OFFSET_MENUITEM_TARGET] = aPropertyRootNode + m_aPropNames[ INDEX_TARGET ];
|
|
plResult[OFFSET_MENUITEM_CONTEXT] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
|
|
plResult[OFFSET_MENUITEM_SUBMENU] = aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ];
|
|
|
|
return lResult;
|
|
}
|
|
|
|
Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( std::u16string_view aPropertyRootNode ) const
|
|
{
|
|
// The URL is automatically set and not read from the configuration.
|
|
Sequence< OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
|
|
auto plResult = lResult.getArray();
|
|
|
|
// Create property names dependent from the root node name
|
|
plResult[OFFSET_POPUPMENU_TITLE] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
|
|
plResult[OFFSET_POPUPMENU_CONTEXT] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
|
|
plResult[OFFSET_POPUPMENU_SUBMENU] = aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ];
|
|
|
|
return lResult;
|
|
}
|
|
|
|
Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( std::u16string_view aPropertyRootNode ) const
|
|
{
|
|
Sequence< OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
|
|
auto plResult = lResult.getArray();
|
|
|
|
// Create property names dependent from the root node name
|
|
plResult[0] = aPropertyRootNode + m_aPropNames[ INDEX_URL ];
|
|
plResult[1] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
|
|
plResult[2] = aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER];
|
|
plResult[3] = aPropertyRootNode + m_aPropNames[ INDEX_TARGET ];
|
|
plResult[4] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
|
|
plResult[5] = aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ];
|
|
plResult[6] = aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ];
|
|
|
|
return lResult;
|
|
}
|
|
|
|
Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesNotebookBarItem( std::u16string_view aPropertyRootNode ) const
|
|
{
|
|
Sequence< OUString > lResult( PROPERTYCOUNT_NOTEBOOKBARITEM );
|
|
auto plResult = lResult.getArray();
|
|
|
|
// Create property names dependent from the root node name
|
|
plResult[0] = aPropertyRootNode + m_aPropNames[ INDEX_URL ];
|
|
plResult[1] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
|
|
plResult[2] = aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER];
|
|
plResult[3] = aPropertyRootNode + m_aPropNames[ INDEX_TARGET ];
|
|
plResult[4] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
|
|
plResult[5] = aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ];
|
|
plResult[6] = aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ];
|
|
plResult[7] = aPropertyRootNode + m_aPropNames[ INDEX_STYLE ];
|
|
|
|
return lResult;
|
|
}
|
|
|
|
Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesStatusbarItem(
|
|
std::u16string_view aPropertyRootNode ) const
|
|
{
|
|
Sequence< OUString > lResult( PROPERTYCOUNT_STATUSBARITEM );
|
|
auto plResult = lResult.getArray();
|
|
|
|
plResult[0] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
|
|
plResult[1] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
|
|
plResult[2] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
|
|
plResult[3] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_ALIGN ] );
|
|
plResult[4] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_AUTOSIZE ] );
|
|
plResult[5] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_OWNERDRAW ] );
|
|
plResult[6] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_MANDATORY ] );
|
|
plResult[7] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ] );
|
|
|
|
return lResult;
|
|
}
|
|
|
|
Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesImages( std::u16string_view aPropertyRootNode ) const
|
|
{
|
|
Sequence< OUString > lResult( PROPERTYCOUNT_IMAGES );
|
|
auto plResult = lResult.getArray();
|
|
|
|
// Create property names dependent from the root node name
|
|
plResult[0] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL ];
|
|
plResult[1] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG ];
|
|
plResult[2] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ];
|
|
plResult[3] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ];
|
|
plResult[4] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ];
|
|
plResult[5] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ];
|
|
plResult[6] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL];
|
|
plResult[7] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ];
|
|
|
|
return lResult;
|
|
}
|
|
|
|
namespace{
|
|
//global
|
|
std::weak_ptr<AddonsOptions_Impl> g_pAddonsOptions;
|
|
}
|
|
|
|
AddonsOptions::AddonsOptions()
|
|
{
|
|
// Global access, must be guarded (multithreading!).
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
|
|
m_pImpl = g_pAddonsOptions.lock();
|
|
if( !m_pImpl )
|
|
{
|
|
m_pImpl = std::make_shared<AddonsOptions_Impl>();
|
|
g_pAddonsOptions = m_pImpl;
|
|
}
|
|
}
|
|
|
|
AddonsOptions::~AddonsOptions()
|
|
{
|
|
// Global access, must be guarded (multithreading!)
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
|
|
m_pImpl.reset();
|
|
}
|
|
|
|
// public method
|
|
|
|
bool AddonsOptions::HasAddonsMenu() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->HasAddonsMenu();
|
|
}
|
|
|
|
// public method
|
|
|
|
sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsToolBarCount();
|
|
}
|
|
|
|
// public method
|
|
|
|
sal_Int32 AddonsOptions::GetAddonsNotebookBarCount() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsNotebookBarCount();
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsMenu();
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsMenuBarPart();
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsToolBarPart( nIndex );
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsNotebookBarPart( sal_uInt32 nIndex ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsNotebookBarPart( nIndex );
|
|
}
|
|
|
|
// public method
|
|
|
|
OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsToolbarResourceName( nIndex );
|
|
}
|
|
|
|
// public method
|
|
|
|
OUString AddonsOptions::GetAddonsNotebookBarResourceName( sal_uInt32 nIndex ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsNotebookBarResourceName( nIndex );
|
|
}
|
|
|
|
// public method
|
|
|
|
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetAddonsHelpMenu();
|
|
}
|
|
|
|
// public method
|
|
|
|
const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetMergeMenuInstructions();
|
|
}
|
|
|
|
// public method
|
|
|
|
bool AddonsOptions::GetMergeToolbarInstructions(
|
|
const OUString& rToolbarName,
|
|
MergeToolbarInstructionContainer& rToolbarInstructions ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetMergeToolbarInstructions(
|
|
rToolbarName, rToolbarInstructions );
|
|
}
|
|
|
|
// public method
|
|
|
|
bool AddonsOptions::GetMergeNotebookBarInstructions(
|
|
const OUString& rNotebookBarName,
|
|
MergeNotebookBarInstructionContainer& rNotebookBarInstructions ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetMergeNotebookBarInstructions(
|
|
rNotebookBarName, rNotebookBarInstructions );
|
|
}
|
|
|
|
//public method
|
|
|
|
const MergeStatusbarInstructionContainer& AddonsOptions::GetMergeStatusbarInstructions() const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetMergeStatusbarInstructions();
|
|
}
|
|
|
|
// public method
|
|
|
|
BitmapEx AddonsOptions::GetImageFromURL( const OUString& aURL, bool bBig, bool bNoScale ) const
|
|
{
|
|
MutexGuard aGuard( GetOwnStaticMutex() );
|
|
return m_pImpl->GetImageFromURL( aURL, bBig, bNoScale );
|
|
}
|
|
|
|
// public method
|
|
|
|
BitmapEx AddonsOptions::GetImageFromURL( const OUString& aURL, bool bBig ) const
|
|
{
|
|
return GetImageFromURL( aURL, bBig, false );
|
|
}
|
|
|
|
Mutex& AddonsOptions::GetOwnStaticMutex()
|
|
{
|
|
// Create static mutex variable.
|
|
static Mutex ourMutex;
|
|
|
|
return ourMutex;
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AddonsOptions_Impl, NotifyEvent, void*, void)
|
|
{
|
|
MutexGuard aGuard(AddonsOptions::GetOwnStaticMutex());
|
|
ReadConfigurationData();
|
|
}
|
|
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|