LibreOffice Module framework (master) 1
addonsoptions.cxx
Go to the documentation of this file.
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 <com/sun/star/beans/PropertyValue.hpp>
22#include <o3tl/safeint.hxx>
26#include <tools/stream.hxx>
27#include <com/sun/star/uno/Any.hxx>
28#include <com/sun/star/uno/Sequence.hxx>
29#include <rtl/ustrbuf.hxx>
30#include <sal/log.hxx>
33#include <vcl/dibtools.hxx>
34#include <vcl/graph.hxx>
35#include <vcl/graphicfilter.hxx>
36#include <vcl/toolbox.hxx>
37#include <vcl/svapp.hxx>
38
39#include <algorithm>
40#include <string_view>
41#include <unordered_map>
42#include <vector>
43
44// namespaces
45
46using namespace ::utl;
47using namespace ::osl;
48using namespace ::com::sun::star::uno;
49using namespace ::com::sun::star::beans;
50using namespace ::com::sun::star::lang;
51using namespace ::com::sun::star;
52
53constexpr OUStringLiteral ROOTNODE_ADDONMENU = u"Office.Addons";
54constexpr OUStringLiteral PATHDELIMITER = u"/";
55constexpr OUStringLiteral SEPARATOR_URL = u"private:separator";
56
57#define PROPERTYNAME_URL ADDONSMENUITEM_STRING_URL
58#define PROPERTYNAME_TITLE ADDONSMENUITEM_STRING_TITLE
59#define PROPERTYNAME_TARGET ADDONSMENUITEM_STRING_TARGET
60#define PROPERTYNAME_IMAGEIDENTIFIER ADDONSMENUITEM_STRING_IMAGEIDENTIFIER
61#define PROPERTYNAME_CONTEXT ADDONSMENUITEM_STRING_CONTEXT
62#define PROPERTYNAME_SUBMENU ADDONSMENUITEM_STRING_SUBMENU
63
64constexpr OUStringLiteral IMAGES_NODENAME = u"UserDefinedImages";
65
66// The following order is mandatory. Please add properties at the end!
67#define INDEX_URL 0
68#define INDEX_TITLE 1
69#define INDEX_IMAGEIDENTIFIER 2
70#define INDEX_TARGET 3
71#define INDEX_CONTEXT 4
72#define INDEX_SUBMENU 5
73#define INDEX_CONTROLTYPE 6
74#define INDEX_WIDTH 7
75#define INDEX_ALIGN 8
76#define INDEX_AUTOSIZE 9
77#define INDEX_OWNERDRAW 10
78#define INDEX_MANDATORY 11
79#define INDEX_STYLE 12
80#define PROPERTYCOUNT_INDEX 13
81
82// The following order is mandatory. Please add properties at the end!
83#define PROPERTYCOUNT_MENUITEM 6
84#define OFFSET_MENUITEM_URL 0
85#define OFFSET_MENUITEM_TITLE 1
86#define OFFSET_MENUITEM_IMAGEIDENTIFIER 2
87#define OFFSET_MENUITEM_TARGET 3
88#define OFFSET_MENUITEM_CONTEXT 4
89#define OFFSET_MENUITEM_SUBMENU 5
90
91// The following order is mandatory. Please add properties at the end!
92#define PROPERTYCOUNT_POPUPMENU 4
93#define OFFSET_POPUPMENU_TITLE 0
94#define OFFSET_POPUPMENU_CONTEXT 1
95#define OFFSET_POPUPMENU_SUBMENU 2
96#define OFFSET_POPUPMENU_URL 3 // Used for property set
97
98// The following order is mandatory. Please add properties at the end!
99#define PROPERTYCOUNT_TOOLBARITEM 7
100#define OFFSET_TOOLBARITEM_URL 0
101#define OFFSET_TOOLBARITEM_TITLE 1
102#define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER 2
103#define OFFSET_TOOLBARITEM_TARGET 3
104#define OFFSET_TOOLBARITEM_CONTEXT 4
105#define OFFSET_TOOLBARITEM_CONTROLTYPE 5
106#define OFFSET_TOOLBARITEM_WIDTH 6
107
108// The following order is mandatory. Please add properties at the end!
109#define PROPERTYCOUNT_NOTEBOOKBARITEM 8
110#define OFFSET_NOTEBOOKBARITEM_URL 0
111#define OFFSET_NOTEBOOKBARITEM_TITLE 1
112#define OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER 2
113#define OFFSET_NOTEBOOKBARITEM_TARGET 3
114#define OFFSET_NOTEBOOKBARITEM_CONTEXT 4
115#define OFFSET_NOTEBOOKBARITEM_CONTROLTYPE 5
116#define OFFSET_NOTEBOOKBARITEM_WIDTH 6
117#define OFFSET_NOTEBOOKBARITEM_STYLE 7
118
119// The following order is mandatory. Please add properties at the end!
120#define PROPERTYCOUNT_STATUSBARITEM 8
121#define OFFSET_STATUSBARITEM_URL 0
122#define OFFSET_STATUSBARITEM_TITLE 1
123#define OFFSET_STATUSBARITEM_CONTEXT 2
124#define OFFSET_STATUSBARITEM_ALIGN 3
125#define OFFSET_STATUSBARITEM_AUTOSIZE 4
126#define OFFSET_STATUSBARITEM_OWNERDRAW 5
127#define OFFSET_STATUSBARITEM_MANDATORY 6
128#define OFFSET_STATUSBARITEM_WIDTH 7
129
130// The following order is mandatory. Please add properties at the end!
131#define PROPERTYCOUNT_IMAGES 8
132#define PROPERTYCOUNT_EMBEDDED_IMAGES 2
133#define OFFSET_IMAGES_SMALL 0
134#define OFFSET_IMAGES_BIG 1
135#define OFFSET_IMAGES_SMALLHC 2
136#define OFFSET_IMAGES_BIGHC 3
137#define OFFSET_IMAGES_SMALL_URL 4
138#define OFFSET_IMAGES_BIG_URL 5
139#define OFFSET_IMAGES_SMALLHC_URL 6
140#define OFFSET_IMAGES_BIGHC_URL 7
141
142#define PROPERTYCOUNT_MERGE_MENUBAR 6
143#define OFFSET_MERGEMENU_MERGEPOINT 0
144#define OFFSET_MERGEMENU_MERGECOMMAND 1
145#define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER 2
146#define OFFSET_MERGEMENU_MERGEFALLBACK 3
147#define OFFSET_MERGEMENU_MERGECONTEXT 4
148#define OFFSET_MERGEMENU_MENUITEMS 5
149
150#define PROPERTYCOUNT_MERGE_TOOLBAR 7
151#define OFFSET_MERGETOOLBAR_TOOLBAR 0
152#define OFFSET_MERGETOOLBAR_MERGEPOINT 1
153#define OFFSET_MERGETOOLBAR_MERGECOMMAND 2
154#define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER 3
155#define OFFSET_MERGETOOLBAR_MERGEFALLBACK 4
156#define OFFSET_MERGETOOLBAR_MERGECONTEXT 5
157#define OFFSET_MERGETOOLBAR_TOOLBARITEMS 6
158
159#define PROPERTYCOUNT_MERGE_NOTEBOOKBAR 7
160#define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR 0
161#define OFFSET_MERGENOTEBOOKBAR_MERGEPOINT 1
162#define OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND 2
163#define OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER 3
164#define OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK 4
165#define OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT 5
166#define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS 6
167
168#define PROPERTYCOUNT_MERGE_STATUSBAR 6
169#define OFFSET_MERGESTATUSBAR_MERGEPOINT 0
170#define OFFSET_MERGESTATUSBAR_MERGECOMMAND 1
171#define OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER 2
172#define OFFSET_MERGESTATUSBAR_MERGEFALLBACK 3
173#define OFFSET_MERGESTATUSBAR_MERGECONTEXT 4
174#define OFFSET_MERGESTATUSBAR_STATUSBARITEMS 5
175
176// private declarations!
177
178/*-****************************************************************************************************************
179 @descr struct to hold information about one menu entry.
180****************************************************************************************************************-*/
181
182namespace framework
183{
184
185class AddonsOptions_Impl : public ConfigItem
186{
187
188 // public methods
189
190 public:
191
192 // constructor / destructor
193
195 virtual ~AddonsOptions_Impl() override;
196
197 // overridden methods of baseclass
198
199 /*-****************************************************************************************************
200 @short called for notify of configmanager
201 @descr This method is called from the ConfigManager before application ends or from the
202 PropertyChangeListener if the sub tree broadcasts changes. You must update your
203 internal values.
204
205 @seealso baseclass ConfigItem
206
207 @param "lPropertyNames" is the list of properties which should be updated.
208 *//*-*****************************************************************************************************/
209
210 virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
211
212 // public interface
213
214 /*-****************************************************************************************************
215 @short base implementation of public interface for "SvtDynamicMenuOptions"!
216 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
217 => The code exist only for one time and isn't duplicated for every instance!
218 *//*-*****************************************************************************************************/
219
220 bool HasAddonsMenu () const;
221 sal_Int32 GetAddonsToolBarCount() const;
222 sal_Int32 GetAddonsNotebookBarCount() const;
223 const Sequence< Sequence< PropertyValue > >& GetAddonsMenu () const { return m_aCachedMenuProperties;}
224 const Sequence< Sequence< PropertyValue > >& GetAddonsMenuBarPart () const { return m_aCachedMenuBarPartProperties;}
225 const Sequence< Sequence< PropertyValue > >& GetAddonsToolBarPart ( sal_uInt32 nIndex ) const;
226 const Sequence< Sequence< PropertyValue > >& GetAddonsNotebookBarPart ( sal_uInt32 nIndex ) const;
227 OUString GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
228 OUString GetAddonsNotebookBarResourceName( sal_uInt32 nIndex ) const;
229 const Sequence< Sequence< PropertyValue > >& GetAddonsHelpMenu () const { return m_aCachedHelpMenuProperties;}
230 BitmapEx GetImageFromURL( const OUString& aURL, bool bBig, bool bNoScale );
232 bool GetMergeToolbarInstructions( const OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
233 bool GetMergeNotebookBarInstructions( const OUString& rNotebookBarName, MergeNotebookBarInstructionContainer& rNotebookBarInstructions ) const;
236
237 private:
239 {
242 };
243
245 {
248 OUString aURL;
249 };
250
252 {
253 // if the image is set, it was embedded in some way,
254 // otherwise we use the associated URL to load on demand
255
256 // accessed in this order
259 void addImage(ImageSize eSize, const BitmapEx &rImage);
260 void addImage(ImageSize eSize, const OUString &rURL);
261 };
262
263 typedef std::unordered_map< OUString, ImageEntry > ImageManager;
264 typedef std::unordered_map< OUString, sal_uInt32 > StringToIndexMap;
265 typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
266 typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonNotebookBars;
267 typedef std::unordered_map< OUString, MergeToolbarInstructionContainer > ToolbarMergingInstructions;
268 typedef std::unordered_map< OUString, MergeNotebookBarInstructionContainer > NotebookBarMergingInstructions;
269
270 /*-****************************************************************************************************
271 @short return list of key names of our configuration management which represent our module tree
272 @descr These methods return the current list of key names! We need it to get needed values from our
273 configuration management!
274 @param "nCount" , returns count of menu entries for "new"
275 @return A list of configuration key names is returned.
276 *//*-*****************************************************************************************************/
277
278 void ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
279 void ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
280 void ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< OUString >& rAddonOfficeToolBarResNames );
281 bool ReadToolBarItemSet( const OUString& rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
282 void ReadOfficeNotebookBarSet( AddonNotebookBars& rAddonOfficeNotebookBars, std::vector< OUString >& rAddonOfficeNotebookBarResNames );
283 bool ReadNotebookBarItemSet( const OUString& rNotebookBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeNotebookBarSeq );
284
285 void ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
286 void ReadImages( ImageManager& aImageManager );
291
292 void ReadMergeMenuData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
293 void ReadMergeToolbarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
294 void ReadMergeNotebookBarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeNotebookBarItems );
295 void ReadMergeStatusbarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeStatusbar );
296 bool ReadMenuItem( std::u16string_view aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, bool bIgnoreSubMenu = false );
297 bool ReadPopupMenu( std::u16string_view aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
298 void AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
299 bool ReadToolBarItem( std::u16string_view aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
300 bool ReadNotebookBarItem( std::u16string_view aNotebookBarItemNodeName, Sequence< PropertyValue >& aNotebookBarItem );
301
302 bool ReadStatusBarItem( std::u16string_view aStatusbarItemNodeName, Sequence< PropertyValue >& aStatusbarItem );
303 std::unique_ptr<ImageEntry> ReadImageData( std::u16string_view aImagesNodeName );
304 void ReadAndAssociateImages( const OUString& aURL, const OUString& aImageId );
305 BitmapEx ReadImageFromURL( const OUString& aURL );
306 bool HasAssociatedImages( const OUString& aURL );
307 void SubstituteVariables( OUString& aURL );
308
309 void ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
310 OUString GeneratePrefixURL();
311
312 Sequence< OUString > GetPropertyNamesMenuItem( std::u16string_view aPropertyRootNode )
313 const;
314 Sequence< OUString > GetPropertyNamesPopupMenu( std::u16string_view aPropertyRootNode )
315 const;
316 Sequence< OUString > GetPropertyNamesToolBarItem( std::u16string_view aPropertyRootNode )
317 const;
318 Sequence< OUString > GetPropertyNamesNotebookBarItem( std::u16string_view aPropertyRootNode ) const;
319
320 Sequence< OUString > GetPropertyNamesStatusbarItem( std::u16string_view aPropertyRootNode ) const;
321 Sequence< OUString > GetPropertyNamesImages( std::u16string_view aPropertyRootNode ) const;
322 bool CreateImageFromSequence( BitmapEx& rImage, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
323
324 DECL_LINK(NotifyEvent, void*, void);
325
326 virtual void ImplCommit() override;
327
328 // private member
329
330 private:
340 Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties;
341 Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties;
344 std::vector< OUString > m_aCachedToolBarPartResourceNames;
346 Sequence< Sequence< PropertyValue > > m_aCachedHelpMenuProperties;
348 Sequence< Sequence< PropertyValue > > m_aEmptyAddonToolBar;
349 Sequence< Sequence< PropertyValue > > m_aEmptyAddonNotebookBar;
354};
355
357{
358 aSizeEntry[static_cast<int>(eSize)].aImage = rImage;
359}
360
362{
363 aSizeEntry[static_cast<int>(eSize)].aURL = rURL;
364}
365
366// constructor
367
369 // Init baseclasses first
370 : ConfigItem( ROOTNODE_ADDONMENU ),
374{
375 // initialize array with fixed property names
382 m_aPropNames[ INDEX_CONTROLTYPE ] = "ControlType";
383 m_aPropNames[ INDEX_WIDTH ] = "Width";
384 m_aPropNames[ INDEX_ALIGN ] = "Alignment";
385 m_aPropNames[ INDEX_AUTOSIZE ] = "AutoSize";
386 m_aPropNames[ INDEX_OWNERDRAW ] = "OwnerDraw";
387 m_aPropNames[ INDEX_MANDATORY ] = "Mandatory";
388 m_aPropNames[ INDEX_STYLE ] = "Style";
389
390 // initialize array with fixed images property names
391 m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] = "ImageSmall";
393 m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] = "ImageSmallHC";
394 m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] = "ImageBigHC";
395 m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] = "ImageSmallURL";
396 m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] = "ImageBigURL";
397 m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL ] = "ImageSmallHCURL";
398 m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] = "ImageBigHCURL";
399
400 // initialize array with fixed merge menu property names
407
415
423
430
432
433 // Enable notification mechanism of our baseclass.
434 // We need it to get information about changes outside these class on our used configuration keys!
435 Sequence<OUString> aNotifySeq { "AddonUI" };
436 EnableNotification( aNotifySeq );
437}
438
439// destructor
440
442{
443 assert(!IsModified()); // should have been committed
444}
445
447{
448 // reset members to be read again from configuration
449 m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
450 m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
453 m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
457
462
465
470
475}
476
477// public method
478
479void AddonsOptions_Impl::Notify( const Sequence< OUString >& /*lPropertyNames*/ )
480{
482}
483
484// public method
485
487{
488 SAL_WARN("fwk", "AddonsOptions_Impl::ImplCommit(): Not implemented yet!");
489}
490
491// public method
492
494{
495 return m_aCachedMenuProperties.hasElements();
496}
497
498// public method
499
501{
502 return m_aCachedToolBarPartProperties.size();
503}
504
505// public method
506
508{
510}
511
512// public method
513
514const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
515{
516 if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
518 else
520}
521
522// public method
523
524const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsNotebookBarPart( sal_uInt32 nIndex ) const
525{
526 if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedNotebookBarPartProperties.size() )
528 else
530}
531
532// public method
533
534OUString AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
535{
538 else
539 return OUString();
540}
541
542// public method
543
545{
548 else
549 return OUString();
550}
551
552// public method
553
555 const OUString& rToolbarName,
556 MergeToolbarInstructionContainer& rToolbarInstructions ) const
557{
558 ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
559 if ( pIter != m_aCachedToolbarMergingInstructions.end() )
560 {
561 rToolbarInstructions = pIter->second;
562 return true;
563 }
564 else
565 return false;
566}
567
568// public method
569
571 const OUString& rNotebookBarName,
572 MergeNotebookBarInstructionContainer& rNotebookBarInstructions ) const
573{
574 NotebookBarMergingInstructions::const_iterator pIter = m_aCachedNotebookBarMergingInstructions.find( rNotebookBarName );
575 if ( pIter != m_aCachedNotebookBarMergingInstructions.end() )
576 {
577 rNotebookBarInstructions = pIter->second;
578 return true;
579 }
580 else
581 return false;
582}
583
584// public method
585
586static BitmapEx ScaleImage( const BitmapEx &rImage, bool bBig )
587{
588 Size aSize = ToolBox::GetDefaultImageSize(bBig ? ToolBoxButtonSize::Large : ToolBoxButtonSize::Small);
589 BitmapEx aScaleBmp(rImage);
590 SAL_INFO("fwk", "Addons: expensive scale image from "
591 << aScaleBmp.GetSizePixel() << " to " << aSize);
592 aScaleBmp.Scale(aSize, BmpScaleFlag::BestQuality);
593 return aScaleBmp;
594}
595
596BitmapEx AddonsOptions_Impl::GetImageFromURL( const OUString& aURL, bool bBig, bool bNoScale )
597{
598 BitmapEx aImage;
599
600 SAL_INFO("fwk", "Expensive: Addons GetImageFromURL " << aURL <<
601 " big " << (bBig?"big":"little") <<
602 " scale " << (bNoScale ? "noscale" : "scale"));
603
604 ImageManager::iterator pIter = m_aImageManager.find(aURL);
605 if ( pIter != m_aImageManager.end() )
606 {
607 ImageSize eSize = bBig ? IMGSIZE_BIG : IMGSIZE_SMALL;
608 int nIdx = static_cast<int>(eSize);
609 int nOtherIdx = nIdx ? 0 : 1;
610
611 OneImageEntry& rSizeEntry = pIter->second.aSizeEntry[nIdx];
612 OneImageEntry& rOtherEntry = pIter->second.aSizeEntry[nOtherIdx];
613 // actually read the image ...
614 if (rSizeEntry.aImage.IsEmpty())
615 rSizeEntry.aImage = ReadImageFromURL(rSizeEntry.aURL);
616
617 if (rSizeEntry.aImage.IsEmpty())
618 { // try the other size and scale it
619 aImage = ScaleImage(ReadImageFromURL(rOtherEntry.aURL), bBig);
620 rSizeEntry.aImage = aImage;
621 if (rSizeEntry.aImage.IsEmpty())
622 SAL_WARN("fwk", "failed to load addons image " << aURL);
623 }
624
625 // FIXME: bNoScale is not terribly meaningful or useful
626
627 if (aImage.IsEmpty() && bNoScale)
628 aImage = rSizeEntry.aImage;
629
630 if (aImage.IsEmpty() && !rSizeEntry.aScaled.IsEmpty())
631 aImage = rSizeEntry.aScaled;
632
633 else // scale to the correct size for the theme / toolbox
634 {
635 aImage = rSizeEntry.aImage;
636 if (aImage.IsEmpty()) // use and scale the other if one size is missing
637 aImage = rOtherEntry.aImage;
638
639 aImage = ScaleImage(aImage, bBig);
640 rSizeEntry.aScaled = aImage; // cache for next time
641 }
642 }
643
644 return aImage;
645}
646
647void AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
648{
649 // Read the AddonMenu set and fill property sequences
650 OUString aAddonMenuNodeName( "AddonUI/AddonMenu" );
651 Sequence< OUString > aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
652 OUString aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
653
654 sal_uInt32 nCount = aAddonMenuNodeSeq.getLength();
655 sal_uInt32 nIndex = 0;
656 Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
657 auto pMenuItem = aMenuItem.getArray();
658 // Init the property value sequence
659 pMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
660 pMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
661 pMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
664 pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
665
666 for ( sal_uInt32 n = 0; n < nCount; n++ )
667 {
668 OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
669
670 // Read the MenuItem
671 if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
672 {
673 // Successfully read a menu item, append to our list
674 sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
675 rAddonMenuSeq.realloc( nMenuItemCount );
676 rAddonMenuSeq.getArray()[nIndex++] = aMenuItem;
677 }
678 }
679}
680
681void AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
682{
683 // Read the AddonMenu set and fill property sequences
684 OUString aAddonHelpMenuNodeName( "AddonUI/OfficeHelp" );
685 Sequence< OUString > aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
686 OUString aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
687
688 sal_uInt32 nCount = aAddonHelpMenuNodeSeq.getLength();
689 sal_uInt32 nIndex = 0;
690 Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
691 auto pMenuItem = aMenuItem.getArray();
692 // Init the property value sequence
693 pMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
694 pMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
695 pMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
698 pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
699
700 for ( sal_uInt32 n = 0; n < nCount; n++ )
701 {
702 OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
703
704 // Read the MenuItem
705 if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, true ) )
706 {
707 // Successfully read a menu item, append to our list
708 sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
709 rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
710 rAddonOfficeHelpMenuSeq.getArray()[nIndex++] = aMenuItem;
711 }
712 }
713}
714
715void AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
716{
717 // Read the OfficeMenuBar set and fill property sequences
718 OUString aAddonMenuBarNodeName( "AddonUI/OfficeMenuBar" );
719 Sequence< OUString > aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
720 OUString aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
721
722 sal_uInt32 nCount = aAddonMenuBarNodeSeq.getLength();
723 sal_uInt32 nIndex = 0;
724 Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
725 auto pPopupMenu = aPopupMenu.getArray();
726 // Init the property value sequence
727 pPopupMenu[ OFFSET_POPUPMENU_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
730 pPopupMenu[ OFFSET_POPUPMENU_URL ].Name = m_aPropNames[ INDEX_URL ];
731
732 StringToIndexMap aTitleToIndexMap;
733 auto pAddonOfficeMenuBarSeq = rAddonOfficeMenuBarSeq.getArray();
734 for ( sal_uInt32 n = 0; n < nCount; n++ )
735 {
736 OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
737
738 // Read the MenuItem
739 if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
740 {
741 // Successfully read a popup menu, append to our list
742 OUString aPopupTitle;
743 if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
744 {
745 StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
746 if ( pIter != aTitleToIndexMap.end() )
747 {
748 // title already there => concat both popup menus
749 Sequence< PropertyValue >& rOldPopupMenu = pAddonOfficeMenuBarSeq[pIter->second];
750 AppendPopupMenu( rOldPopupMenu, aPopupMenu );
751 }
752 else
753 {
754 // not found
755 sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
756 rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
757 pAddonOfficeMenuBarSeq = rAddonOfficeMenuBarSeq.getArray();
758 pAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
759 aTitleToIndexMap.emplace( aPopupTitle, nIndex );
760 ++nIndex;
761 }
762 }
763 }
764 }
765}
766
767void AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< OUString >& rAddonOfficeToolBarResNames )
768{
769 // Read the OfficeToolBar set and fill property sequences
770 OUString aAddonToolBarNodeName( "AddonUI/OfficeToolBar" );
771 Sequence< OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
772 OUString aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
773
774 sal_uInt32 nCount = aAddonToolBarNodeSeq.getLength();
775
776 for ( sal_uInt32 n = 0; n < nCount; n++ )
777 {
778 OUString aToolBarItemNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] );
779 rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
780 rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
781 ReadToolBarItemSet( aToolBarItemNode, rAddonOfficeToolBars[n] );
782 }
783}
784
785bool AddonsOptions_Impl::ReadToolBarItemSet( const OUString& rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
786{
787 sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
788 OUString aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
789 Sequence< OUString > aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
790 Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
791 auto pToolBarItem = aToolBarItem.getArray();
792 // Init the property value sequence
793 pToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
794 pToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
796 pToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
797 pToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
799 pToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
800
801 sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
802 for ( sal_uInt32 n = 0; n < nCount; n++ )
803 {
804 OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
805
806 // Read the ToolBarItem
807 if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
808 {
809 // Successfully read a toolbar item, append to our list
810 sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
811 rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
812 rAddonOfficeToolBarSeq.getArray()[nAddonCount] = aToolBarItem;
813 }
814 }
815
816 return ( o3tl::make_unsigned(rAddonOfficeToolBarSeq.getLength()) > nToolBarItemCount );
817}
818
820 AddonNotebookBars& rAddonOfficeNotebookBars,
821 std::vector<OUString>& rAddonOfficeNotebookBarResNames)
822{
823 // Read the OfficeToolBar set and fill property sequences
824 OUString aAddonNotebookBarNodeName("AddonUI/OfficeNotebookBar");
825 Sequence<OUString> aAddonNotebookBarNodeSeq = GetNodeNames(aAddonNotebookBarNodeName);
826 OUString aAddonNotebookBarNode(aAddonNotebookBarNodeName + m_aPathDelimiter);
827
828 sal_uInt32 nCount = aAddonNotebookBarNodeSeq.getLength();
829
830 for (sal_uInt32 n = 0; n < nCount; n++)
831 {
832 OUString aNotebookBarItemNode(aAddonNotebookBarNode + aAddonNotebookBarNodeSeq[n]);
833 rAddonOfficeNotebookBarResNames.push_back(aAddonNotebookBarNodeSeq[n]);
834 rAddonOfficeNotebookBars.push_back(m_aEmptyAddonNotebookBar);
835 ReadNotebookBarItemSet(aNotebookBarItemNode, rAddonOfficeNotebookBars[n]);
836 }
837}
838
840 const OUString& rNotebookBarItemSetNodeName,
841 Sequence<Sequence<PropertyValue>>& rAddonOfficeNotebookBarSeq)
842{
843 sal_uInt32 nNotebookBarItemCount = rAddonOfficeNotebookBarSeq.getLength();
844 OUString aAddonNotebookBarItemSetNode(rNotebookBarItemSetNodeName + m_aPathDelimiter);
845 Sequence<OUString> aAddonNotebookBarItemSetNodeSeq = GetNodeNames(rNotebookBarItemSetNodeName);
846 Sequence<PropertyValue> aNotebookBarItem(PROPERTYCOUNT_NOTEBOOKBARITEM);
847 auto pNotebookBarItem = aNotebookBarItem.getArray();
848 // Init the property value sequence
849 pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_URL].Name = m_aPropNames[INDEX_URL];
850 pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_TITLE].Name = m_aPropNames[INDEX_TITLE];
851 pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER].Name
856 pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_WIDTH].Name = m_aPropNames[INDEX_WIDTH];
857 pNotebookBarItem[OFFSET_NOTEBOOKBARITEM_STYLE].Name = m_aPropNames[INDEX_STYLE];
858
859 sal_uInt32 nCount = aAddonNotebookBarItemSetNodeSeq.getLength();
860 for (sal_uInt32 n = 0; n < nCount; n++)
861 {
862 OUString aNotebookBarItemNode(aAddonNotebookBarItemSetNode
863 + aAddonNotebookBarItemSetNodeSeq[n]);
864 // Read the NotebookBarItem
865 if (ReadNotebookBarItem(aNotebookBarItemNode, aNotebookBarItem))
866 {
867 // Successfully read a toolbar item, append to our list
868 sal_uInt32 nAddonCount = rAddonOfficeNotebookBarSeq.getLength();
869 rAddonOfficeNotebookBarSeq.realloc(nAddonCount + 1);
870 rAddonOfficeNotebookBarSeq.getArray()[nAddonCount] = aNotebookBarItem;
871 }
872 }
873
874 return (o3tl::make_unsigned(rAddonOfficeNotebookBarSeq.getLength())
875 > nNotebookBarItemCount);
876}
877
879{
880 // Read the user-defined Images set and fill image manager
881 OUString aAddonImagesNodeName( "AddonUI/Images" );
882 Sequence< OUString > aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
883 OUString aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
884
885 sal_uInt32 nCount = aAddonImagesNodeSeq.getLength();
886
887 // Init the property value sequence
888 OUString aURL;
889
890 for ( sal_uInt32 n = 0; n < nCount; n++ )
891 {
892 OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
893
894 // Create sequence for data access
895 Sequence< OUString > aAddonImageItemNodePropNames = { aImagesItemNode +
898
899 Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
900
901 // An user-defined image entry must have a URL. As "ImageIdentifier" has a higher priority
902 // we also check if we already have an images association.
903 if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
904 !aURL.isEmpty() &&
906 {
907 OUString aImagesUserDefinedItemNode = aImagesItemNode +
911
912 // Read a user-defined images data
913 std::unique_ptr<ImageEntry> pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
914 if ( pImageEntry )
915 {
916 // Successfully read a user-defined images item, put it into our image manager
917 aImageManager.emplace( aURL, std::move(*pImageEntry) );
918 }
919 }
920 }
921}
922
924{
925 // Create a unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
926 return m_aRootAddonPopupMenuURLPrexfix + OUString::number( ++m_nRootAddonPopupMenuId );
927}
928
930{
931 static constexpr OUStringLiteral aMenuMergeRootName( u"AddonUI/OfficeMenuBarMerging/" );
932
933 Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
934
935 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
936
937 // Init the property value sequence
938 Sequence< OUString > aNodePropNames( 5 );
939 auto pNodePropNames = aNodePropNames.getArray();
940
941 for ( sal_uInt32 i = 0; i < nCount; i++ )
942 {
943 OUString aMergeAddonInstructions( aMenuMergeRootName + aAddonMergeNodesSeq[i] );
944
945 Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
946 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
947
948 for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
949 {
950 OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
952 aAddonInstMergeNodesSeq[j] +
954
955 // Create sequence for data access
956 pNodePropNames[0] = aMergeAddonInstructionBase +
958
959 pNodePropNames[1] = aMergeAddonInstructionBase +
961
962 pNodePropNames[2] = aMergeAddonInstructionBase +
964
965 pNodePropNames[3] = aMergeAddonInstructionBase +
967
968 pNodePropNames[4] = aMergeAddonInstructionBase +
970
971 Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
972
973 MergeMenuInstruction aMergeMenuInstruction;
974 aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
975 aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
976 aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
977 aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
978 aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
979
980 ReadMergeMenuData( aMergeAddonInstructionBase, aMergeMenuInstruction.aMergeMenu );
981
982 aContainer.push_back( aMergeMenuInstruction );
983 }
984 }
985}
986
987void AddonsOptions_Impl::ReadMergeMenuData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
988{
989 OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
990
991 Sequence< OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
992 aMergeMenuBaseNode += m_aPathDelimiter;
993
994 // extend the node names to have full path strings
995 for ( OUString& rName : asNonConstRange(aSubMenuNodeNames) )
996 rName = aMergeMenuBaseNode + rName;
997
998 ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
999}
1000
1002{
1003 static constexpr OUStringLiteral aToolbarMergeRootName( u"AddonUI/OfficeToolbarMerging/" );
1004
1005 Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
1006 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
1007
1008 // Init the property value sequence
1009 Sequence< OUString > aNodePropNames( 6 );
1010 auto pNodePropNames = aNodePropNames.getArray();
1011
1012 for ( sal_uInt32 i = 0; i < nCount; i++ )
1013 {
1014 OUString aMergeAddonInstructions( aToolbarMergeRootName + aAddonMergeNodesSeq[i] );
1015
1016 Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1017 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
1018
1019 for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1020 {
1021 OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
1023 aAddonInstMergeNodesSeq[j] +
1025
1026 // Create sequence for data access
1027 pNodePropNames[0] = aMergeAddonInstructionBase +
1029
1030 pNodePropNames[1] = aMergeAddonInstructionBase +
1032
1033 pNodePropNames[2] = aMergeAddonInstructionBase +
1035
1036 pNodePropNames[3] = aMergeAddonInstructionBase +
1038
1039 pNodePropNames[4] = aMergeAddonInstructionBase +
1041
1042 pNodePropNames[5] = aMergeAddonInstructionBase +
1044
1045 Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1046
1047 MergeToolbarInstruction aMergeToolbarInstruction;
1048 aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
1049 aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
1050 aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
1051 aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
1052 aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
1053 aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
1054
1055 ReadMergeToolbarData( aMergeAddonInstructionBase,
1056 aMergeToolbarInstruction.aMergeToolbarItems );
1057
1058 MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
1059 rVector.push_back( aMergeToolbarInstruction );
1060 }
1061 }
1062}
1063
1064void AddonsOptions_Impl::ReadMergeToolbarData( std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
1065{
1066 OUString aMergeToolbarBaseNode = aMergeAddonInstructionBase +
1068
1069 ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
1070}
1071
1073 NotebookBarMergingInstructions& rCachedNotebookBarMergingInstructions)
1074{
1075 static constexpr OUStringLiteral aNotebookBarMergeRootName(u"AddonUI/OfficeNotebookBarMerging/");
1076
1077 Sequence<OUString> aAddonMergeNodesSeq = GetNodeNames(aNotebookBarMergeRootName);
1078 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
1079
1080 // Init the property value sequence
1081 Sequence<OUString> aNodePropNames(6);
1082 auto pNodePropNames = aNodePropNames.getArray();
1083
1084 for (sal_uInt32 i = 0; i < nCount; i++)
1085 {
1086 OUString aMergeAddonInstructions(aNotebookBarMergeRootName + aAddonMergeNodesSeq[i]);
1087
1088 Sequence<OUString> aAddonInstMergeNodesSeq = GetNodeNames(aMergeAddonInstructions);
1089 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
1090
1091 for (sal_uInt32 j = 0; j < nCountAddons; j++)
1092 {
1093 OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
1095 aAddonInstMergeNodesSeq[j] +
1097
1098 // Create sequence for data access
1099 pNodePropNames[0] = aMergeAddonInstructionBase +
1101
1102 pNodePropNames[1] = aMergeAddonInstructionBase +
1104
1105 pNodePropNames[2] = aMergeAddonInstructionBase +
1107
1108 pNodePropNames[3] = aMergeAddonInstructionBase +
1110
1111 pNodePropNames[4] = aMergeAddonInstructionBase +
1113
1114 pNodePropNames[5] = aMergeAddonInstructionBase +
1116
1117 Sequence<Any> aNodePropValues = GetProperties(aNodePropNames);
1118
1119 MergeNotebookBarInstruction aMergeNotebookBarInstruction;
1120 aNodePropValues[0] >>= aMergeNotebookBarInstruction.aMergeNotebookBar;
1121 aNodePropValues[1] >>= aMergeNotebookBarInstruction.aMergePoint;
1122 aNodePropValues[2] >>= aMergeNotebookBarInstruction.aMergeCommand;
1123 aNodePropValues[3] >>= aMergeNotebookBarInstruction.aMergeCommandParameter;
1124 aNodePropValues[4] >>= aMergeNotebookBarInstruction.aMergeFallback;
1125 aNodePropValues[5] >>= aMergeNotebookBarInstruction.aMergeContext;
1126
1127 ReadMergeNotebookBarData(aMergeAddonInstructionBase,
1128 aMergeNotebookBarInstruction.aMergeNotebookBarItems);
1129
1131 = rCachedNotebookBarMergingInstructions[aMergeNotebookBarInstruction
1133 rVector.push_back(aMergeNotebookBarInstruction);
1134 }
1135 }
1136}
1137
1139 std::u16string_view aMergeAddonInstructionBase,
1140 Sequence<Sequence<PropertyValue>>& rMergeNotebookBarItems)
1141{
1142 OUString aMergeNotebookBarBaseNode = aMergeAddonInstructionBase +
1144
1145 ReadNotebookBarItemSet(aMergeNotebookBarBaseNode, rMergeNotebookBarItems);
1146}
1147
1149{
1150 static constexpr OUStringLiteral aStatusbarMergeRootName( u"AddonUI/OfficeStatusbarMerging/" );
1151
1152 Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aStatusbarMergeRootName );
1153 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
1154
1155 Sequence< OUString > aNodePropNames( 5 );
1156 auto pNodePropNames = aNodePropNames.getArray();
1157
1158 for ( sal_uInt32 i = 0; i < nCount; i++ )
1159 {
1160 OUString aMergeAddonInstructions( aStatusbarMergeRootName + aAddonMergeNodesSeq[i] );
1161
1162 Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1163 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
1164
1165 for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1166 {
1167 OUString aMergeAddonInstructionBase = aMergeAddonInstructions +
1169 aAddonInstMergeNodesSeq[j] +
1171
1172 // Create sequence for data access
1173 pNodePropNames[0] = aMergeAddonInstructionBase +
1175
1176 pNodePropNames[1] = aMergeAddonInstructionBase +
1178
1179 pNodePropNames[2] = aMergeAddonInstructionBase +
1181
1182 pNodePropNames[3] = aMergeAddonInstructionBase +
1184
1185 pNodePropNames[4] = aMergeAddonInstructionBase +
1187
1188 Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1189
1190 MergeStatusbarInstruction aMergeStatusbarInstruction;
1191 aNodePropValues[0] >>= aMergeStatusbarInstruction.aMergePoint;
1192 aNodePropValues[1] >>= aMergeStatusbarInstruction.aMergeCommand;
1193 aNodePropValues[2] >>= aMergeStatusbarInstruction.aMergeCommandParameter;
1194 // aNodePropValues[3] >>= aMergeStatusbarInstruction.aMergeFallback;
1195 aNodePropValues[4] >>= aMergeStatusbarInstruction.aMergeContext;
1196
1197 ReadMergeStatusbarData( aMergeAddonInstructionBase,
1198 aMergeStatusbarInstruction.aMergeStatusbarItems );
1199
1200 aContainer.push_back( aMergeStatusbarInstruction );
1201 }
1202 }
1203}
1204
1206 std::u16string_view aMergeAddonInstructionBase,
1207 Sequence< Sequence< PropertyValue > >& rMergeStatusbarItems )
1208{
1209 OUString aMergeStatusbarBaseNode = aMergeAddonInstructionBase +
1211
1212 OUString aAddonStatusbarItemSetNode( aMergeStatusbarBaseNode + m_aPathDelimiter );
1213 Sequence< OUString > aAddonStatusbarItemSetNodeSeq = GetNodeNames( aMergeStatusbarBaseNode );
1214
1215 Sequence< PropertyValue > aStatusbarItem( PROPERTYCOUNT_STATUSBARITEM );
1216 auto pStatusbarItem = aStatusbarItem.getArray();
1217 pStatusbarItem[ OFFSET_STATUSBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
1218 pStatusbarItem[ OFFSET_STATUSBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
1219 pStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
1220 pStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN ].Name = m_aPropNames[ INDEX_ALIGN ];
1221 pStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE ].Name = m_aPropNames[ INDEX_AUTOSIZE ];
1224 pStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
1225
1226 sal_uInt32 nCount = aAddonStatusbarItemSetNodeSeq.getLength();
1227 for ( sal_uInt32 n = 0; n < nCount; n++ )
1228 {
1229 OUString aStatusbarItemNode( aAddonStatusbarItemSetNode + aAddonStatusbarItemSetNodeSeq[n] );
1230
1231 if ( ReadStatusBarItem( aStatusbarItemNode, aStatusbarItem ) )
1232 {
1233 sal_uInt32 nAddonCount = rMergeStatusbarItems.getLength();
1234 rMergeStatusbarItems.realloc( nAddonCount+1 );
1235 rMergeStatusbarItems.getArray()[nAddonCount] = aStatusbarItem;
1236 }
1237 }
1238}
1239
1241 std::u16string_view aStatusarItemNodeName,
1242 Sequence< PropertyValue >& aStatusbarItem )
1243{
1244 bool bResult( false );
1245 OUString aURL;
1246 OUString aAddonStatusbarItemTreeNode( aStatusarItemNodeName + m_aPathDelimiter );
1247
1248 Sequence< Any > aStatusbarItemNodePropValues = GetProperties( GetPropertyNamesStatusbarItem( aAddonStatusbarItemTreeNode ) );
1249
1250 // Command URL is required
1251 if (( aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
1252 {
1253 auto pStatusbarItem = aStatusbarItem.getArray();
1254 pStatusbarItem[ OFFSET_STATUSBARITEM_URL ].Value <<= aURL;
1255 pStatusbarItem[ OFFSET_STATUSBARITEM_TITLE ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_TITLE ];
1256 pStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_CONTEXT ];
1257 pStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_ALIGN ];
1258 pStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_AUTOSIZE ];
1259 pStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_OWNERDRAW ];
1260 pStatusbarItem[ OFFSET_STATUSBARITEM_MANDATORY ].Value = aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_MANDATORY ];
1261
1262 // Configuration uses hyper for long. Therefore transform into sal_Int32
1263 sal_Int64 nValue( 0 );
1264 aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_WIDTH ] >>= nValue;
1265 pStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
1266
1267 bResult = true;
1268 }
1269
1270 return bResult;
1271}
1272
1273bool AddonsOptions_Impl::ReadMenuItem( std::u16string_view aMenuNodeName, Sequence< PropertyValue >& aMenuItem, bool bIgnoreSubMenu )
1274{
1275 bool bResult = false;
1276 OUString aStrValue;
1277 OUString aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
1278
1279 Sequence< Any > aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
1280 if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && !aStrValue.isEmpty() )
1281 {
1282 auto pMenuItem = aMenuItem.getArray();
1283 pMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
1284
1285 OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
1286 Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
1287 if ( aRootSubMenuNodeNames.hasElements() && !bIgnoreSubMenu )
1288 {
1289 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1290 OUString aPopupMenuURL = GeneratePrefixURL();
1291 OUString aPopupMenuImageId;
1292
1293 aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
1294 ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
1295
1296 // A popup menu must have a title and can have a URL and ImageIdentifier
1297 // Set the other property values to empty
1298 pMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aPopupMenuURL;
1299 pMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= OUString();
1300 pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aPopupMenuImageId;
1301 pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value = aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
1302
1303 // Continue to read the sub menu nodes
1304 Sequence< Sequence< PropertyValue > > aSubMenuSeq;
1305 OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
1306 for ( OUString& rName : asNonConstRange(aRootSubMenuNodeNames) )
1307 rName = aSubMenuRootNodeName + rName;
1308 ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
1309 pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
1310 bResult = true;
1311 }
1312 else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && !aStrValue.isEmpty() )
1313 {
1314 // A simple menu item => read the other properties;
1315 OUString aMenuImageId;
1316
1317 aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
1318 ReadAndAssociateImages( aStrValue, aMenuImageId );
1319
1320 pMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
1321 pMenuItem[ OFFSET_MENUITEM_TARGET ].Value = aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET ];
1322 pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aMenuImageId;
1323 pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value = aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
1324 pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
1325
1326 bResult = true;
1327 }
1328 }
1329 else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
1330 aStrValue == SEPARATOR_URL )
1331 {
1332 auto pMenuItem = aMenuItem.getArray();
1333
1334 // Separator
1335 pMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
1336 pMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= OUString();
1337 pMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= OUString();
1338 pMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= OUString();
1339 pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
1340 bResult = true;
1341 }
1342
1343 return bResult;
1344}
1345
1346bool AddonsOptions_Impl::ReadPopupMenu( std::u16string_view aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
1347{
1348 bool bResult = false;
1349 OUString aStrValue;
1350 OUString aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
1351
1352 Sequence< Any > aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
1353 if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
1354 !aStrValue.isEmpty() )
1355 {
1356 auto pPopupMenu = aPopupMenu.getArray();
1357 pPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
1358
1359 OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
1360 Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
1361 if ( aRootSubMenuNodeNames.hasElements() )
1362 {
1363 // A top-level popup menu needs a title
1364 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1365 OUString aPopupMenuURL = GeneratePrefixURL();
1366
1367 pPopupMenu[ OFFSET_POPUPMENU_URL ].Value <<= aPopupMenuURL;
1368 pPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Value = aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
1369
1370 // Continue to read the sub menu nodes
1371 Sequence< Sequence< PropertyValue > > aSubMenuSeq;
1372 OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
1373 for ( OUString& rName : asNonConstRange(aRootSubMenuNodeNames) )
1374 rName = aSubMenuRootNodeName + rName;
1375 ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
1376 pPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
1377 bResult = true;
1378 }
1379 }
1380
1381 return bResult;
1382}
1383
1384void AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
1385{
1386 Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
1387 Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
1388
1389 if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
1390 ( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
1391 {
1392 sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
1393 aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
1394 auto pTargetSubMenuSeq = aTargetSubMenuSeq.getArray();
1395 for ( Sequence<PropertyValue> const & rSeq : std::as_const(aSourceSubMenuSeq) )
1396 pTargetSubMenuSeq[nIndex++] = rSeq;
1397 rTargetPopupMenu.getArray()[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
1398 }
1399}
1400
1401bool AddonsOptions_Impl::ReadToolBarItem( std::u16string_view aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
1402{
1403 bool bResult = false;
1404 OUString aURL;
1405 OUString aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
1406
1407 Sequence< Any > aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
1408
1409 // A toolbar item must have a command URL
1410 if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && !aURL.isEmpty() )
1411 {
1412 OUString aTitle;
1413 if ( aURL == SEPARATOR_URL )
1414 {
1415 auto pToolBarItem = aToolBarItem.getArray();
1416
1417 // A separator toolbar item only needs a URL
1418 pToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
1419 pToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= OUString();
1420 pToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= OUString();
1421 pToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= OUString();
1422 pToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= OUString();
1423 pToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= OUString();
1424 pToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
1425
1426 bResult = true;
1427 }
1428 else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE ] >>= aTitle ) && !aTitle.isEmpty() )
1429 {
1430 auto pToolBarItem = aToolBarItem.getArray();
1431
1432 // A normal toolbar item must also have title => read the other properties;
1433 OUString aImageId;
1434
1435 // Try to map a user-defined image URL to our internal private image URL
1436 aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
1437 ReadAndAssociateImages( aURL, aImageId );
1438
1439 pToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
1440 pToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= aTitle;
1441 pToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value = aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET ];
1442 pToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
1443 pToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value = aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT ];
1444 pToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value = aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
1445
1446 // Configuration uses hyper for long. Therefore transform into sal_Int32
1447 sal_Int64 nValue( 0 );
1448 aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
1449 pToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
1450
1451 bResult = true;
1452 }
1453 }
1454
1455 return bResult;
1456}
1457
1458bool AddonsOptions_Impl::ReadNotebookBarItem( std::u16string_view aNotebookBarItemNodeName, Sequence< PropertyValue >& aNotebookBarItem )
1459{
1460 bool bResult = false;
1461 OUString aURL;
1462 OUString aAddonNotebookBarItemTreeNode( aNotebookBarItemNodeName + m_aPathDelimiter );
1463
1464 Sequence< Any > aNotebookBarItemNodePropValues = GetProperties( GetPropertyNamesNotebookBarItem( aAddonNotebookBarItemTreeNode ) );
1465
1466 // A toolbar item must have a command URL
1467 if (( aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_URL ] >>= aURL ) && !aURL.isEmpty() )
1468 {
1469 OUString aTitle;
1470 if ( aURL == SEPARATOR_URL )
1471 {
1472 auto pNotebookBarItem = aNotebookBarItem.getArray();
1473
1474 // A separator toolbar item only needs a URL
1475 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_URL ].Value <<= aURL;
1476 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TITLE ].Value <<= OUString();
1477 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TARGET ].Value <<= OUString();
1478 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER ].Value <<= OUString();
1479 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTEXT ].Value <<= OUString();
1480 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE ].Value <<= OUString();
1481 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
1482 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_STYLE ].Value <<= OUString();
1483
1484 bResult = true;
1485 }
1486 else if (( aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_TITLE ] >>= aTitle ) && !aTitle.isEmpty() )
1487 {
1488 auto pNotebookBarItem = aNotebookBarItem.getArray();
1489
1490 // A normal toolbar item must also have title => read the other properties;
1491 OUString aImageId;
1492
1493 // Try to map a user-defined image URL to our internal private image URL
1494 aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
1495 ReadAndAssociateImages( aURL, aImageId );
1496
1497 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_URL ].Value <<= aURL;
1498 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TITLE ].Value <<= aTitle;
1499 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_TARGET ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_TARGET ];
1500 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
1501 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTEXT ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_CONTEXT ];
1502 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE ];
1503
1504 // Configuration uses hyper for long. Therefore transform into sal_Int32
1505 sal_Int64 nValue( 0 );
1506 aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_WIDTH ] >>= nValue;
1507 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
1508 pNotebookBarItem[ OFFSET_NOTEBOOKBARITEM_STYLE ].Value = aNotebookBarItemNodePropValues[ OFFSET_NOTEBOOKBARITEM_STYLE ];
1509
1510 bResult = true;
1511 }
1512 }
1513
1514 return bResult;
1515}
1516
1517void AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
1518{
1519 Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
1520 auto pMenuItem = aMenuItem.getArray();
1521
1522 // Init the property value sequence
1523 pMenuItem[ OFFSET_MENUITEM_URL ].Name = PROPERTYNAME_URL;
1524 pMenuItem[ OFFSET_MENUITEM_TITLE ].Name = PROPERTYNAME_TITLE;
1525 pMenuItem[ OFFSET_MENUITEM_TARGET ].Name = PROPERTYNAME_TARGET;
1528 pMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = PROPERTYNAME_SUBMENU; // Submenu set!
1529
1530 sal_uInt32 nIndex = 0;
1531 sal_uInt32 nCount = aSubMenuNodeNames.getLength();
1532 for ( sal_uInt32 n = 0; n < nCount; n++ )
1533 {
1534 if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
1535 {
1536 sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
1537 rSubMenuSeq.realloc( nSubMenuCount );
1538 rSubMenuSeq.getArray()[nIndex++] = aMenuItem;
1539 }
1540 }
1541}
1542
1544{
1545 // FIXME: potentially this is not so useful in a world of delayed image loading
1546 ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
1547 return ( pIter != m_aImageManager.end() );
1548}
1549
1551{
1554}
1555
1557{
1558 BitmapEx aImage;
1559
1560 std::unique_ptr<SvStream> pStream = UcbStreamHelper::CreateStream( aImageURL, StreamMode::STD_READ );
1561 if ( pStream && ( pStream->GetErrorCode() == ERRCODE_NONE ))
1562 {
1563 // Use graphic class to also support more graphic formats (bmp,png,...)
1564 Graphic aGraphic;
1565
1567 rGF.ImportGraphic( aGraphic, u"", *pStream );
1568
1569 BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
1570
1571 Size aBmpSize = aBitmapEx.GetSizePixel();
1572 if ( !aBmpSize.IsEmpty() )
1573 {
1574 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1575 if( !aBitmapEx.IsAlpha() )
1576 aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
1577
1578 aImage = aBitmapEx;
1579 }
1580 }
1581
1582 return aImage;
1583}
1584
1585void AddonsOptions_Impl::ReadAndAssociateImages( const OUString& aURL, const OUString& aImageId )
1586{
1587 if ( aImageId.isEmpty() )
1588 return;
1589
1590 ImageEntry aImageEntry;
1591 OUString aImageURL( aImageId );
1592
1593 SubstituteVariables( aImageURL );
1594
1595 // Loop to create the two possible image names and try to read the bitmap files
1596 static const char* aExtArray[] = { "_16", "_26" };
1597 for ( size_t i = 0; i < SAL_N_ELEMENTS(aExtArray); i++ )
1598 {
1599 OUStringBuffer aFileURL( aImageURL );
1600 aFileURL.appendAscii( aExtArray[i] );
1601 aFileURL.append( ".bmp" );
1602
1603 aImageEntry.addImage( !i ? IMGSIZE_SMALL : IMGSIZE_BIG, aFileURL.makeStringAndClear() );
1604 }
1605
1606 m_aImageManager.emplace( aURL, aImageEntry );
1607}
1608
1609std::unique_ptr<AddonsOptions_Impl::ImageEntry> AddonsOptions_Impl::ReadImageData( std::u16string_view aImagesNodeName )
1610{
1611 Sequence< OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
1612 Sequence< Any > aPropertyData;
1613 Sequence< sal_Int8 > aImageDataSeq;
1614 OUString aImageURL;
1615
1616 std::unique_ptr<ImageEntry> pEntry;
1617
1618 // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
1619 // same time. Embedded image data has a higher priority.
1620 aPropertyData = GetProperties( aImageDataNodeNames );
1621 for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
1622 {
1624 {
1625 // Extract image data from the embedded hex binary sequence
1626 BitmapEx aImage;
1627 if (( aPropertyData[i] >>= aImageDataSeq ) &&
1628 aImageDataSeq.hasElements() &&
1629 ( CreateImageFromSequence( aImage, aImageDataSeq ) ) )
1630 {
1631 if ( !pEntry )
1632 pEntry.reset(new ImageEntry);
1633 pEntry->addImage(i == OFFSET_IMAGES_SMALL ? IMGSIZE_SMALL : IMGSIZE_BIG, aImage);
1634 }
1635 }
1637 {
1638 if(!pEntry)
1639 pEntry.reset(new ImageEntry());
1640
1641 // Retrieve image data from an external bitmap file. Make sure that embedded image data
1642 // has a higher priority.
1643 if (aPropertyData[i] >>= aImageURL)
1644 {
1645 SubstituteVariables(aImageURL);
1646 pEntry->addImage(i == OFFSET_IMAGES_SMALL_URL ? IMGSIZE_SMALL : IMGSIZE_BIG, aImageURL);
1647 }
1648 }
1649 }
1650
1651 return pEntry;
1652}
1653
1654bool AddonsOptions_Impl::CreateImageFromSequence( BitmapEx& rImage, Sequence< sal_Int8 >& rBitmapDataSeq ) const
1655{
1656 bool bResult = false;
1657
1658 if ( rBitmapDataSeq.hasElements() )
1659 {
1660 SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), StreamMode::STD_READ );
1661
1662 ReadDIBBitmapEx(rImage, aMemStream);
1663
1664 if( !rImage.IsAlpha() )
1665 {
1666 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1667 rImage = BitmapEx( rImage.GetBitmap(), COL_LIGHTMAGENTA );
1668 }
1669
1670 bResult = true;
1671 }
1672
1673 return bResult;
1674}
1675
1676Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( std::u16string_view aPropertyRootNode ) const
1677{
1678 Sequence< OUString > lResult( PROPERTYCOUNT_MENUITEM );
1679 auto plResult = lResult.getArray();
1680
1681 // Create property names dependent from the root node name
1682 plResult[OFFSET_MENUITEM_URL] = aPropertyRootNode + m_aPropNames[ INDEX_URL ];
1683 plResult[OFFSET_MENUITEM_TITLE] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
1684 plResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ];
1685 plResult[OFFSET_MENUITEM_TARGET] = aPropertyRootNode + m_aPropNames[ INDEX_TARGET ];
1686 plResult[OFFSET_MENUITEM_CONTEXT] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
1687 plResult[OFFSET_MENUITEM_SUBMENU] = aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ];
1688
1689 return lResult;
1690}
1691
1692Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( std::u16string_view aPropertyRootNode ) const
1693{
1694 // The URL is automatically set and not read from the configuration.
1695 Sequence< OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
1696 auto plResult = lResult.getArray();
1697
1698 // Create property names dependent from the root node name
1699 plResult[OFFSET_POPUPMENU_TITLE] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
1700 plResult[OFFSET_POPUPMENU_CONTEXT] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
1701 plResult[OFFSET_POPUPMENU_SUBMENU] = aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ];
1702
1703 return lResult;
1704}
1705
1706Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( std::u16string_view aPropertyRootNode ) const
1707{
1708 Sequence< OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
1709 auto plResult = lResult.getArray();
1710
1711 // Create property names dependent from the root node name
1712 plResult[0] = aPropertyRootNode + m_aPropNames[ INDEX_URL ];
1713 plResult[1] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
1714 plResult[2] = aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER];
1715 plResult[3] = aPropertyRootNode + m_aPropNames[ INDEX_TARGET ];
1716 plResult[4] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
1717 plResult[5] = aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ];
1718 plResult[6] = aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ];
1719
1720 return lResult;
1721}
1722
1723Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesNotebookBarItem( std::u16string_view aPropertyRootNode ) const
1724{
1725 Sequence< OUString > lResult( PROPERTYCOUNT_NOTEBOOKBARITEM );
1726 auto plResult = lResult.getArray();
1727
1728 // Create property names dependent from the root node name
1729 plResult[0] = aPropertyRootNode + m_aPropNames[ INDEX_URL ];
1730 plResult[1] = aPropertyRootNode + m_aPropNames[ INDEX_TITLE ];
1731 plResult[2] = aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER];
1732 plResult[3] = aPropertyRootNode + m_aPropNames[ INDEX_TARGET ];
1733 plResult[4] = aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ];
1734 plResult[5] = aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ];
1735 plResult[6] = aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ];
1736 plResult[7] = aPropertyRootNode + m_aPropNames[ INDEX_STYLE ];
1737
1738 return lResult;
1739}
1740
1742 std::u16string_view aPropertyRootNode ) const
1743{
1744 Sequence< OUString > lResult( PROPERTYCOUNT_STATUSBARITEM );
1745 auto plResult = lResult.getArray();
1746
1747 plResult[0] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
1748 plResult[1] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
1749 plResult[2] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
1750 plResult[3] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_ALIGN ] );
1751 plResult[4] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_AUTOSIZE ] );
1752 plResult[5] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_OWNERDRAW ] );
1753 plResult[6] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_MANDATORY ] );
1754 plResult[7] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ] );
1755
1756 return lResult;
1757}
1758
1759Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesImages( std::u16string_view aPropertyRootNode ) const
1760{
1761 Sequence< OUString > lResult( PROPERTYCOUNT_IMAGES );
1762 auto plResult = lResult.getArray();
1763
1764 // Create property names dependent from the root node name
1765 plResult[0] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL ];
1766 plResult[1] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG ];
1767 plResult[2] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ];
1768 plResult[3] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ];
1769 plResult[4] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ];
1770 plResult[5] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ];
1771 plResult[6] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL];
1772 plResult[7] = aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ];
1773
1774 return lResult;
1775}
1776
1777namespace{
1778 //global
1779 std::weak_ptr<AddonsOptions_Impl> g_pAddonsOptions;
1780}
1781
1782AddonsOptions::AddonsOptions()
1783{
1784 // Global access, must be guarded (multithreading!).
1785 MutexGuard aGuard( GetOwnStaticMutex() );
1786
1787 m_pImpl = g_pAddonsOptions.lock();
1788 if( !m_pImpl )
1789 {
1790 m_pImpl = std::make_shared<AddonsOptions_Impl>();
1791 g_pAddonsOptions = m_pImpl;
1792 }
1793}
1794
1795AddonsOptions::~AddonsOptions()
1796{
1797 // Global access, must be guarded (multithreading!)
1798 MutexGuard aGuard( GetOwnStaticMutex() );
1799
1800 m_pImpl.reset();
1801}
1802
1803// public method
1804
1805bool AddonsOptions::HasAddonsMenu() const
1806{
1807 MutexGuard aGuard( GetOwnStaticMutex() );
1808 return m_pImpl->HasAddonsMenu();
1809}
1810
1811// public method
1812
1813sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
1814{
1815 MutexGuard aGuard( GetOwnStaticMutex() );
1816 return m_pImpl->GetAddonsToolBarCount();
1817}
1818
1819// public method
1820
1821sal_Int32 AddonsOptions::GetAddonsNotebookBarCount() const
1822{
1823 MutexGuard aGuard( GetOwnStaticMutex() );
1824 return m_pImpl->GetAddonsNotebookBarCount();
1825}
1826
1827// public method
1828
1829const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
1830{
1831 MutexGuard aGuard( GetOwnStaticMutex() );
1832 return m_pImpl->GetAddonsMenu();
1833}
1834
1835// public method
1836
1837const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
1838{
1839 MutexGuard aGuard( GetOwnStaticMutex() );
1840 return m_pImpl->GetAddonsMenuBarPart();
1841}
1842
1843// public method
1844
1845const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
1846{
1847 MutexGuard aGuard( GetOwnStaticMutex() );
1848 return m_pImpl->GetAddonsToolBarPart( nIndex );
1849}
1850
1851// public method
1852
1853const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsNotebookBarPart( sal_uInt32 nIndex ) const
1854{
1855 MutexGuard aGuard( GetOwnStaticMutex() );
1856 return m_pImpl->GetAddonsNotebookBarPart( nIndex );
1857}
1858
1859// public method
1860
1861OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
1862{
1863 MutexGuard aGuard( GetOwnStaticMutex() );
1864 return m_pImpl->GetAddonsToolbarResourceName( nIndex );
1865}
1866
1867// public method
1868
1869OUString AddonsOptions::GetAddonsNotebookBarResourceName( sal_uInt32 nIndex ) const
1870{
1871 MutexGuard aGuard( GetOwnStaticMutex() );
1872 return m_pImpl->GetAddonsNotebookBarResourceName( nIndex );
1873}
1874
1875// public method
1876
1877const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
1878{
1879 MutexGuard aGuard( GetOwnStaticMutex() );
1880 return m_pImpl->GetAddonsHelpMenu();
1881}
1882
1883// public method
1884
1885const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
1886{
1887 MutexGuard aGuard( GetOwnStaticMutex() );
1888 return m_pImpl->GetMergeMenuInstructions();
1889}
1890
1891// public method
1892
1893bool AddonsOptions::GetMergeToolbarInstructions(
1894 const OUString& rToolbarName,
1895 MergeToolbarInstructionContainer& rToolbarInstructions ) const
1896{
1897 MutexGuard aGuard( GetOwnStaticMutex() );
1898 return m_pImpl->GetMergeToolbarInstructions(
1899 rToolbarName, rToolbarInstructions );
1900}
1901
1902// public method
1903
1904bool AddonsOptions::GetMergeNotebookBarInstructions(
1905 const OUString& rNotebookBarName,
1906 MergeNotebookBarInstructionContainer& rNotebookBarInstructions ) const
1907{
1908 MutexGuard aGuard( GetOwnStaticMutex() );
1909 return m_pImpl->GetMergeNotebookBarInstructions(
1910 rNotebookBarName, rNotebookBarInstructions );
1911}
1912
1913//public method
1914
1915const MergeStatusbarInstructionContainer& AddonsOptions::GetMergeStatusbarInstructions() const
1916{
1917 MutexGuard aGuard( GetOwnStaticMutex() );
1918 return m_pImpl->GetMergeStatusbarInstructions();
1919}
1920
1921// public method
1922
1923BitmapEx AddonsOptions::GetImageFromURL( const OUString& aURL, bool bBig, bool bNoScale ) const
1924{
1925 MutexGuard aGuard( GetOwnStaticMutex() );
1926 return m_pImpl->GetImageFromURL( aURL, bBig, bNoScale );
1927}
1928
1929// public method
1930
1931BitmapEx AddonsOptions::GetImageFromURL( const OUString& aURL, bool bBig ) const
1932{
1933 return GetImageFromURL( aURL, bBig, false );
1934}
1935
1936Mutex& AddonsOptions::GetOwnStaticMutex()
1937{
1938 // Create static mutex variable.
1939 static Mutex ourMutex;
1940
1941 return ourMutex;
1942}
1943
1945{
1946 MutexGuard aGuard(AddonsOptions::GetOwnStaticMutex());
1947 ReadConfigurationData();
1948}
1949
1950}
1951
1952/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
#define PROPERTYNAME_URL
#define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
#define OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK
#define OFFSET_MENUITEM_TARGET
#define PROPERTYNAME_TITLE
#define INDEX_TITLE
#define INDEX_WIDTH
#define OFFSET_MERGETOOLBAR_TOOLBAR
#define OFFSET_MERGESTATUSBAR_MERGECONTEXT
#define OFFSET_MERGETOOLBAR_TOOLBARITEMS
constexpr OUStringLiteral SEPARATOR_URL
#define OFFSET_MERGEMENU_MERGEPOINT
#define OFFSET_MENUITEM_CONTEXT
#define OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND
#define OFFSET_IMAGES_BIG
#define INDEX_AUTOSIZE
#define OFFSET_STATUSBARITEM_OWNERDRAW
#define OFFSET_NOTEBOOKBARITEM_TARGET
#define INDEX_SUBMENU
#define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER
#define OFFSET_POPUPMENU_CONTEXT
#define OFFSET_MERGETOOLBAR_MERGECOMMAND
constexpr OUStringLiteral ROOTNODE_ADDONMENU
#define OFFSET_MERGETOOLBAR_MERGEPOINT
#define OFFSET_MERGETOOLBAR_MERGECONTEXT
#define OFFSET_MERGENOTEBOOKBAR_MERGEPOINT
#define OFFSET_TOOLBARITEM_CONTEXT
constexpr OUStringLiteral PATHDELIMITER
#define OFFSET_TOOLBARITEM_URL
#define OFFSET_STATUSBARITEM_AUTOSIZE
#define OFFSET_NOTEBOOKBARITEM_TITLE
#define INDEX_CONTROLTYPE
#define OFFSET_STATUSBARITEM_MANDATORY
#define OFFSET_IMAGES_BIG_URL
#define INDEX_STYLE
#define OFFSET_TOOLBARITEM_WIDTH
#define PROPERTYCOUNT_POPUPMENU
#define PROPERTYCOUNT_STATUSBARITEM
#define OFFSET_NOTEBOOKBARITEM_STYLE
#define PROPERTYCOUNT_MENUITEM
#define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER
#define OFFSET_POPUPMENU_URL
#define OFFSET_MERGESTATUSBAR_MERGEPOINT
#define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR
#define OFFSET_STATUSBARITEM_TITLE
#define OFFSET_NOTEBOOKBARITEM_WIDTH
#define INDEX_CONTEXT
#define OFFSET_MENUITEM_TITLE
#define OFFSET_STATUSBARITEM_URL
#define OFFSET_MERGEMENU_MERGEFALLBACK
constexpr OUStringLiteral IMAGES_NODENAME
#define PROPERTYCOUNT_TOOLBARITEM
#define OFFSET_IMAGES_SMALLHC
#define OFFSET_MERGEMENU_MERGECOMMAND
#define OFFSET_MERGESTATUSBAR_MERGEFALLBACK
#define OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT
#define OFFSET_MENUITEM_URL
#define OFFSET_MENUITEM_SUBMENU
#define PROPERTYCOUNT_MERGE_NOTEBOOKBAR
#define OFFSET_MERGETOOLBAR_MERGEFALLBACK
#define PROPERTYNAME_TARGET
#define OFFSET_POPUPMENU_SUBMENU
#define OFFSET_IMAGES_SMALL
#define OFFSET_TOOLBARITEM_TARGET
#define PROPERTYNAME_SUBMENU
#define OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER
#define PROPERTYCOUNT_INDEX
#define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS
#define INDEX_IMAGEIDENTIFIER
#define PROPERTYCOUNT_IMAGES
#define OFFSET_MERGEMENU_MERGECONTEXT
#define INDEX_URL
#define OFFSET_STATUSBARITEM_ALIGN
#define OFFSET_TOOLBARITEM_TITLE
#define PROPERTYNAME_CONTEXT
#define OFFSET_NOTEBOOKBARITEM_URL
#define INDEX_OWNERDRAW
#define OFFSET_STATUSBARITEM_CONTEXT
#define OFFSET_MERGESTATUSBAR_MERGECOMMAND
#define OFFSET_IMAGES_BIGHC
#define PROPERTYCOUNT_MERGE_TOOLBAR
#define OFFSET_IMAGES_SMALL_URL
#define OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER
#define OFFSET_TOOLBARITEM_CONTROLTYPE
#define OFFSET_NOTEBOOKBARITEM_CONTEXT
#define INDEX_TARGET
#define PROPERTYNAME_IMAGEIDENTIFIER
#define OFFSET_IMAGES_SMALLHC_URL
#define OFFSET_IMAGES_BIGHC_URL
#define OFFSET_MERGEMENU_MENUITEMS
#define OFFSET_POPUPMENU_TITLE
#define OFFSET_NOTEBOOKBARITEM_CONTROLTYPE
#define OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER
#define INDEX_MANDATORY
#define PROPERTYCOUNT_MERGE_MENUBAR
#define PROPERTYCOUNT_EMBEDDED_IMAGES
#define INDEX_ALIGN
#define OFFSET_MERGESTATUSBAR_STATUSBARITEMS
#define PROPERTYCOUNT_NOTEBOOKBARITEM
#define OFFSET_MENUITEM_IMAGEIDENTIFIER
#define PROPERTYCOUNT_MERGE_STATUSBAR
#define OFFSET_STATUSBARITEM_WIDTH
constexpr OUStringLiteral ADDONSPOPUPMENU_URL_PREFIX_STR
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
bool IsAlpha() const
bool IsEmpty() const
Bitmap GetBitmap(Color aTransparentReplaceColor) const
const Size & GetSizePixel() const
static GraphicFilter & GetGraphicFilter()
ErrCode ImportGraphic(Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat=GRFILTER_FORMAT_DONTKNOW, sal_uInt16 *pDeterminedFormat=nullptr, GraphicFilterImportFlags nImportFlags=GraphicFilterImportFlags::NONE)
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
bool IsEmpty() const
Size GetDefaultImageSize() const
Sequence< OUString > GetPropertyNamesImages(std::u16string_view aPropertyRootNode) const
std::unordered_map< OUString, MergeToolbarInstructionContainer > ToolbarMergingInstructions
AddonNotebookBars m_aCachedNotebookBarPartProperties
ToolbarMergingInstructions m_aCachedToolbarMergingInstructions
const Sequence< Sequence< PropertyValue > > & GetAddonsNotebookBarPart(sal_uInt32 nIndex) const
void ReadMergeStatusbarData(std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > > &rMergeStatusbar)
void ReadImages(ImageManager &aImageManager)
virtual void ImplCommit() override
Sequence< Sequence< PropertyValue > > m_aEmptyAddonNotebookBar
Sequence< OUString > GetPropertyNamesPopupMenu(std::u16string_view aPropertyRootNode) const
MergeStatusbarInstructionContainer m_aCachedStatusbarMergingInstructions
bool ReadStatusBarItem(std::u16string_view aStatusbarItemNodeName, Sequence< PropertyValue > &aStatusbarItem)
void ReadToolbarMergeInstructions(ToolbarMergingInstructions &rToolbarMergeMap)
const Sequence< Sequence< PropertyValue > > & GetAddonsHelpMenu() const
void ReadAddonMenuSet(Sequence< Sequence< PropertyValue > > &aAddonMenuSeq)
Sequence< OUString > GetPropertyNamesToolBarItem(std::u16string_view aPropertyRootNode) const
bool ReadNotebookBarItem(std::u16string_view aNotebookBarItemNodeName, Sequence< PropertyValue > &aNotebookBarItem)
virtual void Notify(const Sequence< OUString > &lPropertyNames) override
Sequence< Sequence< PropertyValue > > m_aCachedHelpMenuProperties
AddonToolBars m_aCachedToolBarPartProperties
OUString m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR]
Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties
void ReadMergeMenuData(std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > > &rMergeMenu)
std::unordered_map< OUString, MergeNotebookBarInstructionContainer > NotebookBarMergingInstructions
std::vector< OUString > m_aCachedToolBarPartResourceNames
bool GetMergeNotebookBarInstructions(const OUString &rNotebookBarName, MergeNotebookBarInstructionContainer &rNotebookBarInstructions) const
virtual ~AddonsOptions_Impl() override
void ReadSubMenuEntries(const Sequence< OUString > &aSubMenuNodeNames, Sequence< Sequence< PropertyValue > > &rSubMenu)
const Sequence< Sequence< PropertyValue > > & GetAddonsToolBarPart(sal_uInt32 nIndex) const
Sequence< Sequence< PropertyValue > > m_aEmptyAddonToolBar
bool ReadToolBarItemSet(const OUString &rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > > &aAddonOfficeToolBarSeq)
BitmapEx GetImageFromURL(const OUString &aURL, bool bBig, bool bNoScale)
OUString m_aPropImagesNames[PROPERTYCOUNT_IMAGES]
const MergeStatusbarInstructionContainer & GetMergeStatusbarInstructions() const
OUString m_aPropMergeStatusbarNames[PROPERTYCOUNT_MERGE_STATUSBAR]
bool HasAssociatedImages(const OUString &aURL)
MergeMenuInstructionContainer m_aCachedMergeMenuInsContainer
void ReadAndAssociateImages(const OUString &aURL, const OUString &aImageId)
OUString m_aPropMergeNotebookBarNames[PROPERTYCOUNT_MERGE_NOTEBOOKBAR]
OUString m_aPropNames[PROPERTYCOUNT_INDEX]
OUString m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR]
OUString GetAddonsToolbarResourceName(sal_uInt32 nIndex) const
void ReadOfficeHelpSet(Sequence< Sequence< PropertyValue > > &aAddonOfficeHelpMenuSeq)
std::unique_ptr< ImageEntry > ReadImageData(std::u16string_view aImagesNodeName)
void ReadOfficeToolBarSet(AddonToolBars &rAddonOfficeToolBars, std::vector< OUString > &rAddonOfficeToolBarResNames)
OUString GetAddonsNotebookBarResourceName(sal_uInt32 nIndex) const
bool ReadToolBarItem(std::u16string_view aToolBarItemNodeName, Sequence< PropertyValue > &aToolBarItem)
DECL_LINK(NotifyEvent, void *, void)
std::unordered_map< OUString, sal_uInt32 > StringToIndexMap
Sequence< OUString > GetPropertyNamesNotebookBarItem(std::u16string_view aPropertyRootNode) const
void SubstituteVariables(OUString &aURL)
BitmapEx ReadImageFromURL(const OUString &aURL)
void ReadStatusbarMergeInstructions(MergeStatusbarInstructionContainer &rContainer)
Sequence< OUString > GetPropertyNamesMenuItem(std::u16string_view aPropertyRootNode) const
bool GetMergeToolbarInstructions(const OUString &rToolbarName, MergeToolbarInstructionContainer &rToolbarInstructions) const
void ReadMenuMergeInstructions(MergeMenuInstructionContainer &rContainer)
void ReadOfficeMenuBarSet(Sequence< Sequence< PropertyValue > > &aAddonOfficeMenuBarSeq)
sal_Int32 GetAddonsToolBarCount() const
void AppendPopupMenu(Sequence< PropertyValue > &aTargetPopupMenu, const Sequence< PropertyValue > &rSourcePopupMenu)
sal_Int32 GetAddonsNotebookBarCount() const
std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars
std::vector< OUString > m_aCachedNotebookBarPartResourceNames
Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties
Sequence< OUString > GetPropertyNamesStatusbarItem(std::u16string_view aPropertyRootNode) const
const MergeMenuInstructionContainer & GetMergeMenuInstructions() const
void ReadOfficeNotebookBarSet(AddonNotebookBars &rAddonOfficeNotebookBars, std::vector< OUString > &rAddonOfficeNotebookBarResNames)
const Sequence< Sequence< PropertyValue > > & GetAddonsMenu() const
NotebookBarMergingInstructions m_aCachedNotebookBarMergingInstructions
bool ReadMenuItem(std::u16string_view aMenuItemNodeName, Sequence< PropertyValue > &aMenuItem, bool bIgnoreSubMenu=false)
void ReadMergeToolbarData(std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > > &rMergeToolbarItems)
std::unordered_map< OUString, ImageEntry > ImageManager
bool CreateImageFromSequence(BitmapEx &rImage, Sequence< sal_Int8 > &rBitmapDataSeq) const
bool ReadPopupMenu(std::u16string_view aPopupMenuNodeName, Sequence< PropertyValue > &aPopupMenu)
const Sequence< Sequence< PropertyValue > > & GetAddonsMenuBarPart() const
std::vector< Sequence< Sequence< PropertyValue > > > AddonNotebookBars
void ReadNotebookBarMergeInstructions(NotebookBarMergingInstructions &rNotebookBarMergeMap)
void ReadMergeNotebookBarData(std::u16string_view aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > > &rMergeNotebookBarItems)
bool ReadNotebookBarItemSet(const OUString &rNotebookBarItemSetNodeName, Sequence< Sequence< PropertyValue > > &aAddonOfficeNotebookBarSeq)
constexpr ::Color COL_LIGHTMAGENTA(0xFF, 0x00, 0xFF)
int nCount
bool VCL_DLLPUBLIC ReadDIBBitmapEx(BitmapEx &rTarget, SvStream &rIStm, bool bFileHeader=true, bool bMSOFormat=false)
URL aURL
float u
#define ERRCODE_NONE
sal_Int16 nValue
sal_Int32 nIndex
sal_Int64 n
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
COMPHELPER_DLLPUBLIC OUString getExpandedUri(css::uno::Reference< css::uno::XComponentContext > const &context, OUString const &uri)
Reference< XComponentContext > getProcessComponentContext()
Value
::std::vector< MergeToolbarInstruction > MergeToolbarInstructionContainer
::std::vector< MergeMenuInstruction > MergeMenuInstructionContainer
static BitmapEx ScaleImage(const BitmapEx &rImage, bool bBig)
::std::vector< MergeStatusbarInstruction > MergeStatusbarInstructionContainer
IMPL_LINK_NOARG(CloseDispatcher, impl_asyncCallback, LinkParamNone *, void)
asynchronous callback @descr We start all actions inside this object asynchronous (see comments there...
::std::vector< MergeNotebookBarInstruction > MergeNotebookBarInstructionContainer
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
void addImage(ImageSize eSize, const BitmapEx &rImage)
OUString aURL
URL in case it is not loaded yet.
BitmapEx aImage
original un-scaled image
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aMergeMenu
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aMergeNotebookBarItems
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aMergeStatusbarItems
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aMergeToolbarItems