1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <uielement/toolbarmerger.hxx>
25 #include <framework/generictoolbarcontroller.hxx>
27 #include <uielement/buttontoolbarcontroller.hxx>
28 #include <uielement/comboboxtoolbarcontroller.hxx>
29 #include <uielement/dropdownboxtoolbarcontroller.hxx>
30 #include <uielement/edittoolbarcontroller.hxx>
31 #include <uielement/imagebuttontoolbarcontroller.hxx>
32 #include <uielement/spinfieldtoolbarcontroller.hxx>
33 #include <uielement/togglebuttontoolbarcontroller.hxx>
34 #include <uielement/FixedTextToolbarController.hxx>
35 #include <uielement/FixedImageToolbarController.hxx>
36 #include <o3tl/string_view.hxx>
41 const char MERGE_TOOLBAR_URL
[] = "URL";
42 const char MERGE_TOOLBAR_TITLE
[] = "Title";
43 const char MERGE_TOOLBAR_CONTEXT
[] = "Context";
44 const char MERGE_TOOLBAR_TARGET
[] = "Target";
45 const char MERGE_TOOLBAR_CONTROLTYPE
[] = "ControlType";
46 const char MERGE_TOOLBAR_WIDTH
[] = "Width";
48 const char16_t MERGECOMMAND_ADDAFTER
[] = u
"AddAfter";
49 const char16_t MERGECOMMAND_ADDBEFORE
[] = u
"AddBefore";
50 const char16_t MERGECOMMAND_REPLACE
[] = u
"Replace";
51 const char16_t MERGECOMMAND_REMOVE
[] = u
"Remove";
53 const char16_t MERGEFALLBACK_ADDLAST
[] = u
"AddLast";
54 const char16_t MERGEFALLBACK_ADDFIRST
[] = u
"AddFirst";
55 const char16_t MERGEFALLBACK_IGNORE
[] = u
"Ignore";
57 const char16_t TOOLBARCONTROLLER_BUTTON
[] = u
"Button";
58 const char16_t TOOLBARCONTROLLER_COMBOBOX
[] = u
"Combobox";
59 const char16_t TOOLBARCONTROLLER_EDIT
[] = u
"Editfield";
60 const char16_t TOOLBARCONTROLLER_SPINFIELD
[] = u
"Spinfield";
61 const char16_t TOOLBARCONTROLLER_IMGBUTTON
[] = u
"ImageButton";
62 const char16_t TOOLBARCONTROLLER_DROPDOWNBOX
[] = u
"Dropdownbox";
63 const char16_t TOOLBARCONTROLLER_DROPDOWNBTN
[] = u
"DropdownButton";
64 const char16_t TOOLBARCONTROLLER_TOGGLEDDBTN
[] = u
"ToggleDropdownButton";
65 const char16_t TOOLBARCONTROLLER_FIXEDIMAGE
[] = u
"FixedImage";
66 const char16_t TOOLBARCONTROLLER_FIXEDTEXT
[] = u
"FixedText";
68 const char TOOLBOXITEM_SEPARATOR_STR
[] = "private:separator";
70 using namespace ::com::sun::star
;
73 Check whether a module identifier is part of a context
74 defined by a colon separated list of module identifier.
79 Describes a context string list where all contexts
80 are delimited by a colon. For more information about
81 the module identifier used as context strings see the
82 IDL description of css::frame::XModuleManager
87 A string describing a module identifier. See IDL
88 description of css::frame::XModuleManager.
91 The result is true if the rContext is an empty string
92 or rModuleIdentifier is part of the context string.
95 bool ToolBarMerger::IsCorrectContext(
96 std::u16string_view rContext
,
97 std::u16string_view rModuleIdentifier
)
99 return ( rContext
.empty() || ( rContext
.find( rModuleIdentifier
) != std::u16string_view::npos
));
103 Converts a sequence, sequence of property values to
109 Provides a sequence, sequence of property values.
114 A vector of AddonToolbarItems which will hold the
115 conversion from the rSequence argument.
117 void ToolBarMerger::ConvertSeqSeqToVector(
118 const uno::Sequence
< uno::Sequence
< beans::PropertyValue
> >& rSequence
,
119 AddonToolbarItemContainer
& rContainer
)
121 sal_Int32
nLen( rSequence
.getLength() );
122 for ( sal_Int32 i
= 0; i
< nLen
; i
++ )
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
);
137 Converts a sequence of property values to single
143 Provides a sequence of property values.
148 Contains the value of the property with
154 Contains the value of the property with
160 Contains the value of the property with
166 Contains the value of the property with
172 Contains the value of the property with
176 All possible mapping between sequence of property
177 values and the single values are done.
180 void ToolBarMerger::ConvertSequenceToValues(
181 const uno::Sequence
< beans::PropertyValue
>& rSequence
,
182 OUString
& rCommandURL
,
186 OUString
& rControlType
,
189 for ( beans::PropertyValue
const & prop
: rSequence
)
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
)
203 sal_Int32 aValue
= 0;
204 prop
.Value
>>= aValue
;
205 rWidth
= sal_uInt16( aValue
);
211 Tries to find the reference point provided and delivers
212 position and result of the search process.
217 Must be a valid pointer to a toolbar with items which
222 First toolbar item to search from.
227 A command URL which should be the reference point for
228 the coming merge operation.
231 Provides information about the search result, the
232 position of the reference point and the toolbar used.
234 ReferenceToolbarPathInfo
ToolBarMerger::FindReferencePoint(
235 const ToolBox
* pToolbar
, sal_uInt16 nFirstItem
,
236 std::u16string_view rReferencePoint
)
238 ReferenceToolbarPathInfo aResult
;
239 aResult
.bResult
= false;
240 aResult
.nPos
= ToolBox::ITEM_NOTFOUND
;
242 const ToolBox::ImplToolItems::size_type
nSize( pToolbar
->GetItemCount() );
244 for ( ToolBox::ImplToolItems::size_type i
= nFirstItem
; i
< nSize
; i
++ )
246 const ToolBoxItemId nItemId
= pToolbar
->GetItemId( i
);
247 if ( nItemId
> ToolBoxItemId(0) )
249 const OUString rCmd
= pToolbar
->GetItemCommand( nItemId
);
250 if ( rCmd
== rReferencePoint
)
252 aResult
.bResult
= true;
263 Processes a merge operation.
268 A valid pointer to the toolbar where the merge
269 operation is applied to.
274 The reference position of the toolbar item for
275 the merge operation. Value must be between
276 0 and number of toolbar items - 1.
286 The current application module context.
294 rMergeCommandParameter.
296 An optional argument for the merge command.
301 Toolbar items which are associated to the merge
305 Returns true for a successful operation otherwise
308 bool ToolBarMerger::ProcessMergeOperation(
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
)
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
);
332 Processes a merge fallback operation.
337 A valid pointer to the toolbar where the merge
338 fall back operation is applied to.
343 The reference position of the toolbar item for
344 the merge operation. Value must be between
345 0 and number of toolbar items - 1.
355 The current application module context.
365 Toolbar items which are associated to the merge
369 Returns true for a successful operation otherwise
372 bool ToolBarMerger::ProcessMergeFallback(
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
)
381 if (( rMergeFallback
== MERGEFALLBACK_IGNORE
) ||
382 ( rMergeCommand
== MERGECOMMAND_REPLACE
) ||
383 ( rMergeCommand
== MERGECOMMAND_REMOVE
) )
387 else if (( rMergeCommand
== MERGECOMMAND_ADDBEFORE
) ||
388 ( rMergeCommand
== MERGECOMMAND_ADDAFTER
) )
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
);
403 Merges (adds) toolbar items into an existing toolbar.
408 A valid pointer to the toolbar where the merge
409 fall back operation is applied to.
414 The reference position of the toolbar item for
415 the merge operation. Value must be between
416 0 and number of toolbar items - 1.
426 The current application module context.
431 Toolbar items which are associated to the merge
434 void ToolBarMerger::MergeItems(
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
)
443 const sal_Int32
nSize( rAddonToolbarItems
.size() );
445 for ( sal_Int32 i
= 0; i
< nSize
; i
++ )
447 const AddonToolbarItem
& rItem
= rAddonToolbarItems
[i
];
448 if ( IsCorrectContext( rItem
.aContext
, rModuleIdentifier
))
450 ToolBox::ImplToolItems::size_type nInsPos
= nPos
;
451 if (nInsPos
!= ToolBox::APPEND
)
453 nInsPos
+= nModIndex
+i
;
454 if ( nInsPos
> pToolbar
->GetItemCount() )
455 nInsPos
= ToolBox::APPEND
;
458 if ( rItem
.aCommandURL
== TOOLBOXITEM_SEPARATOR_STR
)
459 pToolbar
->InsertSeparator( nInsPos
);
462 CommandToInfoMap::iterator pIter
= rCommandMap
.find( rItem
.aCommandURL
);
463 if ( pIter
== rCommandMap
.end())
465 CommandInfo aCmdInfo
;
466 aCmdInfo
.nId
= rItemId
;
467 const CommandToInfoMap::value_type
aValue( rItem
.aCommandURL
, aCmdInfo
);
468 rCommandMap
.insert( aValue
);
472 pIter
->second
.aIds
.push_back( rItemId
);
475 ToolBarMerger::CreateToolbarItem( pToolbar
, nInsPos
, rItemId
, rItem
);
484 Replaces a toolbar item with new items for an
490 A valid pointer to the toolbar where the merge
491 fall back operation is applied to.
496 The reference position of the toolbar item for
497 the merge operation. Value must be between
498 0 and number of toolbar items - 1.
508 The current application module context.
513 Toolbar items which are associated to the merge
516 void ToolBarMerger::ReplaceItem(
518 ToolBox::ImplToolItems::size_type nPos
,
519 ToolBoxItemId
& rItemId
,
520 CommandToInfoMap
& rCommandMap
,
521 std::u16string_view rModuleIdentifier
,
522 const AddonToolbarItemContainer
& rAddonToolbarItems
)
524 pToolbar
->RemoveItem( nPos
);
525 MergeItems( pToolbar
, nPos
, 0, rItemId
, rCommandMap
, rModuleIdentifier
, rAddonToolbarItems
);
529 Removes toolbar items from an existing toolbar.
534 A valid pointer to the toolbar where the merge
535 fall back operation is applied to.
540 The reference position of the toolbar item for
541 the merge operation. Value must be between
542 0 and number of toolbar items - 1.
545 rMergeCommandParameter.
547 An optional argument for the merge command.
549 void ToolBarMerger::RemoveItems(
551 ToolBox::ImplToolItems::size_type nPos
,
552 std::u16string_view rMergeCommandParameter
)
554 sal_Int32 nCount
= o3tl::toInt32(rMergeCommandParameter
);
557 for ( sal_Int32 i
= 0; i
< nCount
; i
++ )
559 if ( nPos
< pToolbar
->GetItemCount() )
560 pToolbar
->RemoveItem( nPos
);
566 Removes toolbar items from an existing toolbar.
571 A valid pointer to the toolbar where the merge
572 fall back operation is applied to.
577 The reference position of the toolbar item for
578 the merge operation. Value must be between
579 0 and number of toolbar items - 1.
582 rMergeCommandParameter.
584 An optional argument for the merge command.
587 Returns true for a successful operation otherwise
590 rtl::Reference
<::cppu::OWeakObject
> ToolBarMerger::CreateController(
591 const uno::Reference
< uno::XComponentContext
>& rxContext
,
592 const uno::Reference
< frame::XFrame
> & xFrame
,
594 const OUString
& rCommandURL
,
597 std::u16string_view rControlType
)
599 rtl::Reference
<::cppu::OWeakObject
> pResult
;
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
,
615 ToggleButtonToolbarController::Style::DropDownButton
, rCommandURL
);
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
,
622 ToggleButtonToolbarController::Style::ToggleDropDownButton
, rCommandURL
);
624 pResult
= new GenericToolbarController( rxContext
, xFrame
, pToolbar
, nId
, rCommandURL
);
629 void ToolBarMerger::CreateToolbarItem( ToolBox
* pToolbar
, ToolBox::ImplToolItems::size_type nPos
, ToolBoxItemId nItemId
, const AddonToolbarItem
& rItem
)
631 assert(pToolbar
->GetItemData(nItemId
) == nullptr); // that future would contain a double free
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
);
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
);
646 } // namespace framework
648 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */