/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

#include <uielement/toolbarmerger.hxx>
#include <uielement/generictoolbarcontroller.hxx>
#include <helper/imageproducer.hxx>

#include <svtools/miscopt.hxx>

namespace framework
{

static const char MERGE_TOOLBAR_URL[]              = "URL";
static const sal_uInt32 MERGE_TOOLBAR_URL_LEN      = 3;
static const char MERGE_TOOLBAR_TITLE[]            = "Title";
static const sal_uInt32 MERGE_TOOLBAR_TITLE_LEN    = 5;
static const char MERGE_TOOLBAR_IMAGEID[]          = "ImageIdentifier";
static const sal_uInt32 MERGE_TOOLBAR_IMAGEID_LEN  = 15;
static const char MERGE_TOOLBAR_CONTEXT[]          = "Context";
static const sal_uInt32 MERGE_TOOLBAR_CONTEXT_LEN  = 7;
static const char MERGE_TOOLBAR_TARGET[]           = "Target";
static const sal_uInt32 MERGE_TOOLBAR_TARGET_LEN   = 6;
static const char MERGE_TOOLBAR_CONTROLTYPE[]      = "ControlType";
static const char MERGE_TOOLBAR_CONTROLTYPE_LEN    = 11;
static const char MERGE_TOOLBAR_WIDTH[]            = "Width";
static const char MERGE_TOOLBAR_WIDTH_LEN          = 5;

static const char MERGECOMMAND_ADDAFTER[]          = "AddAfter";
static const sal_uInt32 MERGECOMMAND_ADDAFTER_LEN  = 8;
static const char MERGECOMMAND_ADDBEFORE[]         = "AddBefore";
static const sal_uInt32 MERGECOMMAND_ADDBEFORE_LEN = 9;
static const char MERGECOMMAND_REPLACE[]           = "Replace";
static const sal_uInt32 MERGECOMMAND_REPLACE_LEN   = 7;
static const char MERGECOMMAND_REMOVE[]            = "Remove";
static const sal_uInt32 MERGECOMMAND_REMOVE_LEN    = 6;

static const char MERGEFALLBACK_ADDLAST[]          = "AddLast";
static const char MERGEFALLBACK_ADDLAST_LEN        = 7;
static const char MERGEFALLBACK_ADDFIRST[]         = "AddFirst";
static const char MERGEFALLBACK_ADDFIRST_LEN       = 8;
static const char MERGEFALLBACK_IGNORE[]           = "Ignore";
static const char MERGEFALLBACK_IGNORE_LEN         = 6;

static const char TOOLBARCONTROLLER_BUTTON[]              = "Button";
static const sal_uInt32 TOOLBARCONTROLLER_BUTTON_LEN      = 6;
static const char TOOLBARCONTROLLER_COMBOBOX[]            = "Combobox";
static const sal_uInt32 TOOLBARCONTROLLER_COMBOBOX_LEN    = 8;
static const char TOOLBARCONTROLLER_EDIT[]                = "Editfield";
static const sal_uInt32 TOOLBARCONTROLLER_EDIT_LEN        = 9;
static const char TOOLBARCONTROLLER_SPINFIELD[]           = "Spinfield";
static const sal_uInt32 TOOLBARCONTROLLER_SPINFIELD_LEN   = 9;
static const char TOOLBARCONTROLLER_IMGBUTTON[]           = "ImageButton";
static const sal_uInt32 TOOLBARCONTROLLER_IMGBUTTON_LEN   = 11;
static const char TOOLBARCONTROLLER_DROPDOWNBOX[]         = "Dropdownbox";
static const sal_uInt32 TOOLBARCONTROLLER_DROPDOWNBOX_LEN = 11;
static const char TOOLBARCONTROLLER_DROPDOWNBTN[]         = "DropdownButton";
static const sal_uInt32 TOOLBARCONTROLLER_DROPDOWNBTN_LEN = 14;
static const char TOOLBARCONTROLLER_TOGGLEDDBTN[]         = "ToggleDropdownButton";
static const sal_uInt32 TOOLBARCONTROLLER_TOGGLEDDBTN_LEN = 20;

static const char   TOOLBOXITEM_SEPARATOR_STR[]   = "private:separator";
static const USHORT TOOLBOXITEM_SEPARATOR_STR_LEN = sizeof( TOOLBOXITEM_SEPARATOR_STR )-1;

using namespace ::com::sun::star;

/**
 Check whether a module identifier is part of a context
 defined by a colon separated list of module identifier.

 @param
     rContext

     Describes a context string list where all contexts
     are delimited by a colon. For more information about
     the module identifier used as context strings see the
     IDL description of com::sun::star::frame::XModuleManager

 @param
     rModuleIdentifier

     A string describing a module identifier. See IDL
     description of com::sun::star::frame::XModuleManager.

 @result
     The result is true if the rContext is an empty string
     or rModuleIdentifier is part of the context string.

*/
bool ToolBarMerger::IsCorrectContext(
    const ::rtl::OUString& rContext,
    const ::rtl::OUString& rModuleIdentifier )
{
    return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 ));
}

