Make the Modify button functional in the Customize dialog

By adding "rename", "change icon", "reset icon", and "restore default command"
options to the Modify button at the bottom of the right (toolbar/menu
entries) list.

Change icon / Reset icon / Restore default command options are not
supported in the menu/context menu tabs yet.

Change-Id: Iade3d1aca722c7f8eddcadf251b9562c5366d8ad
Reviewed-on: https://gerrit.libreoffice.org/41620
Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
Tested-by: Katarina Behrens <Katarina.Behrens@cib.de>
diff --git a/cui/source/customize/SvxMenuConfigPage.cxx b/cui/source/customize/SvxMenuConfigPage.cxx
index 336e6bb..0161411 100644
--- a/cui/source/customize/SvxMenuConfigPage.cxx
+++ b/cui/source/customize/SvxMenuConfigPage.cxx
@@ -135,9 +135,18 @@ SvxMenuConfigPage::SvxMenuConfigPage(vcl::Window *pParent, const SfxItemSet& rSe

    m_pInsertBtn->SetSelectHdl(
        LINK( this, SvxMenuConfigPage, InsertHdl ) );
    m_pModifyBtn->SetSelectHdl(
        LINK( this, SvxMenuConfigPage, ModifyItemHdl ) );
    m_pResetBtn->SetClickHdl(
        LINK( this, SvxMenuConfigPage, ResetMenuHdl ) );

    PopupMenu* pPopup = m_pModifyBtn->GetPopupMenu();
    // These operations are not possible on menus/context menus yet
    pPopup->EnableItem( pPopup->GetItemId("changeIcon"), false );
    pPopup->EnableItem( pPopup->GetItemId("resetIcon"), false );
    pPopup->EnableItem( pPopup->GetItemId("restoreItem"), false );
    pPopup->RemoveDisabledEntries();

    if ( !bIsMenuBar )
    {
        // Context menus cannot be added/removed
@@ -149,7 +158,6 @@ SvxMenuConfigPage::SvxMenuConfigPage(vcl::Window *pParent, const SfxItemSet& rSe
        // TODO: Remove this when it is possible to reset menubar menus individually
        m_pResetBtn->Disable();
    }

}

SvxMenuConfigPage::~SvxMenuConfigPage()
@@ -197,19 +205,19 @@ void SvxMenuConfigPage::UpdateButtonStates()
    // Disable Up and Down buttons depending on current selection
    SvTreeListEntry* selection = m_pContentsListBox->GetCurEntry();

    if ( m_pContentsListBox->GetEntryCount() == 0 || selection == nullptr )
    {
        m_pMoveUpButton->Enable( false );
        m_pMoveDownButton->Enable( false );
    bool  bIsSeparator =
        selection && (static_cast<SvxConfigEntry*>(selection->GetUserData()))->IsSeparator();
    bool bIsValidSelection =
        !(m_pContentsListBox->GetEntryCount() == 0 || selection == nullptr);

        return;
    }
    m_pMoveUpButton->Enable(
        bIsValidSelection &&  selection != m_pContentsListBox->First() );
    m_pMoveDownButton->Enable(
        bIsValidSelection && selection != m_pContentsListBox->Last() );

    SvTreeListEntry* first = m_pContentsListBox->First();
    SvTreeListEntry* last = m_pContentsListBox->Last();
    m_pRemoveCommandButton->Enable( bIsValidSelection );

    m_pMoveUpButton->Enable( selection != first );
    m_pMoveDownButton->Enable( selection != last );
    m_pModifyBtn->Enable( bIsValidSelection && !bIsSeparator);
}

void SvxMenuConfigPage::DeleteSelectedTopLevel()
@@ -386,6 +394,49 @@ IMPL_LINK( SvxMenuConfigPage, InsertHdl, MenuButton *, pButton, void )
    }
}

