tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / framework / source / uielement / toolbarmerger.cxx
blob5588ff0522d319ec7a44b9fe692a55e98022066f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
38 namespace framework
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;
72 /**
73 Check whether a module identifier is part of a context
74 defined by a colon separated list of module identifier.
76 @param
77 rContext
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
84 @param
85 rModuleIdentifier
87 A string describing a module identifier. See IDL
88 description of css::frame::XModuleManager.
90 @result
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
104 a vector of structs.
106 @param
107 rSequence
109 Provides a sequence, sequence of property values.
111 @param
112 rContainer
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
138 values.
140 @param
141 rSequence
143 Provides a sequence of property values.
145 @param
146 rCommandURL
148 Contains the value of the property with
149 Name="CommandURL".
151 @param
152 rLabel
154 Contains the value of the property with
155 Name="Title"
157 @param
158 rTarget
160 Contains the value of the property with
161 Name="Target"
163 @param
164 rContext
166 Contains the value of the property with
167 Name="Context"
169 @param
170 rControlType
172 Contains the value of the property with
173 Name="ControlType"
175 @result
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,
183 OUString& rLabel,
184 OUString& rTarget,
185 OUString& rContext,
186 OUString& rControlType,
187 sal_uInt16& rWidth )
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.
214 @param
215 pToolbar
217 Must be a valid pointer to a toolbar with items which
218 should be searched.
219 @param
220 nFirstItem
222 First toolbar item to search from.
224 @param
225 rReferencePoint
227 A command URL which should be the reference point for
228 the coming merge operation.
230 @result
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;
253 aResult.nPos = i;
254 return aResult;
259 return aResult;
263 Processes a merge operation.
265 @param
266 pToolbar
268 A valid pointer to the toolbar where the merge
269 operation is applied to.
271 @param
272 nPos
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.
278 @param
279 rItemId
281 A unique item ID.
283 @param
284 rModuleIdentifier
286 The current application module context.
288 @param
289 rMergeCommand
291 A merge command.
293 @param
294 rMergeCommandParameter.
296 An optional argument for the merge command.
298 @param
299 rItems
301 Toolbar items which are associated to the merge
302 command.
304 @result
305 Returns true for a successful operation otherwise
306 false.
308 bool ToolBarMerger::ProcessMergeOperation(
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 )
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;
332 Processes a merge fallback operation.
334 @param
335 pToolbar
337 A valid pointer to the toolbar where the merge
338 fall back operation is applied to.
340 @param
341 nPos
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.
347 @param
348 rItemId
350 A unique item ID.
352 @param
353 rModuleIdentifier
355 The current application module context.
357 @param
358 rMergeCommand
360 A merge command.
362 @param
363 rItems
365 Toolbar items which are associated to the merge
366 command.
368 @result
369 Returns true for a successful operation otherwise
370 false.
372 bool ToolBarMerger::ProcessMergeFallback(
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 )
381 if (( rMergeFallback == MERGEFALLBACK_IGNORE ) ||
382 ( rMergeCommand == MERGECOMMAND_REPLACE ) ||
383 ( rMergeCommand == MERGECOMMAND_REMOVE ) )
385 return true;
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 );
394 else
395 return false;
396 return true;
399 return false;
403 Merges (adds) toolbar items into an existing toolbar.
405 @param
406 pToolbar
408 A valid pointer to the toolbar where the merge
409 fall back operation is applied to.
411 @param
412 nPos
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.
418 @param
419 rItemId
421 A unique item ID.
423 @param
424 rModuleIdentifier
426 The current application module context.
428 @param
429 rItems
431 Toolbar items which are associated to the merge
432 command.
434 void ToolBarMerger::MergeItems(
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 )
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 );
460 else
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 );
470 else
472 pIter->second.aIds.push_back( rItemId );
475 ToolBarMerger::CreateToolbarItem( pToolbar, nInsPos, rItemId, rItem );
478 ++rItemId;
484 Replaces a toolbar item with new items for an
485 existing toolbar.
487 @param
488 pToolbar
490 A valid pointer to the toolbar where the merge
491 fall back operation is applied to.
493 @param
494 nPos
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.
500 @param
501 rItemId
503 A unique item ID.
505 @param
506 rModuleIdentifier
508 The current application module context.
510 @param
511 rItems
513 Toolbar items which are associated to the merge
514 command.
516 void ToolBarMerger::ReplaceItem(
517 ToolBox* pToolbar,
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.
531 @param
532 pToolbar
534 A valid pointer to the toolbar where the merge
535 fall back operation is applied to.
537 @param
538 nPos
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.
544 @param
545 rMergeCommandParameter.
547 An optional argument for the merge command.
549 void ToolBarMerger::RemoveItems(
550 ToolBox* pToolbar,
551 ToolBox::ImplToolItems::size_type nPos,
552 std::u16string_view rMergeCommandParameter )
554 sal_Int32 nCount = o3tl::toInt32(rMergeCommandParameter);
555 if ( nCount > 0 )
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.
568 @param
569 pToolbar
571 A valid pointer to the toolbar where the merge
572 fall back operation is applied to.
574 @param
575 nPos
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.
581 @param
582 rMergeCommandParameter.
584 An optional argument for the merge command.
586 @result
587 Returns true for a successful operation otherwise
588 false.
590 rtl::Reference<::cppu::OWeakObject> ToolBarMerger::CreateController(
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 )
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 );
623 else
624 pResult = new GenericToolbarController( rxContext, xFrame, pToolbar, nId, rCommandURL );
626 return pResult;
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: */