/**
 Converts a sequence, sequence of property values to
 a vector of structs.

 @param
     rSequence

     Provides a sequence, sequence of property values.

 @param
     rContainer

     A vector of AddonToolbarItems which will hold the
     conversion from the rSequence argument.

 @result
     The result is true if the sequence, sequence of property
     values could be converted to a vector of structs.

*/
bool ToolBarMerger::ConvertSeqSeqToVector(
    const uno::Sequence< uno::Sequence< beans::PropertyValue > > rSequence,
    AddonToolbarItemContainer& rContainer )
{
    sal_Int32 nLen( rSequence.getLength() );
    for ( sal_Int32 i = 0; i < nLen; i++ )
    {
        AddonToolbarItem aAddonToolbarItem;
        ConvertSequenceToValues( rSequence[i],
                                 aAddonToolbarItem.aCommandURL,
                                 aAddonToolbarItem.aLabel,
                                 aAddonToolbarItem.aImageIdentifier,
                                 aAddonToolbarItem.aTarget,
                                 aAddonToolbarItem.aContext,
                                 aAddonToolbarItem.aControlType,
                                 aAddonToolbarItem.nWidth );
        rContainer.push_back( aAddonToolbarItem );
    }

    return true;
}

/**
 Converts a sequence of property values to single
 values.

 @param
     rSequence

     Provides a sequence of property values.

 @param
     rCommandURL

     Contains the value of the property with
     Name="CommandURL".

 @param
     rLabel

     Contains the value of the property with
     Name="Title"

 @param
     rImageIdentifier

     Contains the value of the property with
     Name="ImageIdentifier"

 @param
     rTarget

     Contains the value of the property with
     Name="Target"

 @param
     rContext

     Contains the value of the property with
     Name="Context"

 @param
     rControlType

     Contains the value of the property with
     Name="ControlType"

 @result
     All possible mapping between sequence of property
     values and the single values are done.

*/
void ToolBarMerger::ConvertSequenceToValues(
    const uno::Sequence< beans::PropertyValue > rSequence,
    ::rtl::OUString& rCommandURL,
    ::rtl::OUString& rLabel,
    ::rtl::OUString& rImageIdentifier,
    ::rtl::OUString& rTarget,
    ::rtl::OUString& rContext,
    ::rtl::OUString& rControlType,
    sal_uInt16&      rWidth )
{
    for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ )
    {
        if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_URL, MERGE_TOOLBAR_URL_LEN ))
            rSequence[i].Value >>= rCommandURL;
        else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_TITLE, MERGE_TOOLBAR_TITLE_LEN ))
            rSequence[i].Value >>= rLabel;
        else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_IMAGEID, MERGE_TOOLBAR_IMAGEID_LEN ))
            rSequence[i].Value >>= rImageIdentifier;
        else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_CONTEXT, MERGE_TOOLBAR_CONTEXT_LEN ))
            rSequence[i].Value >>= rContext;
        else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_TARGET, MERGE_TOOLBAR_TARGET_LEN ))
            rSequence[i].Value >>= rTarget;
        else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_CONTROLTYPE, MERGE_TOOLBAR_CONTROLTYPE_LEN ))
            rSequence[i].Value >>= rControlType;
        else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_WIDTH, MERGE_TOOLBAR_WIDTH_LEN ))
        {
            sal_Int32 aValue = 0;
            rSequence[i].Value >>= aValue;
            rWidth = sal_uInt16( aValue );
        }
    }
}

