Resolves tdf#80934 - GUI means to filter thumbnails in start center

Resolves also tdf#92499 by removing the (badly placed) context menus
from the left pane into the new "toolbar"

Change-Id: I8e15d30380d4d915ed109877d716e1a4689885c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139730
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
diff --git a/sfx2/inc/recentdocsview.hxx b/sfx2/inc/recentdocsview.hxx
index 44165af..119bf6e 100644
--- a/sfx2/inc/recentdocsview.hxx
+++ b/sfx2/inc/recentdocsview.hxx
@@ -82,6 +82,8 @@ public:

    void clearUnavailableFiles();

    void setFilter(ApplicationType aFilter);

private:
    virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override;

diff --git a/sfx2/source/control/recentdocsview.cxx b/sfx2/source/control/recentdocsview.cxx
index 61b9b55..c7c9efe 100644
--- a/sfx2/source/control/recentdocsview.cxx
+++ b/sfx2/source/control/recentdocsview.cxx
@@ -161,7 +161,8 @@ void RecentDocsView::Reload()
        OUString aURL = rRecentEntry.sURL;
        const INetURLObject aURLObj(aURL);

        if (!isAcceptedFile(aURLObj))
        if ((mnFileTypes != ApplicationType::TYPE_NONE) &&
            (!isAcceptedFile(aURLObj)))
            continue;

        //Remove extension from url's last segment and use it as title
@@ -174,6 +175,12 @@ void RecentDocsView::Reload()
    Invalidate();
}

void RecentDocsView::setFilter(ApplicationType aFilter)
{
    mnFileTypes = aFilter;
    Reload();
}

void RecentDocsView::clearUnavailableFiles(){
    std::vector< SvtHistoryOptions::HistoryItem > aHistoryList = SvtHistoryOptions::GetList( EHistoryType::PickList );
    for ( size_t i = 0; i < aHistoryList.size(); i++ )
diff --git a/sfx2/source/dialog/backingwindow.cxx b/sfx2/source/dialog/backingwindow.cxx
index 6b68370..a19529f 100644
--- a/sfx2/source/dialog/backingwindow.cxx
+++ b/sfx2/source/dialog/backingwindow.cxx
@@ -143,11 +143,13 @@ float const g_fMultiplier = 1.2f;
BackingWindow::BackingWindow(vcl::Window* i_pParent)
    : InterimItemWindow(i_pParent, "sfx/ui/startcenter.ui", "StartCenter", false)
    , mxOpenButton(m_xBuilder->weld_button("open_all"))
    , mxRecentButton(m_xBuilder->weld_menu_toggle_button("open_recent"))
    , mxRecentButton(m_xBuilder->weld_toggle_button("open_recent"))
    , mxRemoteButton(m_xBuilder->weld_button("open_remote"))
    , mxTemplateButton(m_xBuilder->weld_menu_toggle_button("templates_all"))
    , mxTemplateButton(m_xBuilder->weld_toggle_button("templates_all"))
    , mxCreateLabel(m_xBuilder->weld_label("create_label"))
    , mxAltHelpLabel(m_xBuilder->weld_label("althelplabel"))
    , mxFilter(m_xBuilder->weld_combo_box("cbFilter"))
    , mxActions(m_xBuilder->weld_menu_button("mbActions"))
    , mxWriterAllButton(m_xBuilder->weld_button("writer_all"))
    , mxCalcAllButton(m_xBuilder->weld_button("calc_all"))
    , mxImpressAllButton(m_xBuilder->weld_button("impress_all"))
@@ -174,6 +176,10 @@ BackingWindow::BackingWindow(vcl::Window* i_pParent)
    SetPaintTransparent(false);
    SetBackground(svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor);

    // square action button
    auto nHeight = mxFilter->get_preferred_size().getHeight();
    mxActions->set_size_request(nHeight, nHeight);

    //set an alternative help label that doesn't hotkey the H of the Help menu
    mxHelpButton->set_label(mxAltHelpLabel->get_label());
    mxHelpButton->connect_clicked(LINK(this, BackingWindow, ClickHelpHdl));
@@ -227,6 +233,8 @@ void BackingWindow::dispose()
    mxTemplateButton.reset();
    mxCreateLabel.reset();
    mxAltHelpLabel.reset();
    mxFilter.reset();
    mxActions.reset();
    mxWriterAllButton.reset();
    mxCalcAllButton.reset();
    mxImpressAllButton.reset();
@@ -278,11 +286,12 @@ void BackingWindow::initControls()
    mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_OTHER;
    mxAllRecentThumbnails->Reload();
    mxAllRecentThumbnails->ShowTooltips( true );
    mxRecentButton->set_active(true);
    mxRecentButton->grab_focus();
    mxAllRecentThumbnails->GrabFocus();
    mxRecentButton->set_highlight_background();

    //initialize Template view
    mxLocalView->Hide();
    mxActions->set_sensitive(true);

    //set handlers
    mxLocalView->setCreateContextMenuHdl(LINK(this, BackingWindow, CreateContextMenuHdl));
@@ -296,8 +305,6 @@ void BackingWindow::initControls()

    mxOpenButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxRemoteButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxRecentButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxTemplateButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxWriterAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxDrawAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxCalcAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
@@ -305,8 +312,11 @@ void BackingWindow::initControls()
    mxImpressAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));
    mxMathAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl));

    mxRecentButton->connect_selected(LINK(this, BackingWindow, MenuSelectHdl));
    mxTemplateButton->connect_selected(LINK(this, BackingWindow, MenuSelectHdl));
    mxRecentButton->connect_toggled(LINK(this, BackingWindow, ToggleHdl));
    mxTemplateButton->connect_toggled(LINK(this, BackingWindow, ToggleHdl));

    mxFilter->connect_changed(LINK(this, BackingWindow, FilterHdl));
    mxActions->connect_selected(LINK(this, BackingWindow, MenuSelectHdl));

    ApplyStyleSettings();
}
@@ -547,6 +557,55 @@ IMPL_LINK(BackingWindow, ExtLinkClickHdl, weld::Button&, rButton, void)
    }
}

