Added delete keyinput to listview, fixed reload() issues: solves tdf#138884

*Added delete keyinput to listview.
*Views Buttons set focus to the appropiate widget.
*Fixed listview reload() issues.

Change-Id: I21379fd98b491b0ed56a3997155c7bb49a5c2d3e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108365
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/include/sfx2/listview.hxx b/include/sfx2/listview.hxx
index cb7eb23..4f7e37a 100644
--- a/include/sfx2/listview.hxx
+++ b/include/sfx2/listview.hxx
@@ -53,6 +53,8 @@ public:

    void unselect_all() { mxTreeView->unselect_all(); }

    void grab_focus() { mxTreeView->grab_focus(); }

    void remove(const OUString& rId);

    void rename(const OUString& rId, const OUString& rTitle);
diff --git a/include/sfx2/templatedlglocalview.hxx b/include/sfx2/templatedlglocalview.hxx
index c6caca4..bdae9eb 100644
--- a/include/sfx2/templatedlglocalview.hxx
+++ b/include/sfx2/templatedlglocalview.hxx
@@ -26,6 +26,10 @@ public:

    void showRegion(std::u16string_view rName);

    void reload();

    virtual bool KeyInput(const KeyEvent& rKEvt) override;

    void createContextMenu(const bool bIsDefault, const bool bIsBuiltIn);

    virtual void Show() override;
@@ -56,6 +60,8 @@ private:

    DECL_LINK(PopupMenuHdl, const CommandEvent&, bool);

    DECL_LINK(KeyPressHdl, const KeyEvent&, bool);

    TemplateViewMode mViewMode;
};

diff --git a/sfx2/source/control/templatedlglocalview.cxx b/sfx2/source/control/templatedlglocalview.cxx
index 39b8877..d444ec4 100644
--- a/sfx2/source/control/templatedlglocalview.cxx
+++ b/sfx2/source/control/templatedlglocalview.cxx
@@ -17,6 +17,8 @@
#include <sfx2/strings.hrc>
#include <vcl/commandevent.hxx>
#include <vcl/svapp.hxx>
#include <vcl/event.hxx>
#include <sfx2/doctempl.hxx>

TemplateDlgLocalView::TemplateDlgLocalView(std::unique_ptr<weld::ScrolledWindow> xWindow,
                                           std::unique_ptr<weld::Menu> xMenu,
@@ -29,6 +31,7 @@ TemplateDlgLocalView::TemplateDlgLocalView(std::unique_ptr<weld::ScrolledWindow>
    mxTreeView->connect_column_clicked(LINK(this, ListView, ColumnClickedHdl));
    mxTreeView->connect_changed(LINK(this, TemplateDlgLocalView, ListViewChangedHdl));
    mxTreeView->connect_popup_menu(LINK(this, TemplateDlgLocalView, PopupMenuHdl));
    mxTreeView->connect_key_press(LINK(this, TemplateDlgLocalView, KeyPressHdl));
}

void TemplateDlgLocalView::showAllTemplates()
@@ -63,6 +66,34 @@ void TemplateDlgLocalView::showRegion(std::u16string_view rName)
    }
}

void TemplateDlgLocalView::reload()
{
    mpDocTemplates->Update();

    Populate();

    // Check if we are currently browsing a region or root folder
    if (mnCurRegionId)
    {
        sal_uInt16 nRegionId = mnCurRegionId - 1; //Is offset by 1

        for (auto const& pRegion : maRegions)
        {
            if (pRegion->mnRegionId == nRegionId)
            {
                showRegion(pRegion.get());
                break;
            }
        }
    }
    else
        showAllTemplates();

    //No items should be selected by default
    ThumbnailView::deselectItems();
    ListView::unselect_all();
}

void TemplateDlgLocalView::createContextMenu(const bool bIsDefault, const bool bIsBuiltIn)
{
    mxContextMenu->clear();
@@ -129,11 +160,6 @@ void TemplateDlgLocalView::ContextMenuSelectHdl(std::string_view rIdent)
            return;

        maDeleteTemplateHdl.Call(maSelectedItem);
        // this remove is probably redundant because reload would throw away
        // the old contents anyway. Maybe there is an argument that removing it
        // immediately means there is possibility to show it missing while the
        // possibly slow reload is operating if a repaint could occur
        ListView::remove(OUString::number(maSelectedItem->mnId));
        reload();
    }
    else if (rIdent == "default")
@@ -300,4 +326,75 @@ IMPL_LINK_NOARG(TemplateDlgLocalView, ListViewChangedHdl, weld::TreeView&, void)
    updateSelection();
}