/**
 Tries to find the reference point provided and delivers
 position and result of the search process.

 @param
     pToolbar

     Must be a valid pointer to a toolbar with items which
     should be searched.

 @param
     rReferencePoint

     A command URL which should be the reference point for
     the coming merge operation.

 @result
     Provides information about the search result, the
     position of the reference point and the toolbar used.
*/
ReferenceToolbarPathInfo ToolBarMerger::FindReferencePoint(
    ToolBox*               pToolbar,
    const ::rtl::OUString& rReferencePoint )
{
    ReferenceToolbarPathInfo aResult;
    aResult.bResult  = false;
    aResult.pToolbar = pToolbar;
    aResult.nPos     = TOOLBOX_ITEM_NOTFOUND;

    const sal_uInt16 nSize( pToolbar->GetItemCount() );

    for ( sal_uInt16 i = 0; i < nSize; i++ )
    {
        const sal_uInt16 nItemId = pToolbar->GetItemId( i );
        if ( nItemId > 0 )
        {
            const ::rtl::OUString rCmd = pToolbar->GetItemCommand( nItemId );
            if ( rCmd == rReferencePoint )
            {
                aResult.bResult = true;
                aResult.nPos    = i;
                return aResult;
            }
        }
    }

    return aResult;
}

/**
 Processes a merge operation.

 @param
     xFrame

     Must be a valid reference to a frame.

 @param
     pToolbar

     A valid pointer to the toolbar where the merge
     operation is applied to.

 @param
     nPos

     The reference position of the toolbar item for
     the merge operation. Value must be between
     0 and number of toolbar items - 1.

 @param
     rItemId

     A unique item ID.

 @param
     rModuleIdentifier

     The current application module context.

 @param
     rMergeCommand

     A merge command.

 @param
     rMergeCommandParameter.

     An optional argument for the merge command.

 @param
     rItems

     Toolbar items which are associated to the merge
     command.

 @result
     Returns true for a successful operation otherwise
     false.
*/
bool ToolBarMerger::ProcessMergeOperation(
    const uno::Reference< frame::XFrame >& xFrame,
    ToolBox*                               pToolbar,
    sal_uInt16                             nPos,
    sal_uInt16&                            rItemId,
    CommandToInfoMap&                      rCommandMap,
    const ::rtl::OUString&                 rModuleIdentifier,
    const ::rtl::OUString&                 rMergeCommand,
    const ::rtl::OUString&                 rMergeCommandParameter,
    const AddonToolbarItemContainer&       rItems )
{
    if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDAFTER, MERGECOMMAND_ADDAFTER_LEN ))
        return MergeItems( xFrame, pToolbar, nPos, 1, rItemId, rCommandMap, rModuleIdentifier, rItems );
    else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDBEFORE, MERGECOMMAND_ADDBEFORE_LEN ))
        return MergeItems( xFrame, pToolbar, nPos, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
    else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN ))
        return ReplaceItem( xFrame, pToolbar, nPos, rItemId, rCommandMap, rModuleIdentifier, rItems );
    else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN ))
        return RemoveItems( pToolbar, nPos, rMergeCommandParameter );

    return false;
}