IMPL_LINK( SvxMenuConfigPage, ModifyItemHdl, MenuButton *, pButton, void )
{
    OString sIdent = pButton->GetCurItemIdent();

    SAL_WARN("cui.customize", "sIdent: " << sIdent);

    if (sIdent == "renameItem")
    {
        SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
        SvxConfigEntry* pEntry =
            static_cast<SvxConfigEntry*>(pActEntry->GetUserData());

        OUString aNewName( SvxConfigPageHelper::stripHotKey( pEntry->GetName() ) );
        OUString aDesc = CuiResId( RID_SVXSTR_LABEL_NEW_NAME );

        VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
        pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU_ITEM );
        pNameDialog->SetText( CuiResId( RID_SVXSTR_RENAME_MENU ) );

        if ( pNameDialog->Execute() == RET_OK )
        {
            pNameDialog->GetName( aNewName );

            pEntry->SetName( aNewName );
            m_pContentsListBox->SetEntryText( pActEntry, aNewName );

            GetSaveInData()->SetModified();
            GetTopLevelSelection()->SetModified();
        }
    }
    else
    {
        //This block should never be reached
        SAL_WARN("cui.customize", "Unknown insert option: " << sIdent);
        return;
    }

    if ( GetSaveInData()->IsModified() )
    {
        UpdateButtonStates();
    }
}

IMPL_LINK_NOARG( SvxMenuConfigPage, ResetMenuHdl, Button *, void )
{
    SvxConfigEntry* pMenuData = GetTopLevelSelection();
diff --git a/cui/source/customize/SvxToolbarConfigPage.cxx b/cui/source/customize/SvxToolbarConfigPage.cxx
index f9c700c..5446c67 100644
--- a/cui/source/customize/SvxToolbarConfigPage.cxx
+++ b/cui/source/customize/SvxToolbarConfigPage.cxx
@@ -145,6 +145,8 @@ SvxToolbarConfigPage::SvxToolbarConfigPage(vcl::Window *pParent, const SfxItemSe

    m_pInsertBtn->SetSelectHdl(
        LINK( this, SvxToolbarConfigPage, InsertHdl ) );
    m_pModifyBtn->SetSelectHdl(
        LINK( this, SvxToolbarConfigPage, ModifyItemHdl ) );
    m_pResetBtn->SetClickHdl(
        LINK( this, SvxToolbarConfigPage, ResetToolbarHdl ) );

@@ -454,6 +456,226 @@ IMPL_LINK( SvxToolbarConfigPage, InsertHdl, MenuButton *, pButton, void )
    }
}