void BackingWindow::applyFilter()
{
    const int nFilter = mxFilter->get_active();
    if (mxLocalView->IsVisible())
    {
        FILTER_APPLICATION aFilter = static_cast<FILTER_APPLICATION>(nFilter);
        mxLocalView->filterItems(ViewFilter_Application(aFilter));
    }
    else
    {
        sfx2::ApplicationType aFilter;
        if (nFilter == 0)
            aFilter = sfx2::ApplicationType::TYPE_NONE;
        else
            aFilter = static_cast<sfx2::ApplicationType>(1 << (nFilter - 1));
        mxAllRecentThumbnails->setFilter(aFilter);
    }
}

IMPL_LINK_NOARG( BackingWindow, FilterHdl, weld::ComboBox&, void )
{
    applyFilter();
}

IMPL_LINK( BackingWindow, ToggleHdl, weld::Toggleable&, rButton, void )
{
    if( &rButton == mxRecentButton.get() )
    {
        mxLocalView->Hide();
        mxAllRecentThumbnails->Show();
        mxAllRecentThumbnails->GrabFocus();
        mxRecentButton->set_highlight_background();
        mxTemplateButton->set_stack_background();
        mxActions->set_sensitive(true);
    }
    else if( &rButton == mxTemplateButton.get() )
    {
        mxAllRecentThumbnails->Hide();
        initializeLocalView();
        mxLocalView->Show();
        mxLocalView->reload();
        mxLocalView->GrabFocus();
        mxTemplateButton->set_highlight_background();
        mxRecentButton->set_stack_background();
        mxActions->set_sensitive(false);
    }
    applyFilter();
}

IMPL_LINK( BackingWindow, ClickHdl, weld::Button&, rButton, void )
{
    // dispatch the appropriate URL and end the dialog
@@ -574,25 +633,6 @@ IMPL_LINK( BackingWindow, ClickHdl, weld::Button&, rButton, void )

        dispatchURL( ".uno:OpenRemote", OUString(), xFrame, {} );
    }
    else if( &rButton == mxRecentButton.get() )
    {
        mxLocalView->Hide();
        mxAllRecentThumbnails->Show();
        mxAllRecentThumbnails->GrabFocus();
        mxRecentButton->set_active(true);
        mxTemplateButton->set_active(false);
    }
    else if( &rButton == mxTemplateButton.get() )
    {
        mxAllRecentThumbnails->Hide();
        initializeLocalView();
        mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE));
        mxLocalView->Show();
        mxLocalView->reload();
        mxLocalView->GrabFocus();
        mxRecentButton->set_active(false);
        mxTemplateButton->set_active(true);
    }
}