/**
 Processes a merge fallback operation.

 @param
     xFrame

     Must be a valid reference to a frame.

 @param
     pToolbar

     A valid pointer to the toolbar where the merge
     fall back operation is applied to.

 @param
     nPos

     The reference position of the toolbar item for
     the merge operation. Value must be between
     0 and number of toolbar items - 1.

 @param
     rItemId

     A unique item ID.

 @param
     rModuleIdentifier

     The current application module context.

 @param
     rMergeCommand

     A merge command.

 @param
     rItems

     Toolbar items which are associated to the merge
     command.

 @result
     Returns true for a successful operation otherwise
     false.
*/
bool ToolBarMerger::ProcessMergeFallback(
    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
    ToolBox*                         pToolbar,
    sal_uInt16                       /*nPos*/,
    sal_uInt16&                      rItemId,
    CommandToInfoMap&                rCommandMap,
    const ::rtl::OUString&           rModuleIdentifier,
    const ::rtl::OUString&           rMergeCommand,
    const ::rtl::OUString&           rMergeFallback,
    const AddonToolbarItemContainer& rItems )
{
    if (( rMergeFallback.equalsAsciiL( MERGEFALLBACK_IGNORE, MERGEFALLBACK_IGNORE_LEN )) ||
        ( rMergeCommand.equalsAsciiL(  MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN )) ||
        ( rMergeCommand.equalsAsciiL(  MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN   )) )
    {
        return true;
    }
    else if (( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDBEFORE, MERGECOMMAND_ADDBEFORE_LEN )) ||
             ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDAFTER, MERGECOMMAND_ADDAFTER_LEN   )) )
    {
        if ( rMergeFallback.equalsAsciiL( MERGEFALLBACK_ADDFIRST, MERGEFALLBACK_ADDFIRST_LEN ))
            return MergeItems( xFrame, pToolbar, 0, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
        else if ( rMergeFallback.equalsAsciiL( MERGEFALLBACK_ADDLAST, MERGEFALLBACK_ADDLAST_LEN ))
            return MergeItems( xFrame, pToolbar, TOOLBOX_APPEND, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
    }

    return false;
}

/**
 Merges (adds) toolbar items into an existing toolbar.

 @param
     xFrame

     Must be a valid reference to a frame.

 @param
     pToolbar

     A valid pointer to the toolbar where the merge
     fall back operation is applied to.

 @param
     nPos

     The reference position of the toolbar item for
     the merge operation. Value must be between
     0 and number of toolbar items - 1.

 @param
     rItemId

     A unique item ID.

 @param
     rModuleIdentifier

     The current application module context.

 @param
     rItems

     Toolbar items which are associated to the merge
     command.

 @result
     Returns true for a successful operation otherwise
     false.
*/
bool ToolBarMerger::MergeItems(
    const uno::Reference< frame::XFrame >& rFrame,
    ToolBox*                               pToolbar,
    sal_uInt16                             nPos,
    sal_uInt16                             nModIndex,
    sal_uInt16&                            rItemId,
    CommandToInfoMap&                      rCommandMap,
    const ::rtl::OUString&                 rModuleIdentifier,
    const AddonToolbarItemContainer&       rAddonToolbarItems )
{
    const sal_Int32 nSize( rAddonToolbarItems.size() );

    uno::Reference< frame::XFrame > xFrame( rFrame );

    sal_uInt16 nIndex( 0 );
    for ( sal_Int32 i = 0; i < nSize; i++ )
    {
        const AddonToolbarItem& rItem = rAddonToolbarItems[i];
        if ( IsCorrectContext( rItem.aContext, rModuleIdentifier ))
        {
            sal_Int32 nInsPos = nPos+nModIndex+i;
            if ( nInsPos > sal_Int32( pToolbar->GetItemCount() ))
                nInsPos = TOOLBOX_APPEND;

            if ( rItem.aCommandURL.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR, TOOLBOXITEM_SEPARATOR_STR_LEN ))
                pToolbar->InsertSeparator( sal_uInt16( nInsPos ));
            else
            {
                ToolBarMerger::CreateToolbarItem( pToolbar, sal_uInt16( nInsPos ), rItemId, rItem );
                CommandToInfoMap::iterator pIter = rCommandMap.find( rItem.aCommandURL );
                if ( pIter == rCommandMap.end())
                {
                    CommandInfo aCmdInfo;
                    aCmdInfo.nId = rItemId;
                    rCommandMap.insert( CommandToInfoMap::value_type( rItem.aCommandURL, aCmdInfo ));
                }
                else
                {
                    pIter->second.aIds.push_back( rItemId );
                }
            }

            ++nIndex;
            ++rItemId;
        }
    }

    return true;
}

/**
 Replaces a toolbar item with new items for an
 existing toolbar.

 @param
     xFrame

     Must be a valid reference to a frame.

 @param
     pToolbar

     A valid pointer to the toolbar where the merge
     fall back operation is applied to.

 @param
     nPos

     The reference position of the toolbar item for
     the merge operation. Value must be between
     0 and number of toolbar items - 1.

 @param
     rItemId

     A unique item ID.

 @param
     rModuleIdentifier

     The current application module context.

 @param
     rItems

     Toolbar items which are associated to the merge
     command.

 @result
     Returns true for a successful operation otherwise
     false.
*/
bool ToolBarMerger::ReplaceItem(
    const uno::Reference< frame::XFrame >& xFrame,
    ToolBox*                               pToolbar,
    sal_uInt16                             nPos,
    sal_uInt16&                            rItemId,
    CommandToInfoMap&                      rCommandMap,
    const ::rtl::OUString&                 rModuleIdentifier,
    const AddonToolbarItemContainer&       rAddonToolbarItems )
{
    pToolbar->RemoveItem( nPos );
    return MergeItems( xFrame, pToolbar, nPos, 0, rItemId, rCommandMap, rModuleIdentifier, rAddonToolbarItems );
}

