LibreOffice Module framework (master) 1
toolbarmerger.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 <sal/config.h>
21
22#include <string_view>
23
26
36#include <o3tl/string_view.hxx>
37
38namespace framework
39{
40
41const char MERGE_TOOLBAR_URL[] = "URL";
42const char MERGE_TOOLBAR_TITLE[] = "Title";
43const char MERGE_TOOLBAR_CONTEXT[] = "Context";
44const char MERGE_TOOLBAR_TARGET[] = "Target";
45const char MERGE_TOOLBAR_CONTROLTYPE[] = "ControlType";
46const char MERGE_TOOLBAR_WIDTH[] = "Width";
47
48const char16_t MERGECOMMAND_ADDAFTER[] = u"AddAfter";
49const char16_t MERGECOMMAND_ADDBEFORE[] = u"AddBefore";
50const char16_t MERGECOMMAND_REPLACE[] = u"Replace";
51const char16_t MERGECOMMAND_REMOVE[] = u"Remove";
52
53const char16_t MERGEFALLBACK_ADDLAST[] = u"AddLast";
54const char16_t MERGEFALLBACK_ADDFIRST[] = u"AddFirst";
55const char16_t MERGEFALLBACK_IGNORE[] = u"Ignore";
56
57const char16_t TOOLBARCONTROLLER_BUTTON[] = u"Button";
58const char16_t TOOLBARCONTROLLER_COMBOBOX[] = u"Combobox";
59const char16_t TOOLBARCONTROLLER_EDIT[] = u"Editfield";
60const char16_t TOOLBARCONTROLLER_SPINFIELD[] = u"Spinfield";
61const char16_t TOOLBARCONTROLLER_IMGBUTTON[] = u"ImageButton";
62const char16_t TOOLBARCONTROLLER_DROPDOWNBOX[] = u"Dropdownbox";
63const char16_t TOOLBARCONTROLLER_DROPDOWNBTN[] = u"DropdownButton";
64const char16_t TOOLBARCONTROLLER_TOGGLEDDBTN[] = u"ToggleDropdownButton";
65const char16_t TOOLBARCONTROLLER_FIXEDIMAGE[] = u"FixedImage";
66const char16_t TOOLBARCONTROLLER_FIXEDTEXT[] = u"FixedText";
67
68const char TOOLBOXITEM_SEPARATOR_STR[] = "private:separator";
69
70using namespace ::com::sun::star;
71
96 std::u16string_view rContext,
97 std::u16string_view rModuleIdentifier )
98{
99 return ( rContext.empty() || ( rContext.find( rModuleIdentifier ) != std::u16string_view::npos ));
100}
101
118 const uno::Sequence< uno::Sequence< beans::PropertyValue > >& rSequence,
119 AddonToolbarItemContainer& rContainer )
120{
121 sal_Int32 nLen( rSequence.getLength() );
122 for ( sal_Int32 i = 0; i < nLen; i++ )
123 {
124 AddonToolbarItem aAddonToolbarItem;
125 ConvertSequenceToValues( rSequence[i],
126 aAddonToolbarItem.aCommandURL,
127 aAddonToolbarItem.aLabel,
128 aAddonToolbarItem.aTarget,
129 aAddonToolbarItem.aContext,
130 aAddonToolbarItem.aControlType,
131 aAddonToolbarItem.nWidth );
132 rContainer.push_back( aAddonToolbarItem );
133 }
134}
135
181 const uno::Sequence< beans::PropertyValue >& rSequence,
182 OUString& rCommandURL,
183 OUString& rLabel,
184 OUString& rTarget,
185 OUString& rContext,
186 OUString& rControlType,
187 sal_uInt16& rWidth )
188{
189 for ( beans::PropertyValue const & prop : rSequence )
190 {
191 if ( prop.Name == MERGE_TOOLBAR_URL )
192 prop.Value >>= rCommandURL;
193 else if ( prop.Name == MERGE_TOOLBAR_TITLE )
194 prop.Value >>= rLabel;
195 else if ( prop.Name == MERGE_TOOLBAR_CONTEXT )
196 prop.Value >>= rContext;
197 else if ( prop.Name == MERGE_TOOLBAR_TARGET )
198 prop.Value >>= rTarget;
199 else if ( prop.Name == MERGE_TOOLBAR_CONTROLTYPE )
200 prop.Value >>= rControlType;
201 else if ( prop.Name == MERGE_TOOLBAR_WIDTH )
202 {
203 sal_Int32 aValue = 0;
204 prop.Value >>= aValue;
205 rWidth = sal_uInt16( aValue );
206 }
207 }
208}
209
235 const ToolBox* pToolbar, sal_uInt16 nFirstItem,
236 std::u16string_view rReferencePoint )
237{
239 aResult.bResult = false;
241
242 const ToolBox::ImplToolItems::size_type nSize( pToolbar->GetItemCount() );
243
244 for ( ToolBox::ImplToolItems::size_type i = nFirstItem; i < nSize; i++ )
245 {
246 const ToolBoxItemId nItemId = pToolbar->GetItemId( i );
247 if ( nItemId > ToolBoxItemId(0) )
248 {
249 const OUString rCmd = pToolbar->GetItemCommand( nItemId );
250 if ( rCmd == rReferencePoint )
251 {
252 aResult.bResult = true;
253 aResult.nPos = i;
254 return aResult;
255 }
256 }
257 }
258
259 return aResult;
260}
261
309 ToolBox* pToolbar,
310 ToolBox::ImplToolItems::size_type nPos,
311 ToolBoxItemId& rItemId,
312 CommandToInfoMap& rCommandMap,
313 std::u16string_view rModuleIdentifier,
314 std::u16string_view rMergeCommand,
315 std::u16string_view rMergeCommandParameter,
316 const AddonToolbarItemContainer& rItems )
317{
318 if ( rMergeCommand == MERGECOMMAND_ADDAFTER )
319 MergeItems( pToolbar, nPos, 1, rItemId, rCommandMap, rModuleIdentifier, rItems );
320 else if ( rMergeCommand == MERGECOMMAND_ADDBEFORE )
321 MergeItems( pToolbar, nPos, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
322 else if ( rMergeCommand == MERGECOMMAND_REPLACE )
323 ReplaceItem( pToolbar, nPos, rItemId, rCommandMap, rModuleIdentifier, rItems );
324 else if ( rMergeCommand == MERGECOMMAND_REMOVE )
325 RemoveItems( pToolbar, nPos, rMergeCommandParameter );
326 else
327 return false;
328 return true;
329}
330
373 ToolBox* pToolbar,
374 ToolBoxItemId& rItemId,
375 CommandToInfoMap& rCommandMap,
376 std::u16string_view rModuleIdentifier,
377 std::u16string_view rMergeCommand,
378 std::u16string_view rMergeFallback,
379 const AddonToolbarItemContainer& rItems )
380{
381 if (( rMergeFallback == MERGEFALLBACK_IGNORE ) ||
382 ( rMergeCommand == MERGECOMMAND_REPLACE ) ||
383 ( rMergeCommand == MERGECOMMAND_REMOVE ) )
384 {
385 return true;
386 }
387 else if (( rMergeCommand == MERGECOMMAND_ADDBEFORE ) ||
388 ( rMergeCommand == MERGECOMMAND_ADDAFTER ) )
389 {
390 if ( rMergeFallback == MERGEFALLBACK_ADDFIRST )
391 MergeItems( pToolbar, 0, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
392 else if ( rMergeFallback == MERGEFALLBACK_ADDLAST )
393 MergeItems( pToolbar, ToolBox::APPEND, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
394 else
395 return false;
396 return true;
397 }
398
399 return false;
400}
401
435 ToolBox* pToolbar,
436 ToolBox::ImplToolItems::size_type nPos,
437 sal_uInt16 nModIndex,
438 ToolBoxItemId& rItemId,
439 CommandToInfoMap& rCommandMap,
440 std::u16string_view rModuleIdentifier,
441 const AddonToolbarItemContainer& rAddonToolbarItems )
442{
443 const sal_Int32 nSize( rAddonToolbarItems.size() );
444
445 for ( sal_Int32 i = 0; i < nSize; i++ )
446 {
447 const AddonToolbarItem& rItem = rAddonToolbarItems[i];
448 if ( IsCorrectContext( rItem.aContext, rModuleIdentifier ))
449 {
450 ToolBox::ImplToolItems::size_type nInsPos = nPos;
451 if (nInsPos != ToolBox::APPEND)
452 {
453 nInsPos += nModIndex+i;
454 if ( nInsPos > pToolbar->GetItemCount() )
455 nInsPos = ToolBox::APPEND;
456 }
457
459 pToolbar->InsertSeparator( nInsPos );
460 else
461 {
462 CommandToInfoMap::iterator pIter = rCommandMap.find( rItem.aCommandURL );
463 if ( pIter == rCommandMap.end())
464 {
465 CommandInfo aCmdInfo;
466 aCmdInfo.nId = rItemId;
467 const CommandToInfoMap::value_type aValue( rItem.aCommandURL, aCmdInfo );
468 rCommandMap.insert( aValue );
469 }
470 else
471 {
472 pIter->second.aIds.push_back( rItemId );
473 }
474
475 ToolBarMerger::CreateToolbarItem( pToolbar, nInsPos, rItemId, rItem );
476 }
477
478 ++rItemId;
479 }
480 }
481}
482
517 ToolBox* pToolbar,
518 ToolBox::ImplToolItems::size_type nPos,
519 ToolBoxItemId& rItemId,
520 CommandToInfoMap& rCommandMap,
521 std::u16string_view rModuleIdentifier,
522 const AddonToolbarItemContainer& rAddonToolbarItems )
523{
524 pToolbar->RemoveItem( nPos );
525 MergeItems( pToolbar, nPos, 0, rItemId, rCommandMap, rModuleIdentifier, rAddonToolbarItems );
526}
527
550 ToolBox* pToolbar,
551 ToolBox::ImplToolItems::size_type nPos,
552 std::u16string_view rMergeCommandParameter )
553{
554 sal_Int32 nCount = o3tl::toInt32(rMergeCommandParameter);
555 if ( nCount > 0 )
556 {
557 for ( sal_Int32 i = 0; i < nCount; i++ )
558 {
559 if ( nPos < pToolbar->GetItemCount() )
560 pToolbar->RemoveItem( nPos );
561 }
562 }
563}
564
591 const uno::Reference< uno::XComponentContext >& rxContext,
592 const uno::Reference< frame::XFrame > & xFrame,
593 ToolBox* pToolbar,
594 const OUString& rCommandURL,
595 ToolBoxItemId nId,
596 sal_uInt16 nWidth,
597 std::u16string_view rControlType )
598{
600
601 if ( rControlType == TOOLBARCONTROLLER_BUTTON )
602 pResult = new ButtonToolbarController( rxContext, pToolbar, rCommandURL );
603 else if ( rControlType == TOOLBARCONTROLLER_COMBOBOX )
604 pResult = new ComboboxToolbarController( rxContext, xFrame, pToolbar, nId, nWidth, rCommandURL );
605 else if ( rControlType == TOOLBARCONTROLLER_EDIT )
606 pResult = new EditToolbarController( rxContext, xFrame, pToolbar, nId, nWidth, rCommandURL );
607 else if ( rControlType == TOOLBARCONTROLLER_SPINFIELD )
608 pResult = new SpinfieldToolbarController( rxContext, xFrame, pToolbar, nId, nWidth, rCommandURL );
609 else if ( rControlType == TOOLBARCONTROLLER_IMGBUTTON )
610 pResult = new ImageButtonToolbarController( rxContext, xFrame, pToolbar, nId, rCommandURL );
611 else if ( rControlType == TOOLBARCONTROLLER_DROPDOWNBOX )
612 pResult = new DropdownToolbarController( rxContext, xFrame, pToolbar, nId, nWidth, rCommandURL );
613 else if ( rControlType == TOOLBARCONTROLLER_DROPDOWNBTN )
614 pResult = new ToggleButtonToolbarController( rxContext, xFrame, pToolbar, nId,
616 else if ( rControlType == TOOLBARCONTROLLER_FIXEDIMAGE )
617 pResult = new FixedImageToolbarController( rxContext, xFrame, pToolbar, nId, rCommandURL );
618 else if ( rControlType == TOOLBARCONTROLLER_FIXEDTEXT )
619 pResult = new FixedTextToolbarController( rxContext, xFrame, pToolbar, nId, rCommandURL );
620 else if ( rControlType == TOOLBARCONTROLLER_TOGGLEDDBTN )
621 pResult = new ToggleButtonToolbarController( rxContext, xFrame, pToolbar, nId,
623 else
624 pResult = new GenericToolbarController( rxContext, xFrame, pToolbar, nId, rCommandURL );
625
626 return pResult;
627}
628
629void ToolBarMerger::CreateToolbarItem( ToolBox* pToolbar, ToolBox::ImplToolItems::size_type nPos, ToolBoxItemId nItemId, const AddonToolbarItem& rItem )
630{
631 assert(pToolbar->GetItemData(nItemId) == nullptr); // that future would contain a double free
632
633 pToolbar->InsertItem( nItemId, rItem.aLabel, rItem.aCommandURL, ToolBoxItemBits::NONE, nPos );
634 pToolbar->SetQuickHelpText( nItemId, rItem.aLabel );
635 pToolbar->SetItemText( nItemId, rItem.aLabel );
636 pToolbar->EnableItem( nItemId );
637 pToolbar->SetItemState( nItemId, TRISTATE_FALSE );
638
639 // Use the user data to store add-on specific data with the toolbar item
640 AddonsParams* pAddonParams = new AddonsParams;
641 pAddonParams->aControlType = rItem.aControlType;
642 pAddonParams->nWidth = rItem.nWidth;
643 pToolbar->SetItemData( nItemId, pAddonParams );
644}
645
646} // namespace framework
647
648/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ToolBoxItemId GetItemId(ImplToolItems::size_type nPos) const
void RemoveItem(ImplToolItems::size_type nPos)
void SetQuickHelpText(ToolBoxItemId nItemId, const OUString &rText)
OUString GetItemCommand(ToolBoxItemId nItemId) const
void InsertSeparator(ImplToolItems::size_type nPos=APPEND, sal_uInt16 nPixSize=0)
void EnableItem(ToolBoxItemId nItemId, bool bEnable=true)
void * GetItemData(ToolBoxItemId nItemId) const
ImplToolItems::size_type GetItemCount() const
static constexpr auto APPEND
void SetItemState(ToolBoxItemId nItemId, TriState eState)
void SetItemData(ToolBoxItemId nItemId, void *pNewData)
virtual void InsertItem(const OUString &rCommand, const css::uno::Reference< css::frame::XFrame > &rFrame, ToolBoxItemBits nBits, const Size &rRequestedSize, ImplToolItems::size_type nPos=APPEND)
static constexpr auto ITEM_NOTFOUND
void SetItemText(ToolBoxItemId nItemId, const OUString &rText)
static void CreateToolbarItem(ToolBox *pToolbox, ToolBox::ImplToolItems::size_type nPos, ToolBoxItemId nItemId, const AddonToolbarItem &rAddonToolbarItem)
static rtl::Reference<::cppu::OWeakObject > CreateController(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::frame::XFrame > &xFrame, ToolBox *pToolbar, const OUString &rCommandURL, ToolBoxItemId nId, sal_uInt16 nWidth, std::u16string_view rControlType)
Removes toolbar items from an existing toolbar.
static void MergeItems(ToolBox *pToolbar, ToolBox::ImplToolItems::size_type nPos, sal_uInt16 nModIndex, ToolBoxItemId &rItemId, CommandToInfoMap &rCommandMap, std::u16string_view rModuleIdentifier, const AddonToolbarItemContainer &rAddonToolbarItems)
Merges (adds) toolbar items into an existing toolbar.
static bool ProcessMergeOperation(ToolBox *pToolbar, ToolBox::ImplToolItems::size_type nPos, ToolBoxItemId &rItemId, CommandToInfoMap &rCommandMap, std::u16string_view rModuleIdentifier, std::u16string_view rMergeCommand, std::u16string_view rMergeCommandParameter, const AddonToolbarItemContainer &rItems)
Processes a merge operation.
static void ReplaceItem(ToolBox *pToolbar, ToolBox::ImplToolItems::size_type nPos, ToolBoxItemId &rItemId, CommandToInfoMap &rCommandMap, std::u16string_view rModuleIdentifier, const AddonToolbarItemContainer &rAddonToolbarItems)
Replaces a toolbar item with new items for an existing toolbar.
static void ConvertSeqSeqToVector(const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > &rSequence, AddonToolbarItemContainer &rContainer)
Converts a sequence, sequence of property values to a vector of structs.
static void RemoveItems(ToolBox *pToolbar, ToolBox::ImplToolItems::size_type nPos, std::u16string_view rMergeCommandParameter)
Removes toolbar items from an existing toolbar.
static void ConvertSequenceToValues(const css::uno::Sequence< css::beans::PropertyValue > &rSequence, OUString &rCommandURL, OUString &rLabel, OUString &rTarget, OUString &rContext, OUString &rControlType, sal_uInt16 &rWidth)
Converts a sequence of property values to single values.
static bool ProcessMergeFallback(ToolBox *pToolbar, ToolBoxItemId &rItemId, CommandToInfoMap &rCommandMap, std::u16string_view rModuleIdentifier, std::u16string_view rMergeCommand, std::u16string_view rMergeFallback, const AddonToolbarItemContainer &rItems)
Processes a merge fallback operation.
static ReferenceToolbarPathInfo FindReferencePoint(const ToolBox *pToolbar, sal_uInt16 nFirstItem, std::u16string_view rReferencePoint)
Tries to find the reference point provided and delivers position and result of the search process.
static bool IsCorrectContext(std::u16string_view aContext, std::u16string_view aModuleIdentifier)
Check whether a module identifier is part of a context defined by a colon separated list of module id...
int nCount
float u
FilterGroup & rTarget
TRISTATE_FALSE
sal_uInt16 nPos
const char16_t MERGECOMMAND_REPLACE[]
const char16_t TOOLBARCONTROLLER_SPINFIELD[]
const char TOOLBOXITEM_SEPARATOR_STR[]
const char16_t MERGEFALLBACK_ADDFIRST[]
const char MERGE_TOOLBAR_URL[]
const char MERGE_TOOLBAR_WIDTH[]
const char16_t TOOLBARCONTROLLER_TOGGLEDDBTN[]
const char MERGE_TOOLBAR_TITLE[]
const char16_t TOOLBARCONTROLLER_DROPDOWNBOX[]
::std::vector< AddonToolbarItem > AddonToolbarItemContainer
std::unordered_map< OUString, CommandInfo > CommandToInfoMap
Definition: commandinfo.hxx:41
const char MERGE_TOOLBAR_CONTEXT[]
const char16_t TOOLBARCONTROLLER_FIXEDIMAGE[]
const char16_t TOOLBARCONTROLLER_COMBOBOX[]
const char16_t MERGEFALLBACK_IGNORE[]
const char16_t MERGEFALLBACK_ADDLAST[]
const char16_t TOOLBARCONTROLLER_IMGBUTTON[]
const char16_t TOOLBARCONTROLLER_EDIT[]
const char MERGE_TOOLBAR_CONTROLTYPE[]
const char16_t MERGECOMMAND_ADDAFTER[]
const char MERGE_TOOLBAR_TARGET[]
const char16_t TOOLBARCONTROLLER_DROPDOWNBTN[]
const char16_t MERGECOMMAND_REMOVE[]
const char16_t TOOLBARCONTROLLER_BUTTON[]
const char16_t MERGECOMMAND_ADDBEFORE[]
const char16_t TOOLBARCONTROLLER_FIXEDTEXT[]
int i
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
sal_Int16 nId
ToolBox::ImplToolItems::size_type nPos
Reference< XFrame > xFrame