IMPL_LINK( SvxToolbarConfigPage, ModifyItemHdl, MenuButton *, pButton, void )
{
    bool bNeedsApply = false;

    // get currently selected toolbar
    SvxConfigEntry* pToolbar = GetTopLevelSelection();

    OString sIdent = pButton->GetCurItemIdent();

    if (sIdent == "renameItem")
    {
        SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
        SvxConfigEntry* pEntry =
            static_cast<SvxConfigEntry*>(pActEntry->GetUserData());

        OUString aNewName( SvxConfigPageHelper::stripHotKey( pEntry->GetName() ) );
        OUString aDesc = CuiResId( RID_SVXSTR_LABEL_NEW_NAME );

        VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
        pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM );
        pNameDialog->SetText( CuiResId( RID_SVXSTR_RENAME_TOOLBAR ) );

        if ( pNameDialog->Execute() == RET_OK )
        {
            pNameDialog->GetName(aNewName);

            if( aNewName.isEmpty() )    // tdf#80758 - Accelerator character ("~") is passed as
                pEntry->SetName( "~" ); // the button name in case of empty values.
            else
                pEntry->SetName( aNewName );

            m_pContentsListBox->SetEntryText( pActEntry, aNewName );
            bNeedsApply = true;
        }
    }
    else if (sIdent == "changeIcon")
    {
        SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
        SvxConfigEntry* pEntry =
            static_cast<SvxConfigEntry*>(pActEntry->GetUserData());

        // Position of entry within the list
        // TODO: Add a GetSelectionPos() method to the SvTreeListBox class
        sal_uInt16 nSelectionPos = m_pContentsListBox->GetModel()->GetAbsPos( pActEntry );

        ScopedVclPtr<SvxIconSelectorDialog> pIconDialog(
            VclPtr<SvxIconSelectorDialog>::Create( nullptr,
                GetSaveInData()->GetImageManager(),
                GetSaveInData()->GetParentImageManager() ));

        if ( pIconDialog->Execute() == RET_OK )
        {
            css::uno::Reference< css::graphic::XGraphic > newgraphic =
                pIconDialog->GetSelectedIcon();

            if ( newgraphic.is() )
            {
                css::uno::Sequence< css::uno::Reference< css::graphic::XGraphic > >
                    aGraphicSeq( 1 );

                css::uno::Sequence<OUString> aURLSeq { pEntry->GetCommand() };

                if ( !pEntry->GetBackupGraphic().is() )
                {
                    css::uno::Reference< css::graphic::XGraphic > backup;
                    backup = SvxConfigPageHelper::GetGraphic(
                        GetSaveInData()->GetImageManager(), aURLSeq[ 0 ] );

                    if ( backup.is() )
                    {
                        pEntry->SetBackupGraphic( backup );
                    }
                }

                aGraphicSeq[ 0 ] = newgraphic;
                try
                {
                    GetSaveInData()->GetImageManager()->replaceImages(
                        SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq );

                    m_pContentsListBox->GetModel()->Remove( pActEntry );
                    SvTreeListEntry* pNewLBEntry =
                        InsertEntryIntoUI( pEntry, nSelectionPos );

                    m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
                        pEntry->IsVisible() ?
                        SvButtonState::Checked : SvButtonState::Unchecked );

                    m_pContentsListBox->Select( pNewLBEntry );
                    m_pContentsListBox->MakeVisible( pNewLBEntry );

                    GetSaveInData()->PersistChanges(
                        GetSaveInData()->GetImageManager() );
                }
                catch ( css::uno::Exception& e)
                {
                    SAL_WARN("cui.customize", "Error replacing image: " << e.Message);
                }
            }
        }
    }
    else if (sIdent == "resetIcon")
    {
        SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
        SvxConfigEntry* pEntry =
            static_cast<SvxConfigEntry*>(pActEntry->GetUserData());

        // Position of entry within the list
        // TODO: Add a GetSelectionPos() method to the SvTreeListBox class
        sal_uInt16 nSelectionPos = m_pContentsListBox->GetModel()->GetAbsPos( pActEntry );

        css::uno::Reference< css::graphic::XGraphic > backup =
            pEntry->GetBackupGraphic();

        css::uno::Sequence< css::uno::Reference< css::graphic::XGraphic > >
            aGraphicSeq( 1 );
        aGraphicSeq[ 0 ] = backup;

        css::uno::Sequence<OUString> aURLSeq { pEntry->GetCommand() };

        try
        {
            GetSaveInData()->GetImageManager()->replaceImages(
                SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq );

            m_pContentsListBox->GetModel()->Remove( pActEntry );

            SvTreeListEntry* pNewLBEntry =
                InsertEntryIntoUI( pEntry, nSelectionPos );

            m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
                pEntry->IsVisible() ?
                    SvButtonState::Checked : SvButtonState::Unchecked );

            m_pContentsListBox->Select( pNewLBEntry );
            m_pContentsListBox->MakeVisible( pNewLBEntry );

            // reset backup in entry
            pEntry->SetBackupGraphic(
                css::uno::Reference< css::graphic::XGraphic >() );

            GetSaveInData()->PersistChanges(
                GetSaveInData()->GetImageManager() );
        }
        catch ( css::uno::Exception& e )
        {
            SAL_WARN("cui.customize", "Error resetting image: " << e.Message);
        }
    }
    else if (sIdent == "restoreItem")
    {
        SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
        SvxConfigEntry* pEntry =
            static_cast<SvxConfigEntry*>(pActEntry->GetUserData());

        // Position of entry within the list
        // TODO: Add a GetSelectionPos() method to the SvTreeListBox class
        sal_uInt16 nSelectionPos = m_pContentsListBox->GetModel()->GetAbsPos( pActEntry );

        ToolbarSaveInData* pSaveInData =
            static_cast<ToolbarSaveInData*>( GetSaveInData() );

        OUString aSystemName =
            pSaveInData->GetSystemUIName( pEntry->GetCommand() );

        if ( !pEntry->GetName().equals( aSystemName ) )
        {
            pEntry->SetName( aSystemName );
            m_pContentsListBox->SetEntryText(
                pActEntry, SvxConfigPageHelper::stripHotKey( aSystemName ) );
            bNeedsApply = true;
        }

        css::uno::Sequence<OUString> aURLSeq { pEntry->GetCommand() };

        try
        {
            GetSaveInData()->GetImageManager()->removeImages(
                SvxConfigPageHelper::GetImageType(), aURLSeq );

            // reset backup in entry
            pEntry->SetBackupGraphic(
                css::uno::Reference< css::graphic::XGraphic >() );

            GetSaveInData()->PersistChanges(
                GetSaveInData()->GetImageManager() );

            m_pContentsListBox->RemoveEntry( pActEntry );

            SvTreeListEntry* pNewLBEntry =
                InsertEntryIntoUI( pEntry, nSelectionPos );

            m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
                pEntry->IsVisible() ?
                    SvButtonState::Checked : SvButtonState::Unchecked );

            m_pContentsListBox->Select( pNewLBEntry );
            m_pContentsListBox->MakeVisible( pNewLBEntry );

            bNeedsApply = true;
        }
        catch ( css::uno::Exception& e )
        {
            SAL_WARN("cui.customize", "Error restoring image: " << e.Message);
        }
    }
    else
    {
        //This block should never be reached
        SAL_WARN("cui.customize", "Unknown insert option: " << sIdent);
        return;
    }

    if ( bNeedsApply )
    {
        static_cast<ToolbarSaveInData*>( GetSaveInData())->ApplyToolbar( pToolbar );
        UpdateButtonStates();
    }
}