/**
 Removes toolbar items from an existing toolbar.

 @param
     pToolbar

     A valid pointer to the toolbar where the merge
     fall back operation is applied to.

 @param
     nPos

     The reference position of the toolbar item for
     the merge operation. Value must be between
     0 and number of toolbar items - 1.

 @param
     rMergeCommandParameter.

     An optional argument for the merge command.

 @result
     Returns true for a successful operation otherwise
     false.
*/
bool ToolBarMerger::RemoveItems(
    ToolBox*                  pToolbar,
    sal_uInt16                nPos,
    const ::rtl::OUString&    rMergeCommandParameter )
{
    sal_Int32 nCount = rMergeCommandParameter.toInt32();
    if ( nCount > 0 )
    {
        for ( sal_Int32 i = 0; i < nCount; i++ )
        {
            if ( nPos < pToolbar->GetItemCount() )
                pToolbar->RemoveItem( nPos );
        }
    }
    return true;
}

/**
 Removes toolbar items from an existing toolbar.

 @param
     pToolbar

     A valid pointer to the toolbar where the merge
     fall back operation is applied to.

 @param
     nPos

     The reference position of the toolbar item for
     the merge operation. Value must be between
     0 and number of toolbar items - 1.

 @param
     rMergeCommandParameter.

     An optional argument for the merge command.

 @result
     Returns true for a successful operation otherwise
     false.
*/
::cppu::OWeakObject* ToolBarMerger::CreateController(
    uno::Reference< lang::XMultiServiceFactory > xSMGR,
    uno::Reference< frame::XFrame > xFrame,
    ToolBox*               pToolbar,
    const ::rtl::OUString& rCommandURL,
    sal_uInt16             nId,
    sal_uInt16             nWidth,
    const ::rtl::OUString& rControlType )
{
    ::cppu::OWeakObject* pResult( 0 );

    if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_BUTTON, TOOLBARCONTROLLER_BUTTON_LEN ))
        pResult = new ButtonToolbarController( xSMGR, pToolbar, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_COMBOBOX, TOOLBARCONTROLLER_COMBOBOX_LEN ))
        pResult = new ComboboxToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_EDIT, TOOLBARCONTROLLER_EDIT_LEN ))
        pResult = new EditToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_SPINFIELD, TOOLBARCONTROLLER_SPINFIELD_LEN ))
        pResult = new SpinfieldToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_IMGBUTTON, TOOLBARCONTROLLER_IMGBUTTON_LEN ))
        pResult = new ImageButtonToolbarController( xSMGR, xFrame, pToolbar, nId, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_DROPDOWNBOX, TOOLBARCONTROLLER_DROPDOWNBOX_LEN ))
        pResult = new DropdownToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_DROPDOWNBTN, TOOLBARCONTROLLER_DROPDOWNBTN_LEN ))
        pResult = new ToggleButtonToolbarController( xSMGR, xFrame, pToolbar, nId,
                                                     ToggleButtonToolbarController::STYLE_DROPDOWNBUTTON, rCommandURL );
    else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_TOGGLEDDBTN, TOOLBARCONTROLLER_TOGGLEDDBTN_LEN ))
        pResult = new ToggleButtonToolbarController( xSMGR, xFrame, pToolbar, nId,
                                                     ToggleButtonToolbarController::STYLE_TOGGLE_DROPDOWNBUTTON, rCommandURL );
    else
        pResult = new GenericToolbarController( xSMGR, xFrame, pToolbar, nId, rCommandURL );

    return pResult;
}

void ToolBarMerger::CreateToolbarItem( ToolBox* pToolbar, sal_uInt16 nPos, sal_uInt16 nItemId, const AddonToolbarItem& rItem )
{
    pToolbar->InsertItem( nItemId, rItem.aLabel, 0, nPos );
    pToolbar->SetItemCommand( nItemId, rItem.aCommandURL );
    pToolbar->SetQuickHelpText( nItemId, rItem.aLabel );
    pToolbar->SetItemText( nItemId, rItem.aLabel );
    pToolbar->EnableItem( nItemId, sal_True );
    pToolbar->SetItemState( nItemId, STATE_NOCHECK );

    // Use obsolete help id to transport the width of the item
    pToolbar->SetHelpId( nItemId, rItem.nWidth );

    // Use the user data to store add-on specific data with the toolbar item
    AddonsParams* pAddonParams = new AddonsParams;
    pAddonParams->aImageId     = rItem.aImageIdentifier;
    pAddonParams->aTarget      = rItem.aTarget;
    pAddonParams->aControlType = rItem.aControlType;
    pToolbar->SetItemData( nItemId, pAddonParams );
}

} // namespace framework

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