IMPL_LINK (BackingWindow, MenuSelectHdl, const OString&, rId, void)
@@ -603,43 +643,9 @@ IMPL_LINK (BackingWindow, MenuSelectHdl, const OString&, rId, void)
        mxAllRecentThumbnails->Reload();
        return;
    }
    else if(rId == "clear_unavailable"){
        mxAllRecentThumbnails->clearUnavailableFiles();
    }
    else if (!rId.isEmpty())
    else if(rId == "clear_unavailable")
    {
        initializeLocalView();

        if( rId == "filter_writer" )
        {
            mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::WRITER));
        }
        else if( rId == "filter_calc" )
        {
            mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::CALC));
        }
        else if( rId == "filter_impress" )
        {
            mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::IMPRESS));
        }
        else if( rId == "filter_draw" )
        {
            mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::DRAW));
        }
        else if( rId == "manage" )
        {
            Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );

            dispatchURL( ".uno:NewDoc", OUString(), xFrame, { comphelper::makePropertyValue("Referer", OUString("private:user")) } );
            return;
        }

        mxAllRecentThumbnails->Hide();
        mxLocalView->Show();
        mxLocalView->reload();
        mxLocalView->GrabFocus();
        mxRecentButton->set_active(false);
        mxTemplateButton->set_active(true);
        mxAllRecentThumbnails->clearUnavailableFiles();
    }
}

diff --git a/sfx2/source/dialog/backingwindow.hxx b/sfx2/source/dialog/backingwindow.hxx
index 358055c..2bd2e04 100644
--- a/sfx2/source/dialog/backingwindow.hxx
+++ b/sfx2/source/dialog/backingwindow.hxx
@@ -48,12 +48,14 @@ class BackingWindow : public InterimItemWindow
    css::uno::Reference<css::datatransfer::dnd::XDropTargetListener> mxDropTargetListener;

    std::unique_ptr<weld::Button> mxOpenButton;
    std::unique_ptr<weld::MenuToggleButton> mxRecentButton;
    std::unique_ptr<weld::ToggleButton> mxRecentButton;
    std::unique_ptr<weld::Button> mxRemoteButton;
    std::unique_ptr<weld::MenuToggleButton> mxTemplateButton;
    std::unique_ptr<weld::ToggleButton> mxTemplateButton;

    std::unique_ptr<weld::Label> mxCreateLabel;
    std::unique_ptr<weld::Label> mxAltHelpLabel;
    std::unique_ptr<weld::ComboBox> mxFilter;
    std::unique_ptr<weld::MenuButton> mxActions;

    std::unique_ptr<weld::Button> mxWriterAllButton;
    std::unique_ptr<weld::Button> mxCalcAllButton;
@@ -88,6 +90,8 @@ class BackingWindow : public InterimItemWindow
                     const css::uno::Sequence<css::beans::PropertyValue>& = css::uno::Sequence<
                         css::beans::PropertyValue>());

    DECL_LINK(ToggleHdl, weld::Toggleable&, void);
    DECL_LINK(FilterHdl, weld::ComboBox&, void);
    DECL_LINK(ClickHdl, weld::Button&, void);
    DECL_LINK(ClickHelpHdl, weld::Button&, void);
    DECL_LINK(MenuSelectHdl, const OString&, void);
@@ -107,6 +111,9 @@ class BackingWindow : public InterimItemWindow
    template <typename WidgetClass> void setLargerFont(WidgetClass&, const vcl::Font&);
    void ApplyStyleSettings();

private:
    void applyFilter();

public:
    explicit BackingWindow(vcl::Window* pParent);
    virtual ~BackingWindow() override;
diff --git a/sfx2/uiconfig/ui/startcenter.ui b/sfx2/uiconfig/ui/startcenter.ui
index 89b4653..8120556 100644
--- a/sfx2/uiconfig/ui/startcenter.ui
+++ b/sfx2/uiconfig/ui/startcenter.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkImage" id="calc_all_image">
@@ -35,50 +35,11 @@
    <property name="can-focus">False</property>
    <property name="icon-name">res/odg_32_8.png</property>
  </object>
  <object class="GtkMenu" id="filtermenu">
  <object class="GtkImage" id="imActions">
    <property name="visible">True</property>
    <property name="can-focus">False</property>
    <child>
      <object class="GtkMenuItem" id="filter_writer">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="label" translatable="yes" context="startcenter|filter_writer">Writer Templates</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="filter_calc">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="label" translatable="yes" context="startcenter|filter_calc">Calc Templates</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="filter_impress">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="label" translatable="yes" context="startcenter|filter_impress">Impress Templates</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="filter_draw">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="label" translatable="yes" context="startcenter|filter_draw">Draw Templates</property>
      </object>
    </child>
    <child>
      <object class="GtkSeparatorMenuItem" id="menuitem3">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="manage">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="label" translatable="yes" context="startcenter|manage">Manage Templates</property>
      </object>
    </child>
    <property name="icon-name">open-menu-symbolic</property>
    <property name="icon_size">3</property>
  </object>
  <object class="GtkImage" id="impress_all_image">
    <property name="visible">True</property>