IMPL_LINK_NOARG( SvxToolbarConfigPage, ResetToolbarHdl, Button *, void )
{
    sal_Int32 nSelectionPos = m_pTopLevelListBox->GetSelectEntryPos();
@@ -477,19 +699,19 @@ IMPL_LINK_NOARG( SvxToolbarConfigPage, ResetToolbarHdl, Button *, void )

void SvxToolbarConfigPage::UpdateButtonStates()
{
    m_pDescriptionField->SetText("");

    SvTreeListEntry* selection = m_pContentsListBox->GetCurEntry();
    if ( m_pContentsListBox->GetEntryCount() == 0 || selection == nullptr )
    {
        return;
    }

    SvxConfigEntry* pEntryData = static_cast<SvxConfigEntry*>(selection->GetUserData());
    if ( !pEntryData->IsSeparator() )
    {
        m_pDescriptionField->SetText(pEntryData->GetHelpText());
    }
    bool  bIsSeparator =
        selection && (static_cast<SvxConfigEntry*>(selection->GetUserData()))->IsSeparator();
    bool bIsValidSelection =
        !(m_pContentsListBox->GetEntryCount() == 0 || selection == nullptr);

    m_pMoveUpButton->Enable( bIsValidSelection );
    m_pMoveDownButton->Enable( bIsValidSelection );

    m_pRemoveCommandButton->Enable( bIsValidSelection );

    m_pModifyBtn->Enable( bIsValidSelection && !bIsSeparator );
}

short SvxToolbarConfigPage::QueryReset()
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
index d946329..efb488f 100644
--- a/cui/source/customize/cfg.cxx
+++ b/cui/source/customize/cfg.cxx
@@ -1163,6 +1163,7 @@ SvxConfigPage::SvxConfigPage(vcl::Window *pParent, const SfxItemSet& rSet)
    get(m_pMoveDownButton, "down");
    get(m_pSaveInListBox, "savein");
    get(m_pInsertBtn, "insert");
    get(m_pModifyBtn, "modify");
    get(m_pResetBtn, "resetbtn");
    get(m_pDescriptionField, "desc");
    m_pDescriptionField->set_height_request(m_pDescriptionField->GetTextHeight()*4);
@@ -1204,6 +1205,7 @@ void SvxConfigPage::dispose()
    m_pMoveDownButton.clear();
    m_pSaveInListBox.clear();
    m_pInsertBtn.clear();
    m_pModifyBtn.clear();
    m_pResetBtn.clear();
    m_pDescriptionField.clear();

diff --git a/cui/source/inc/SvxMenuConfigPage.hxx b/cui/source/inc/SvxMenuConfigPage.hxx
index f0b0bca..3763dca 100644
--- a/cui/source/inc/SvxMenuConfigPage.hxx
+++ b/cui/source/inc/SvxMenuConfigPage.hxx
@@ -63,6 +63,7 @@ private:
    DECL_LINK( RemoveCommandHdl, Button *, void );

    DECL_LINK( InsertHdl, MenuButton *, void );
    DECL_LINK( ModifyItemHdl, MenuButton *, void );
    DECL_LINK( ResetMenuHdl, Button *, void );

    void            Init() override;
diff --git a/cui/source/inc/SvxToolbarConfigPage.hxx b/cui/source/inc/SvxToolbarConfigPage.hxx
index 07cae0d..7426fb2 100644
--- a/cui/source/inc/SvxToolbarConfigPage.hxx
+++ b/cui/source/inc/SvxToolbarConfigPage.hxx
@@ -64,6 +64,7 @@ private:
    DECL_LINK( RemoveCommandHdl, Button *, void );

    DECL_LINK( InsertHdl, MenuButton *, void );
    DECL_LINK( ModifyItemHdl, MenuButton *, void );
    DECL_LINK( ResetToolbarHdl, Button *, void );

    void            UpdateButtonStates() override;
diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx
index f8b397b..06b2c4d 100644
--- a/cui/source/inc/cfg.hxx
+++ b/cui/source/inc/cfg.hxx
@@ -409,6 +409,7 @@ protected:
    VclPtr<ListBox>                            m_pSaveInListBox;

    VclPtr<MenuButton>                         m_pInsertBtn;
    VclPtr<MenuButton>                         m_pModifyBtn;
    // Used to reset the selected toolbar/menu/context menu
    VclPtr<PushButton>                         m_pResetBtn;

diff --git a/cui/uiconfig/ui/menuassignpage.ui b/cui/uiconfig/ui/menuassignpage.ui
index 571cc2c..928e78d 100644
--- a/cui/uiconfig/ui/menuassignpage.ui
+++ b/cui/uiconfig/ui/menuassignpage.ui
@@ -166,7 +166,7 @@
                          </packing>
                        </child>
                        <child>
                          <object class="GtkButton">
                          <object class="GtkButton" id="modify:modifymenu">
                            <property name="label" translatable="yes">Modify</property>
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
@@ -576,6 +576,42 @@
      </object>
    </child>
  </object>
  <object class="GtkMenu" id="modifymenu">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkMenuItem" id="renameItem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Rename...</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="changeIcon">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Change Icon...</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="resetIcon">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Reset Icon</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="restoreItem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Restore Default Command</property>
        <property name="use_underline">True</property>
      </object>
    </child>
  </object>
  <object class="GtkSizeGroup" id="sizegroup1"/>
  <object class="GtkSizeGroup" id="sizegroup2"/>
</interface>