bool TemplateDlgLocalView::KeyInput(const KeyEvent& rKEvt)
{
    vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();

    if (aKeyCode == (KEY_MOD1 | KEY_A))
    {
        for (ThumbnailViewItem* pItem : mFilteredItemList)
        {
            if (!pItem->isSelected())
            {
                pItem->setSelection(true);
                maItemStateHdl.Call(pItem);
            }
        }

        if (IsReallyVisible() && IsUpdateMode())
            Invalidate();
        return true;
    }
    else if (aKeyCode == KEY_DELETE && !mFilteredItemList.empty())
    {
        std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(
            GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo,
            SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
        if (xQueryDlg->run() != RET_YES)
            return true;

        //copy to avoid changing filtered item list during deletion
        ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList;

        for (ThumbnailViewItem* pItem : mFilteredItemListCopy)
        {
            if (pItem->isSelected())
            {
                maDeleteTemplateHdl.Call(pItem);
            }
        }
        reload();
    }

    return ThumbnailView::KeyInput(rKEvt);
}

IMPL_LINK(TemplateDlgLocalView, KeyPressHdl, const KeyEvent&, rKEvt, bool)
{
    vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();

    if (aKeyCode == KEY_DELETE && !mFilteredItemList.empty()
        && !ListView::get_selected_rows().empty())
    {
        std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(
            mxTreeView.get(), VclMessageType::Question, VclButtonsType::YesNo,
            SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
        if (xQueryDlg->run() != RET_YES)
            return true;

        //copy to avoid changing filtered item list during deletion
        ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList;

        for (ThumbnailViewItem* pItem : mFilteredItemListCopy)
        {
            if (pItem->isSelected())
            {
                maDeleteTemplateHdl.Call(pItem);
            }
        }

        reload();
    }
    return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/control/templatesearchview.cxx b/sfx2/source/control/templatesearchview.cxx
index bde9769..941b54c 100644
--- a/sfx2/source/control/templatesearchview.cxx
+++ b/sfx2/source/control/templatesearchview.cxx
@@ -38,6 +38,7 @@ TemplateSearchView::TemplateSearchView(std::unique_ptr<weld::ScrolledWindow> xWi
    mxTreeView->connect_column_clicked(LINK(this, ListView, ColumnClickedHdl));
    mxTreeView->connect_changed(LINK(this, TemplateSearchView, ListViewChangedHdl));
    mxTreeView->connect_popup_menu(LINK(this, TemplateSearchView, PopupMenuHdl));
    mxTreeView->connect_key_press(LINK(this, TemplateSearchView, KeyPressHdl));
}

bool TemplateSearchView::MouseButtonDown( const MouseEvent& rMEvt )
@@ -80,8 +81,8 @@ bool TemplateSearchView::KeyInput( const KeyEvent& rKEvt )
            if (pItem->isSelected())
            {
                maDeleteTemplateHdl.Call(pItem);
                RemoveItem(pItem->mnId);

                ListView::remove(OUString::number(pItem->mnId));
                ThumbnailView::RemoveItem(pItem->mnId);
                CalculateItemPositions();
            }
        }
@@ -175,7 +176,7 @@ void TemplateSearchView::ContextMenuSelectHdl(std::string_view rIdent)

        maDeleteTemplateHdl.Call(maSelectedItem);
        ListView::remove(OUString::number(maSelectedItem->mnId));
        RemoveItem(maSelectedItem->mnId);
        ThumbnailView::RemoveItem(maSelectedItem->mnId);

        CalculateItemPositions();
    }
@@ -428,4 +429,34 @@ void TemplateSearchView::RemoveDefaultTemplateIcon(std::u16string_view rPath)
        }
    }
}

IMPL_LINK(TemplateSearchView, KeyPressHdl, const KeyEvent&, rKEvt, bool)
{
    vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();

    if( aKeyCode == KEY_DELETE && !mFilteredItemList.empty() && !ListView::get_selected_rows().empty())
    {
        std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(mxTreeView.get(), VclMessageType::Question, VclButtonsType::YesNo,
                                                       SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
        if (xQueryDlg->run() != RET_YES)
            return true;

        //copy to avoid changing filtered item list during deletion
        ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList;

        for (ThumbnailViewItem* pItem : mFilteredItemListCopy)
        {
            if (pItem->isSelected())
            {
                maDeleteTemplateHdl.Call(pItem);
                ListView::remove(OUString::number(pItem->mnId));
                ThumbnailView::RemoveItem(pItem->mnId);

                CalculateItemPositions();
            }
        }
    }

    return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/doc/templatedlg.cxx b/sfx2/source/doc/templatedlg.cxx
index afeb5a0..707fcd0 100644
--- a/sfx2/source/doc/templatedlg.cxx
+++ b/sfx2/source/doc/templatedlg.cxx
@@ -822,12 +822,22 @@ IMPL_LINK_NOARG(SfxTemplateManagerDlg, LoseFocusHdl, weld::Widget&, void)
IMPL_LINK_NOARG ( SfxTemplateManagerDlg, ListViewHdl, weld::Button&, void )
{
    setTemplateViewMode(TemplateViewMode::eListView);

    if (mxSearchFilter->get_text().isEmpty())
        mxLocalView->ListView::grab_focus();
    else
        mxSearchView->ListView::grab_focus();
}

IMPL_LINK_NOARG ( SfxTemplateManagerDlg, ThumbnailViewHdl, weld::Button&, void )
{
    setTemplateViewMode(TemplateViewMode::eThumbnailView);
    bMakeSelItemVisible = true;

    if (mxSearchFilter->get_text().isEmpty())
        mxLocalView->ThumbnailView::GrabFocus();
    else
        mxSearchView->ThumbnailView::GrabFocus();
}

IMPL_LINK_NOARG(SfxTemplateManagerDlg, FocusRectLocalHdl, weld::Widget&, tools::Rectangle)
diff --git a/sfx2/source/inc/templatesearchview.hxx b/sfx2/source/inc/templatesearchview.hxx
index 324c97a..e564e03 100644
--- a/sfx2/source/inc/templatesearchview.hxx
+++ b/sfx2/source/inc/templatesearchview.hxx
@@ -80,6 +80,8 @@ private:

    virtual bool KeyInput( const KeyEvent& rKEvt ) override;

    DECL_LINK(KeyPressHdl, const KeyEvent&, bool);

    TemplateViewItem *maSelectedItem;

    Point maPosition;