1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: toolbarmerger.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 #include <uielement/toolbarmerger.hxx>
35 #include <uielement/generictoolbarcontroller.hxx>
36 #include <helper/imageproducer.hxx>
38 #include <svtools/miscopt.hxx>
43 static const char MERGE_TOOLBAR_URL
[] = "URL";
44 static const sal_uInt32 MERGE_TOOLBAR_URL_LEN
= 3;
45 static const char MERGE_TOOLBAR_TITLE
[] = "Title";
46 static const sal_uInt32 MERGE_TOOLBAR_TITLE_LEN
= 5;
47 static const char MERGE_TOOLBAR_IMAGEID
[] = "ImageIdentifier";
48 static const sal_uInt32 MERGE_TOOLBAR_IMAGEID_LEN
= 15;
49 static const char MERGE_TOOLBAR_CONTEXT
[] = "Context";
50 static const sal_uInt32 MERGE_TOOLBAR_CONTEXT_LEN
= 7;
51 static const char MERGE_TOOLBAR_TARGET
[] = "Target";
52 static const sal_uInt32 MERGE_TOOLBAR_TARGET_LEN
= 6;
53 static const char MERGE_TOOLBAR_CONTROLTYPE
[] = "ControlType";
54 static const char MERGE_TOOLBAR_CONTROLTYPE_LEN
= 11;
55 static const char MERGE_TOOLBAR_WIDTH
[] = "Width";
56 static const char MERGE_TOOLBAR_WIDTH_LEN
= 5;
58 static const char MERGECOMMAND_ADDAFTER
[] = "AddAfter";
59 static const sal_uInt32 MERGECOMMAND_ADDAFTER_LEN
= 8;
60 static const char MERGECOMMAND_ADDBEFORE
[] = "AddBefore";
61 static const sal_uInt32 MERGECOMMAND_ADDBEFORE_LEN
= 9;
62 static const char MERGECOMMAND_REPLACE
[] = "Replace";
63 static const sal_uInt32 MERGECOMMAND_REPLACE_LEN
= 7;
64 static const char MERGECOMMAND_REMOVE
[] = "Remove";
65 static const sal_uInt32 MERGECOMMAND_REMOVE_LEN
= 6;
67 static const char MERGEFALLBACK_ADDLAST
[] = "AddLast";
68 static const char MERGEFALLBACK_ADDLAST_LEN
= 7;
69 static const char MERGEFALLBACK_ADDFIRST
[] = "AddFirst";
70 static const char MERGEFALLBACK_ADDFIRST_LEN
= 8;
71 static const char MERGEFALLBACK_IGNORE
[] = "Ignore";
72 static const char MERGEFALLBACK_IGNORE_LEN
= 6;
74 static const char TOOLBARCONTROLLER_BUTTON
[] = "Button";
75 static const sal_uInt32 TOOLBARCONTROLLER_BUTTON_LEN
= 6;
76 static const char TOOLBARCONTROLLER_COMBOBOX
[] = "Combobox";
77 static const sal_uInt32 TOOLBARCONTROLLER_COMBOBOX_LEN
= 8;
78 static const char TOOLBARCONTROLLER_EDIT
[] = "Editfield";
79 static const sal_uInt32 TOOLBARCONTROLLER_EDIT_LEN
= 9;
80 static const char TOOLBARCONTROLLER_SPINFIELD
[] = "Spinfield";
81 static const sal_uInt32 TOOLBARCONTROLLER_SPINFIELD_LEN
= 9;
82 static const char TOOLBARCONTROLLER_IMGBUTTON
[] = "ImageButton";
83 static const sal_uInt32 TOOLBARCONTROLLER_IMGBUTTON_LEN
= 11;
84 static const char TOOLBARCONTROLLER_DROPDOWNBOX
[] = "Dropdownbox";
85 static const sal_uInt32 TOOLBARCONTROLLER_DROPDOWNBOX_LEN
= 11;
86 static const char TOOLBARCONTROLLER_DROPDOWNBTN
[] = "DropdownButton";
87 static const sal_uInt32 TOOLBARCONTROLLER_DROPDOWNBTN_LEN
= 14;
88 static const char TOOLBARCONTROLLER_TOGGLEDDBTN
[] = "ToggleDropdownButton";
89 static const sal_uInt32 TOOLBARCONTROLLER_TOGGLEDDBTN_LEN
= 20;
91 static const char TOOLBOXITEM_SEPARATOR_STR
[] = "private:separator";
92 static const USHORT TOOLBOXITEM_SEPARATOR_STR_LEN
= sizeof( TOOLBOXITEM_SEPARATOR_STR
)-1;
94 using namespace ::com::sun::star
;
97 Check whether a module identifier is part of a context
98 defined by a colon separated list of module identifier.
103 Describes a context string list where all contexts
104 are delimited by a colon. For more information about
105 the module identifier used as context strings see the
106 IDL description of com::sun::star::frame::XModuleManager
111 A string describing a module identifier. See IDL
112 description of com::sun::star::frame::XModuleManager.
115 The result is true if the rContext is an empty string
116 or rModuleIdentifier is part of the context string.
119 bool ToolBarMerger::IsCorrectContext(
120 const ::rtl::OUString
& rContext
,
121 const ::rtl::OUString
& rModuleIdentifier
)
123 return (( rContext
.getLength() == 0 ) || ( rContext
.indexOf( rModuleIdentifier
) >= 0 ));
127 Converts a sequence, sequence of property values to
133 Provides a sequence, sequence of property values.
138 A vector of AddonToolbarItems which will hold the
139 conversion from the rSequence argument.
142 The result is true if the sequence, sequence of property
143 values could be converted to a vector of structs.
146 bool ToolBarMerger::ConvertSeqSeqToVector(
147 const uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > rSequence
,
148 AddonToolbarItemContainer
& rContainer
)
150 sal_Int32
nLen( rSequence
.getLength() );
151 for ( sal_Int32 i
= 0; i
< nLen
; i
++ )
153 AddonToolbarItem aAddonToolbarItem
;
154 ConvertSequenceToValues( rSequence
[i
],
155 aAddonToolbarItem
.aCommandURL
,
156 aAddonToolbarItem
.aLabel
,
157 aAddonToolbarItem
.aImageIdentifier
,
158 aAddonToolbarItem
.aTarget
,
159 aAddonToolbarItem
.aContext
,
160 aAddonToolbarItem
.aControlType
,
161 aAddonToolbarItem
.nWidth
);
162 rContainer
.push_back( aAddonToolbarItem
);
169 Converts a sequence of property values to single
175 Provides a sequence of property values.
180 Contains the value of the property with
186 Contains the value of the property with
192 Contains the value of the property with
193 Name="ImageIdentifier"
198 Contains the value of the property with
204 Contains the value of the property with
210 Contains the value of the property with
214 All possible mapping between sequence of property
215 values and the single values are done.
218 void ToolBarMerger::ConvertSequenceToValues(
219 const uno::Sequence
< beans::PropertyValue
> rSequence
,
220 ::rtl::OUString
& rCommandURL
,
221 ::rtl::OUString
& rLabel
,
222 ::rtl::OUString
& rImageIdentifier
,
223 ::rtl::OUString
& rTarget
,
224 ::rtl::OUString
& rContext
,
225 ::rtl::OUString
& rControlType
,
228 for ( sal_Int32 i
= 0; i
< rSequence
.getLength(); i
++ )
230 if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_URL
, MERGE_TOOLBAR_URL_LEN
))
231 rSequence
[i
].Value
>>= rCommandURL
;
232 else if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_TITLE
, MERGE_TOOLBAR_TITLE_LEN
))
233 rSequence
[i
].Value
>>= rLabel
;
234 else if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_IMAGEID
, MERGE_TOOLBAR_IMAGEID_LEN
))
235 rSequence
[i
].Value
>>= rImageIdentifier
;
236 else if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_CONTEXT
, MERGE_TOOLBAR_CONTEXT_LEN
))
237 rSequence
[i
].Value
>>= rContext
;
238 else if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_TARGET
, MERGE_TOOLBAR_TARGET_LEN
))
239 rSequence
[i
].Value
>>= rTarget
;
240 else if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_CONTROLTYPE
, MERGE_TOOLBAR_CONTROLTYPE_LEN
))
241 rSequence
[i
].Value
>>= rControlType
;
242 else if ( rSequence
[i
].Name
.equalsAsciiL( MERGE_TOOLBAR_WIDTH
, MERGE_TOOLBAR_WIDTH_LEN
))
244 sal_Int32 aValue
= 0;
245 rSequence
[i
].Value
>>= aValue
;
246 rWidth
= sal_uInt16( aValue
);
252 Tries to find the reference point provided and delivers
253 position and result of the search process.
258 Must be a valid pointer to a toolbar with items which
264 A command URL which should be the reference point for
265 the coming merge operation.
268 Provides information about the search result, the
269 position of the reference point and the toolbar used.
271 ReferenceToolbarPathInfo
ToolBarMerger::FindReferencePoint(
273 const ::rtl::OUString
& rReferencePoint
)
275 ReferenceToolbarPathInfo aResult
;
276 aResult
.bResult
= false;
277 aResult
.pToolbar
= pToolbar
;
278 aResult
.nPos
= TOOLBOX_ITEM_NOTFOUND
;
280 const sal_uInt16
nSize( pToolbar
->GetItemCount() );
282 for ( sal_uInt16 i
= 0; i
< nSize
; i
++ )
284 const sal_uInt16 nItemId
= pToolbar
->GetItemId( i
);
287 const ::rtl::OUString rCmd
= pToolbar
->GetItemCommand( nItemId
);
288 if ( rCmd
== rReferencePoint
)
290 aResult
.bResult
= true;
301 Processes a merge operation.
306 Must be a valid reference to a frame.
311 A valid pointer to the toolbar where the merge
312 operation is applied to.
317 The reference position of the toolbar item for
318 the merge operation. Value must be between
319 0 and number of toolbar items - 1.
329 The current application module context.
337 rMergeCommandParameter.
339 An optional argument for the merge command.
344 Toolbar items which are associated to the merge
348 Returns true for a successful operation otherwise
351 bool ToolBarMerger::ProcessMergeOperation(
352 const uno::Reference
< frame::XFrame
>& xFrame
,
356 CommandToInfoMap
& rCommandMap
,
357 const ::rtl::OUString
& rModuleIdentifier
,
358 const ::rtl::OUString
& rMergeCommand
,
359 const ::rtl::OUString
& rMergeCommandParameter
,
360 const AddonToolbarItemContainer
& rItems
)
362 if ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_ADDAFTER
, MERGECOMMAND_ADDAFTER_LEN
))
363 return MergeItems( xFrame
, pToolbar
, nPos
, 1, rItemId
, rCommandMap
, rModuleIdentifier
, rItems
);
364 else if ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_ADDBEFORE
, MERGECOMMAND_ADDBEFORE_LEN
))
365 return MergeItems( xFrame
, pToolbar
, nPos
, 0, rItemId
, rCommandMap
, rModuleIdentifier
, rItems
);
366 else if ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_REPLACE
, MERGECOMMAND_REPLACE_LEN
))
367 return ReplaceItem( xFrame
, pToolbar
, nPos
, rItemId
, rCommandMap
, rModuleIdentifier
, rItems
);
368 else if ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_REMOVE
, MERGECOMMAND_REMOVE_LEN
))
369 return RemoveItems( pToolbar
, nPos
, rMergeCommandParameter
);
375 Processes a merge fallback operation.
380 Must be a valid reference to a frame.
385 A valid pointer to the toolbar where the merge
386 fall back operation is applied to.
391 The reference position of the toolbar item for
392 the merge operation. Value must be between
393 0 and number of toolbar items - 1.
403 The current application module context.
413 Toolbar items which are associated to the merge
417 Returns true for a successful operation otherwise
420 bool ToolBarMerger::ProcessMergeFallback(
421 const ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
>& xFrame
,
425 CommandToInfoMap
& rCommandMap
,
426 const ::rtl::OUString
& rModuleIdentifier
,
427 const ::rtl::OUString
& rMergeCommand
,
428 const ::rtl::OUString
& rMergeFallback
,
429 const AddonToolbarItemContainer
& rItems
)
431 if (( rMergeFallback
.equalsAsciiL( MERGEFALLBACK_IGNORE
, MERGEFALLBACK_IGNORE_LEN
)) ||
432 ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_REPLACE
, MERGECOMMAND_REPLACE_LEN
)) ||
433 ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_REMOVE
, MERGECOMMAND_REMOVE_LEN
)) )
437 else if (( rMergeCommand
.equalsAsciiL( MERGECOMMAND_ADDBEFORE
, MERGECOMMAND_ADDBEFORE_LEN
)) ||
438 ( rMergeCommand
.equalsAsciiL( MERGECOMMAND_ADDAFTER
, MERGECOMMAND_ADDAFTER_LEN
)) )
440 if ( rMergeFallback
.equalsAsciiL( MERGEFALLBACK_ADDFIRST
, MERGEFALLBACK_ADDFIRST_LEN
))
441 return MergeItems( xFrame
, pToolbar
, 0, 0, rItemId
, rCommandMap
, rModuleIdentifier
, rItems
);
442 else if ( rMergeFallback
.equalsAsciiL( MERGEFALLBACK_ADDLAST
, MERGEFALLBACK_ADDLAST_LEN
))
443 return MergeItems( xFrame
, pToolbar
, TOOLBOX_APPEND
, 0, rItemId
, rCommandMap
, rModuleIdentifier
, rItems
);
450 Merges (adds) toolbar items into an existing toolbar.
455 Must be a valid reference to a frame.
460 A valid pointer to the toolbar where the merge
461 fall back operation is applied to.
466 The reference position of the toolbar item for
467 the merge operation. Value must be between
468 0 and number of toolbar items - 1.
478 The current application module context.
483 Toolbar items which are associated to the merge
487 Returns true for a successful operation otherwise
490 bool ToolBarMerger::MergeItems(
491 const uno::Reference
< frame::XFrame
>& rFrame
,
494 sal_uInt16 nModIndex
,
496 CommandToInfoMap
& rCommandMap
,
497 const ::rtl::OUString
& rModuleIdentifier
,
498 const AddonToolbarItemContainer
& rAddonToolbarItems
)
500 const sal_Int32
nSize( rAddonToolbarItems
.size() );
502 uno::Reference
< frame::XFrame
> xFrame( rFrame
);
504 sal_uInt16
nIndex( 0 );
505 for ( sal_Int32 i
= 0; i
< nSize
; i
++ )
507 const AddonToolbarItem
& rItem
= rAddonToolbarItems
[i
];
508 if ( IsCorrectContext( rItem
.aContext
, rModuleIdentifier
))
510 sal_Int32 nInsPos
= nPos
+nModIndex
+i
;
511 if ( nInsPos
> sal_Int32( pToolbar
->GetItemCount() ))
512 nInsPos
= TOOLBOX_APPEND
;
514 if ( rItem
.aCommandURL
.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR
, TOOLBOXITEM_SEPARATOR_STR_LEN
))
515 pToolbar
->InsertSeparator( sal_uInt16( nInsPos
));
518 ToolBarMerger::CreateToolbarItem( pToolbar
, sal_uInt16( nInsPos
), rItemId
, rItem
);
519 CommandToInfoMap::iterator pIter
= rCommandMap
.find( rItem
.aCommandURL
);
520 if ( pIter
== rCommandMap
.end())
522 CommandInfo aCmdInfo
;
523 aCmdInfo
.nId
= rItemId
;
524 rCommandMap
.insert( CommandToInfoMap::value_type( rItem
.aCommandURL
, aCmdInfo
));
528 pIter
->second
.aIds
.push_back( rItemId
);
541 Replaces a toolbar item with new items for an
547 Must be a valid reference to a frame.
552 A valid pointer to the toolbar where the merge
553 fall back operation is applied to.
558 The reference position of the toolbar item for
559 the merge operation. Value must be between
560 0 and number of toolbar items - 1.
570 The current application module context.
575 Toolbar items which are associated to the merge
579 Returns true for a successful operation otherwise
582 bool ToolBarMerger::ReplaceItem(
583 const uno::Reference
< frame::XFrame
>& xFrame
,
587 CommandToInfoMap
& rCommandMap
,
588 const ::rtl::OUString
& rModuleIdentifier
,
589 const AddonToolbarItemContainer
& rAddonToolbarItems
)
591 pToolbar
->RemoveItem( nPos
);
592 return MergeItems( xFrame
, pToolbar
, nPos
, 0, rItemId
, rCommandMap
, rModuleIdentifier
, rAddonToolbarItems
);
596 Removes toolbar items from an existing toolbar.
601 A valid pointer to the toolbar where the merge
602 fall back operation is applied to.
607 The reference position of the toolbar item for
608 the merge operation. Value must be between
609 0 and number of toolbar items - 1.
612 rMergeCommandParameter.
614 An optional argument for the merge command.
617 Returns true for a successful operation otherwise
620 bool ToolBarMerger::RemoveItems(
623 const ::rtl::OUString
& rMergeCommandParameter
)
625 sal_Int32 nCount
= rMergeCommandParameter
.toInt32();
628 for ( sal_Int32 i
= 0; i
< nCount
; i
++ )
630 if ( nPos
< pToolbar
->GetItemCount() )
631 pToolbar
->RemoveItem( nPos
);
638 Removes toolbar items from an existing toolbar.
643 A valid pointer to the toolbar where the merge
644 fall back operation is applied to.
649 The reference position of the toolbar item for
650 the merge operation. Value must be between
651 0 and number of toolbar items - 1.
654 rMergeCommandParameter.
656 An optional argument for the merge command.
659 Returns true for a successful operation otherwise
662 ::cppu::OWeakObject
* ToolBarMerger::CreateController(
663 uno::Reference
< lang::XMultiServiceFactory
> xSMGR
,
664 uno::Reference
< frame::XFrame
> xFrame
,
666 const ::rtl::OUString
& rCommandURL
,
669 const ::rtl::OUString
& rControlType
)
671 ::cppu::OWeakObject
* pResult( 0 );
673 if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_BUTTON
, TOOLBARCONTROLLER_BUTTON_LEN
))
674 pResult
= new ButtonToolbarController( xSMGR
, pToolbar
, rCommandURL
);
675 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_COMBOBOX
, TOOLBARCONTROLLER_COMBOBOX_LEN
))
676 pResult
= new ComboboxToolbarController( xSMGR
, xFrame
, pToolbar
, nId
, nWidth
, rCommandURL
);
677 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_EDIT
, TOOLBARCONTROLLER_EDIT_LEN
))
678 pResult
= new EditToolbarController( xSMGR
, xFrame
, pToolbar
, nId
, nWidth
, rCommandURL
);
679 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_SPINFIELD
, TOOLBARCONTROLLER_SPINFIELD_LEN
))
680 pResult
= new SpinfieldToolbarController( xSMGR
, xFrame
, pToolbar
, nId
, nWidth
, rCommandURL
);
681 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_IMGBUTTON
, TOOLBARCONTROLLER_IMGBUTTON_LEN
))
682 pResult
= new ImageButtonToolbarController( xSMGR
, xFrame
, pToolbar
, nId
, rCommandURL
);
683 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_DROPDOWNBOX
, TOOLBARCONTROLLER_DROPDOWNBOX_LEN
))
684 pResult
= new DropdownToolbarController( xSMGR
, xFrame
, pToolbar
, nId
, nWidth
, rCommandURL
);
685 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_DROPDOWNBTN
, TOOLBARCONTROLLER_DROPDOWNBTN_LEN
))
686 pResult
= new ToggleButtonToolbarController( xSMGR
, xFrame
, pToolbar
, nId
,
687 ToggleButtonToolbarController::STYLE_DROPDOWNBUTTON
, rCommandURL
);
688 else if ( rControlType
.equalsAsciiL( TOOLBARCONTROLLER_TOGGLEDDBTN
, TOOLBARCONTROLLER_TOGGLEDDBTN_LEN
))
689 pResult
= new ToggleButtonToolbarController( xSMGR
, xFrame
, pToolbar
, nId
,
690 ToggleButtonToolbarController::STYLE_TOGGLE_DROPDOWNBUTTON
, rCommandURL
);
692 pResult
= new GenericToolbarController( xSMGR
, xFrame
, pToolbar
, nId
, rCommandURL
);
697 void ToolBarMerger::CreateToolbarItem( ToolBox
* pToolbar
, sal_uInt16 nPos
, sal_uInt16 nItemId
, const AddonToolbarItem
& rItem
)
699 pToolbar
->InsertItem( nItemId
, rItem
.aLabel
, 0, nPos
);
700 pToolbar
->SetItemCommand( nItemId
, rItem
.aCommandURL
);
701 pToolbar
->SetQuickHelpText( nItemId
, rItem
.aLabel
);
702 pToolbar
->SetItemText( nItemId
, rItem
.aLabel
);
703 pToolbar
->EnableItem( nItemId
, sal_True
);
704 pToolbar
->SetItemState( nItemId
, STATE_NOCHECK
);
706 // Use obsolete help id to transport the width of the item
707 pToolbar
->SetHelpId( nItemId
, rItem
.nWidth
);
709 // Use the user data to store add-on specific data with the toolbar item
710 AddonsParams
* pAddonParams
= new AddonsParams
;
711 pAddonParams
->aImageId
= rItem
.aImageIdentifier
;
712 pAddonParams
->aTarget
= rItem
.aTarget
;
713 pAddonParams
->aControlType
= rItem
.aControlType
;
714 pToolbar
->SetItemData( nItemId
, pAddonParams
);
717 } // namespace framework