@@ -208,9 +169,8 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkMenuButton" id="open_recent">
                      <object class="GtkToggleButton" id="open_recent">
                        <property name="label" translatable="yes" context="startcenter|open_recent">_Recent Documents</property>
                        <property name="name">MenuToggleButton</property>
                        <property name="visible">True</property>
                        <property name="can-focus">True</property>
                        <property name="receives-default">True</property>
@@ -221,9 +181,6 @@
                        <property name="use-underline">True</property>
                        <property name="xalign">0</property>
                        <property name="always-show-image">True</property>
                        <property name="draw-indicator">True</property>
                        <property name="popup">clearmenu</property>
                        <property name="use-popover">False</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -232,9 +189,8 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkMenuButton" id="templates_all">
                      <object class="GtkToggleButton" id="templates_all">
                        <property name="label" translatable="yes" context="startcenter|templates_all">T_emplates</property>
                        <property name="name">MenuToggleButton</property>
                        <property name="visible">True</property>
                        <property name="can-focus">True</property>
                        <property name="receives-default">True</property>
@@ -245,9 +201,6 @@
                        <property name="use-underline">True</property>
                        <property name="xalign">0</property>
                        <property name="always-show-image">True</property>
                        <property name="draw-indicator">True</property>
                        <property name="popup">filtermenu</property>
                        <property name="use-popover">False</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -546,6 +499,78 @@
              </packing>
            </child>
            <child>
              <!-- n-columns=3 n-rows=1 -->
              <object class="GtkGrid" id="actions">
                <property name="visible">True</property>
                <property name="can-focus">False</property>
                <property name="margin-start">6</property>
                <property name="margin-end">6</property>
                <property name="margin-top">6</property>
                <property name="margin-bottom">6</property>
                <property name="column-spacing">3</property>
                <child>
                  <object class="GtkLabel" id="lbFilter">
                    <property name="visible">True</property>
                    <property name="can-focus">False</property>
                    <property name="halign">start</property>
                    <property name="label" translatable="yes" context="startcenter|filter_label">Filter:</property>
                    <accessibility>
                      <relation type="label-for" target="cbFilter"/>
                    </accessibility>
                  </object>
                  <packing>
                    <property name="left-attach">0</property>
                    <property name="top-attach">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkComboBoxText" id="cbFilter">
                    <property name="visible">True</property>
                    <property name="can-focus">False</property>
                    <property name="halign">start</property>
                    <property name="active">0</property>
                    <items>
                      <item id="filter_none" translatable="yes" context="startcenter|filter_none">All Applications</item>
                      <item id="filter_writer" translatable="yes" context="startcenter|filter_writer">Text Documents</item>
                      <item id="filter_calc" translatable="yes" context="startcenter|filter_calc">Spreadsheets</item>
                      <item id="filter_impress" translatable="yes" context="startcenter|filter_impress">Presentations</item>
                      <item id="filter_draw" translatable="yes" context="startcenter|filter_draw">Drawings</item>
                    </items>
                    <accessibility>
                      <relation type="labelled-by" target="lbFilter"/>
                    </accessibility>
                  </object>
                  <packing>
                    <property name="left-attach">1</property>
                    <property name="top-attach">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkMenuButton" id="mbActions">
                    <property name="visible">True</property>
                    <property name="can-focus">True</property>
                    <property name="focus-on-click">False</property>
                    <property name="receives-default">True</property>
                    <property name="tooltip-text" translatable="yes" context="startcenter|mbActions|tool_tip">Actions</property>
                    <property name="halign">end</property>
                    <property name="hexpand">True</property>
                    <property name="image">imActions</property>
                    <property name="always-show-image">True</property>
                    <property name="popup">clearmenu</property>
                  </object>
                  <packing>
                    <property name="left-attach">2</property>
                    <property name="top-attach">0</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <object class="GtkScrolledWindow" id="scrollrecent">
                <property name="visible">True</property>
                <property name="can-focus">True</property>
@@ -573,7 +598,7 @@
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">2</property>
                <property name="position">3</property>
              </packing>
            </child>
            <child>
@@ -604,7 +629,7 @@
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">3</property>
                <property name="position">4</property>
              </packing>
            </child>
          </object>