weld StylesPropertyPanel

and SvxStyleToolBoxControl, etc.

use a GtkOverlay to support the submenu hackery in the Style
wysiwyg combobox dropdown

Change-Id: I17baa56f382243070ee49e6d707e97324e4f4d67
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85720
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index 4ecff16..8cdb5ef 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -339,7 +339,7 @@ private:
    SVT_DLLPRIVATE void         ImplDestroyFontList();

    DECL_LINK(CustomRenderHdl, weld::ComboBox::render_args, void);
    DECL_STATIC_LINK(FontNameBox, CustomGetSizeHdl, weld::ComboBox::get_size_args, Size);
    DECL_STATIC_LINK(FontNameBox, CustomGetSizeHdl, OutputDevice&, Size);
    DECL_LINK(UpdateHdl, Timer*, void);

    void            LoadMRUEntries( const OUString& aFontMRUEntriesFile );
diff --git a/include/svx/tbcontrl.hxx b/include/svx/tbcontrl.hxx
index 0c7da00..387c67f 100644
--- a/include/svx/tbcontrl.hxx
+++ b/include/svx/tbcontrl.hxx
@@ -146,7 +146,6 @@ class SvxFontItem;
class SfxStyleControllerItem_Impl;
class SfxStyleSheetBasePool;
class SfxTemplateItem;
class SvxStyleBox_Impl;
class PaletteManager;

namespace svx
@@ -154,25 +153,22 @@ namespace svx
    class ToolboxButtonColorUpdaterBase;
}

class SVXCORE_DLLPUBLIC SvxStyleToolBoxControl final : public SfxToolBoxControl
class SVXCORE_DLLPUBLIC SvxStyleToolBoxControl final : public cppu::ImplInheritanceHelper<svt::ToolboxController,
                                                                                          css::lang::XServiceInfo>
{
    struct Impl;
    std::unique_ptr<Impl> pImpl;

public:
    SFX_DECL_TOOLBOX_CONTROL();

    SvxStyleToolBoxControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rToolBox);
    SvxStyleToolBoxControl();
    virtual ~SvxStyleToolBoxControl() override;

    virtual VclPtr<vcl::Window> CreateItemWindow(vcl::Window* pParent) override;
    // XStatusListener
    virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;

    virtual void StateChanged(sal_uInt16 nSID, SfxItemState eState,
                              const SfxPoolItem* pState) override;
    // XToolbarController
    virtual css::uno::Reference<css::awt::XWindow> SAL_CALL createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent) override;

    DECL_LINK( VisibilityNotification, SvxStyleBox_Impl&, void );

private:
    // XInitialization
    virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& aArguments) override;

@@ -182,6 +178,12 @@ private:
    // XComponent
    virtual void SAL_CALL dispose() override;

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() override;
    virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;

private:
#define MAX_FAMILIES 5

    SfxStyleSheetBasePool* pStyleSheetPool;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 2d94323..d059e9c 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -585,6 +585,8 @@ enum class EntryMessageType
    Error,
};

class Menu;

/// A widget used to choose from a list of items.
class VCL_DLLPUBLIC ComboBox : virtual public Container
{
@@ -593,7 +595,6 @@ private:

public:
    // OUString is the id of the row, it may be null to measure the height of a generic line
    typedef std::pair<vcl::RenderContext&, const OUString&> get_size_args;
    typedef std::tuple<vcl::RenderContext&, const tools::Rectangle&, bool, const OUString&>
        render_args;

@@ -615,11 +616,8 @@ protected:
                rDevice, rRect, bSelected, rId));
    }

    Link<get_size_args, Size> m_aGetSizeHdl;
    Size signal_custom_get_size(vcl::RenderContext& rDevice, const OUString& rId)
    {
        return m_aGetSizeHdl.Call(std::pair<vcl::RenderContext&, const OUString&>(rDevice, rId));
    }
    Link<vcl::RenderContext&, Size> m_aGetSizeHdl;
    Size signal_custom_get_size(vcl::RenderContext& rDevice) { return m_aGetSizeHdl.Call(rDevice); }

public:
    virtual void insert(int pos, const OUString& rStr, const OUString* pId,
@@ -717,12 +715,19 @@ public:
    bool get_value_changed_from_saved() const { return m_sSavedValue != get_active_text(); }

    // for custom rendering a row
    void connect_custom_get_size(const Link<get_size_args, Size>& rLink) { m_aGetSizeHdl = rLink; }
    void connect_custom_get_size(const Link<vcl::RenderContext&, Size>& rLink)
    {
        m_aGetSizeHdl = rLink;
    }
    void connect_custom_render(const Link<render_args, void>& rLink) { m_aRenderHdl = rLink; }
    // call set_custom_renderer after setting custom callbacks
    virtual void set_custom_renderer() = 0;
    // create a virtual device compatible with the device passed in render_args wrt alpha
    virtual VclPtr<VirtualDevice> create_render_virtual_device() const = 0;
    // set a sub menu for a entry, only works with custom rendering
    virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) = 0;
    // get the width needed to show the menu launcher in a custom row
    virtual int get_menu_button_width() const = 0;

    // for mru support
    virtual int get_max_mru_count() const = 0;
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
index b9c4d64..48ed82b 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
@@ -1701,6 +1701,17 @@
          <value>com.sun.star.comp.svx.FontNameToolBoxControl</value>
        </prop>
      </node>
      <node oor:name="StyleToolBox" oor:op="replace">
        <prop oor:name="Command">
          <value>.uno:StyleApply</value>
        </prop>
        <prop oor:name="Module">
          <value/>
        </prop>
        <prop oor:name="Controller">
          <value>com.sun.star.comp.svx.StyleToolBoxControl</value>
        </prop>
      </node>
      <node oor:name="OpenToolbarController" oor:op="replace">
        <prop oor:name="Command">
          <value>.uno:Open</value>
diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx
index c50fcce..2d254db 100644
--- a/sc/source/ui/app/scdll.cxx
+++ b/sc/source/ui/app/scdll.cxx
@@ -147,7 +147,6 @@ void ScDLL::Init()
    SvxTbxCtlDraw                   ::RegisterControl(SID_INSERT_DRAW,          pMod);
    SvxFillToolBoxControl           ::RegisterControl(0, pMod);
    SvxLineWidthToolBoxControl      ::RegisterControl(0, pMod);
    SvxStyleToolBoxControl          ::RegisterControl(SID_STYLE_APPLY,          pMod);
    SvxClipBoardControl             ::RegisterControl(SID_PASTE,                pMod );
    SvxClipBoardControl             ::RegisterControl(SID_PASTE_UNFORMATTED,    pMod );
    svx::FormatPaintBrushToolBoxControl::RegisterControl(SID_FORMATPAINTBRUSH,  pMod );
diff --git a/sc/uiconfig/scalc/ui/sidebaralignment.ui b/sc/uiconfig/scalc/ui/sidebaralignment.ui
index 5d5474b..ce04c24 100644
--- a/sc/uiconfig/scalc/ui/sidebaralignment.ui
+++ b/sc/uiconfig/scalc/ui/sidebaralignment.ui
@@ -165,7 +165,6 @@
                  <object class="GtkToggleToolButton" id=".uno:ParaLeftToRight">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="is_important">True</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
@@ -177,7 +176,6 @@
                  <object class="GtkToggleToolButton" id=".uno:ParaRightToLeft">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="is_important">True</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
@@ -249,7 +247,6 @@
              <object class="GtkToolButton" id=".uno:IncrementIndent">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="is_important">True</property>
                <property name="use_underline">True</property>
              </object>
              <packing>
@@ -261,7 +258,6 @@
              <object class="GtkToolButton" id=".uno:DecrementIndent">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="is_important">True</property>
                <property name="use_underline">True</property>
              </object>
              <packing>
diff --git a/sd/source/ui/app/sddll.cxx b/sd/source/ui/app/sddll.cxx
index dcaab83..bb52a97 100644
--- a/sd/source/ui/app/sddll.cxx
+++ b/sd/source/ui/app/sddll.cxx
@@ -179,8 +179,6 @@ void SdDLL::RegisterControllers(SdModule* pMod)
    SvxFillToolBoxControl::RegisterControl(0, pMod);
    SvxLineWidthToolBoxControl::RegisterControl(0, pMod);

    SvxStyleToolBoxControl::RegisterControl(0, pMod);

    SvxGrafModeToolBoxControl::RegisterControl( SID_ATTR_GRAF_MODE, pMod );
    SvxGrafRedToolBoxControl::RegisterControl( SID_ATTR_GRAF_RED, pMod );
    SvxGrafGreenToolBoxControl::RegisterControl( SID_ATTR_GRAF_GREEN, pMod );
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 3ea5f08..dff4cc4 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -257,6 +257,7 @@ core_constructor_list = [
    "com_sun_star_comp_svx_FontNameToolBoxControl_get_implementation",
    "com_sun_star_comp_Svx_GraphicExportHelper_get_implementation",
    "com_sun_star_comp_Svx_GraphicImportHelper_get_implementation",
    "com_sun_star_comp_svx_StyleToolBoxControl_get_implementation",
# toolkit/util/tk.component
    "stardiv_Toolkit_StdTabController_get_implementation",
    "stardiv_Toolkit_UnoButtonControl_get_implementation",
diff --git a/solenv/sanitizers/ui/vcl.suppr b/solenv/sanitizers/ui/vcl.suppr
index b267355..96a13e0 100644
--- a/solenv/sanitizers/ui/vcl.suppr
+++ b/solenv/sanitizers/ui/vcl.suppr
@@ -5,6 +5,7 @@ vcl/uiconfig/ui/aboutbox.ui://GtkLabel[@id='description'] orphan-label
vcl/uiconfig/ui/aboutbox.ui://GtkLabel[@id='copyright'] orphan-label
vcl/uiconfig/ui/combobox.ui://GtkEntry[@id='entry'] no-labelled-by
vcl/uiconfig/ui/combobox.ui://GtkToggleButton[@id='button'] button-no-label
vcl/uiconfig/ui/combobox.ui://GtkMenuButton[@id='overlaybutton'] button-no-label
vcl/uiconfig/ui/cupspassworddialog.ui://GtkLabel[@id='text'] orphan-label
vcl/uiconfig/ui/printdialog.ui://GtkEntry[@id='pageedit-nospin'] no-labelled-by
vcl/uiconfig/ui/printdialog.ui://GtkLabel[@id='totalnumpages'] orphan-label
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index 78be607..b31ccc4 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -489,7 +489,7 @@ void FontNameBox::EnableWYSIWYG()
    mbWYSIWYG = true;
}

IMPL_STATIC_LINK_NOARG(FontNameBox, CustomGetSizeHdl, weld::ComboBox::get_size_args, Size)
IMPL_STATIC_LINK_NOARG(FontNameBox, CustomGetSizeHdl, OutputDevice&, Size)
{
    return gUserItemSz;
}
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index 98ef36a..861eea4 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
	svx/uiconfig/ui/addnamespacedialog \
	svx/uiconfig/ui/addsubmissiondialog \
	svx/uiconfig/ui/asianphoneticguidedialog \
	svx/uiconfig/ui/applystylebox \
	svx/uiconfig/ui/cellmenu \
	svx/uiconfig/ui/charsetmenu \
	svx/uiconfig/ui/checkbuttonbox \
diff --git a/svx/source/sidebar/styles/StylesPropertyPanel.cxx b/svx/source/sidebar/styles/StylesPropertyPanel.cxx
index 24189c8..931862f4 100644
--- a/svx/source/sidebar/styles/StylesPropertyPanel.cxx
+++ b/svx/source/sidebar/styles/StylesPropertyPanel.cxx
@@ -22,9 +22,12 @@ VclPtr<vcl::Window> StylesPropertyPanel::Create (
}

StylesPropertyPanel::StylesPropertyPanel ( vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rxFrame )
    : PanelLayout(pParent, "SidebarStylesPanel", "svx/ui/sidebarstylespanel.ui", rxFrame)
    : PanelLayout(pParent, "SidebarStylesPanel", "svx/ui/sidebarstylespanel.ui", rxFrame, true)
    , m_xFontStyle(m_xBuilder->weld_toolbar("fontstyletoolbox"))
    , m_xFontStyleDispatch(new ToolbarUnoDispatcher(*m_xFontStyle, *m_xBuilder, rxFrame))
    , m_xStyle(m_xBuilder->weld_toolbar("style"))
    , m_xStyleDispatch(new ToolbarUnoDispatcher(*m_xStyle, *m_xBuilder, rxFrame))
{

}

StylesPropertyPanel::~StylesPropertyPanel()
@@ -32,6 +35,16 @@ StylesPropertyPanel::~StylesPropertyPanel()
    disposeOnce();
}

void StylesPropertyPanel::dispose()
{
    m_xStyleDispatch.reset();
    m_xStyle.reset();
    m_xFontStyleDispatch.reset();
    m_xFontStyle.reset();

    PanelLayout::dispose();
}

void StylesPropertyPanel::DataChanged( const DataChangedEvent& /*rEvent*/)
{

diff --git a/svx/source/sidebar/styles/StylesPropertyPanel.hxx b/svx/source/sidebar/styles/StylesPropertyPanel.hxx
index b576503..3576345 100644
--- a/svx/source/sidebar/styles/StylesPropertyPanel.hxx
+++ b/svx/source/sidebar/styles/StylesPropertyPanel.hxx
@@ -2,12 +2,20 @@
#define INCLUDED_SVX_SOURCE_SIDEBAR_STYLES_STYLESPROPERTYPANEL_HXX

#include <svx/sidebar/PanelLayout.hxx>
#include <sfx2/weldutils.hxx>

namespace svx { namespace sidebar{

class StylesPropertyPanel:
    public PanelLayout
{
private:
    std::unique_ptr<weld::Toolbar> m_xFontStyle;
    std::unique_ptr<ToolbarUnoDispatcher> m_xFontStyleDispatch;

    std::unique_ptr<weld::Toolbar> m_xStyle;
    std::unique_ptr<ToolbarUnoDispatcher> m_xStyleDispatch;

public:
    virtual ~StylesPropertyPanel() override;

@@ -17,6 +25,8 @@ public:

    virtual void DataChanged( const DataChangedEvent& rEvent ) override;

    virtual void dispose() override;

    StylesPropertyPanel(
        vcl::Window* pParent,
        const css::uno::Reference<css::frame::XFrame>& rxFrame);
diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 5ab016d..cf55416 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -27,7 +27,6 @@
#include <vcl/commandinfoprovider.hxx>
#include <vcl/combobox.hxx>
#include <vcl/event.hxx>
#include <vcl/menubtn.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/customweld.hxx>
#include <vcl/vclptr.hxx>
@@ -106,8 +105,7 @@

#define MAX_MRU_FONTNAME_ENTRIES    5

// don't make more than 15 entries visible at once
#define MAX_STYLES_ENTRIES          15
#define COMBO_WIDTH_IN_CHARS        16

// namespaces
using namespace ::editeng;
@@ -117,44 +115,105 @@ using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;

SFX_IMPL_TOOLBOX_CONTROL( SvxStyleToolBoxControl, SfxTemplateItem );

class SvxStyleBox_Impl : public ComboBox
namespace
{
    using Window::IsVisible;
class SvxStyleBox_Base
{
public:
    SvxStyleBox_Impl( vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily, const Reference< XDispatchProvider >& rDispatchProvider,
                        const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString& rMoreKey, bool bInSpecialMode );
    virtual ~SvxStyleBox_Impl() override;
    virtual void dispose() override;
    SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget, const OUString& rCommand, SfxStyleFamily eFamily,
                     const Reference<XDispatchProvider>& rDispatchProvider,
                     const Reference<XFrame>& _xFrame,const OUString& rClearFormatKey,
                     const OUString& rMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);

    virtual ~SvxStyleBox_Base()
    {
    }

    void            SetFamily( SfxStyleFamily eNewFamily );
    bool            IsVisible() const { return bVisible; }

    virtual bool    PreNotify( NotifyEvent& rNEvt ) override;
    virtual bool    EventNotify( NotifyEvent& rNEvt ) override;
    virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
    virtual void    StateChanged( StateChangedType nStateChange ) override;

    virtual void    UserDraw( const UserDrawEvent& rUDEvt ) override;

    void            SetVisibilityListener( const Link<SvxStyleBox_Impl&,void>& aVisListener ) { aVisibilityListener = aVisListener; }

    void            SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }
    virtual boost::property_tree::ptree DumpAsPropertyTree() override;

protected:
    /// Calculate the optimal width of the dropdown.  Very expensive operation, triggers lots of font measurement.
    DECL_LINK(CalcOptimalExtraUserWidth, VclWindowEvent&, void);
    int get_count() const { return m_xWidget->get_count(); }
    OUString get_text(int nIndex) const { return m_xWidget->get_text(nIndex); }
    OUString get_active_text() const { return m_xWidget->get_active_text(); }

    virtual void    Select() override;
    void append_text(const OUString& rStr)
    {
        OUString sId(OUString::number(m_xWidget->get_count()));
        m_xWidget->append(sId, rStr);
    }

    void insert_separator(int pos, const OUString& rId)
    {
        m_xWidget->insert_separator(pos, rId);
    }

    virtual void set_sensitive(bool bSensitive)
    {
        m_xWidget->set_sensitive(bSensitive);
    }

    void set_active_or_entry_text(const OUString& rText)
    {
        const int nFound = m_xWidget->find_text(rText);
        if (nFound != -1)
            m_xWidget->set_active(nFound);
        else
            m_xWidget->set_entry_text(rText);
    }

    void set_active(int nActive)
    {
        m_xWidget->set_active(nActive);
    }

    void freeze()
    {
        m_xWidget->freeze();
    }

    void save_value()
    {
        m_xWidget->save_value();
    }

    void clear()
    {
        m_xWidget->clear();
        m_nMaxUserDrawFontWidth = 0;
    }

    void thaw()
    {
        m_xWidget->thaw();
    }

    virtual bool DoKeyInput(const KeyEvent& rKEvt);

private:
    DECL_LINK(SelectHdl, weld::ComboBox&, void);
    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
    DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
    DECL_LINK(FocusOutHdl, weld::Widget&, void);
    DECL_LINK(DumpAsPropertyTreeHdl, boost::property_tree::ptree&, void);
    DECL_LINK(CustomRenderHdl, weld::ComboBox::render_args, void);
    DECL_LINK(CustomGetSizeHdl, OutputDevice&, Size);

    /// Calculate the optimal width of the dropdown.  Very expensive operation, triggers lots of font measurement.
    void CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext);

    void Select(bool bNonTravelSelect);

protected:
    SvxStyleToolBoxControl& m_rCtrl;

    std::unique_ptr<weld::Builder>  m_xMenuBuilder;
    std::unique_ptr<weld::Menu>     m_xMenu;
    std::unique_ptr<weld::ComboBox> m_xWidget;

    SfxStyleFamily                  eStyleFamily;
    sal_Int32                       nCurSel;
    int                             m_nMaxUserDrawFontWidth;
    bool                            bRelease;
    Size                            aLogicalSize;
    Link<SvxStyleBox_Impl&,void>    aVisibilityListener;
    bool                            bVisible;
    Reference< XDispatchProvider >  m_xDispatchProvider;
    Reference< XFrame >             m_xFrame;
@@ -163,27 +222,58 @@ private:
    OUString                        aMoreKey;
    OUString                        sDefaultStyle;
    bool                            bInSpecialMode;
    VclPtr<MenuButton>              m_pButtons[MAX_STYLES_ENTRIES];
    VclBuilder                      m_aBuilder;
    VclPtr<PopupMenu>               m_pMenu;

    void            ReleaseFocus();
    static Color    TestColorsVisible(const Color &FontCol, const Color &BackCol);
    static void     UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName);
    void            SetupEntry(vcl::RenderContext& rRenderContext, vcl::Window* pParent, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected);
    static bool     AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rectangle const & rTextRect, long nHeight);
    void            SetOptimalSize();
    DECL_LINK( MenuSelectHdl, Menu *, bool );
    DECL_STATIC_LINK(SvxStyleBox_Impl, ShowMoreHdl, void*, void);
    static void     UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const OUString &rStyleName);
    void            SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected);
    static bool     AdjustFontForItemHeight(OutputDevice& rDevice, tools::Rectangle const & rTextRect, long nHeight);
    DECL_LINK(MenuSelectHdl, const OString&, void);
    DECL_STATIC_LINK(SvxStyleBox_Base, ShowMoreHdl, void*, void);
};

namespace {
class SvxStyleBox_Impl final : public InterimItemWindow
                             , public SvxStyleBox_Base
{
public:
    SvxStyleBox_Impl(vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily, const Reference< XDispatchProvider >& rDispatchProvider,
                     const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString& rMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);

    virtual ~SvxStyleBox_Impl() override
    {
        disposeOnce();
    }

    virtual void dispose() override
    {
        m_xWidget.reset();
        m_xMenu.reset();
        m_xMenuBuilder.reset();
        InterimItemWindow::dispose();
    }

    virtual bool DoKeyInput(const KeyEvent& rKEvt) override;

private:

    virtual void set_sensitive(bool bSensitive) override
    {
        m_xWidget->set_sensitive(bSensitive);
        if (bSensitive)
            InterimItemWindow::Enable();
        else
            InterimItemWindow::Disable();
    }

    virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
    void            SetOptimalSize();
};

class SvxFontNameBox_Impl;
class SvxFontNameBox_Base;

class SvxFontNameToolBoxControl : public cppu::ImplInheritanceHelper< svt::ToolboxController,
                                                                      css::lang::XServiceInfo >
class SvxFontNameToolBoxControl final : public cppu::ImplInheritanceHelper<svt::ToolboxController,
                                                                           css::lang::XServiceInfo>
{
public:
    SvxFontNameToolBoxControl();
@@ -192,7 +282,7 @@ public:
    virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;

    // XToolbarController
    virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createItemWindow( const css::uno::Reference< css::awt::XWindow >& rParent ) override;
    virtual css::uno::Reference<css::awt::XWindow> SAL_CALL createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent) override;

    // XComponent
    virtual void SAL_CALL dispose() override;
@@ -218,7 +308,6 @@ protected:
    const FontList*                pFontList;
    ::std::unique_ptr<FontList>    m_aOwnFontList;
    vcl::Font                      aCurFont;
    OUString                       aCurText;
    sal_uInt16                     nFtCount;
    bool                           bRelease;
    Reference< XDispatchProvider > m_xDispatchProvider;
@@ -477,7 +566,7 @@ private:
                                Color aColor1, Color aColor2, Color aColorDist,
                                SvxBorderLineStyle nStyle, BitmapEx& rBmp )
    {
        auto nMinWidth = GetDrawingArea()->get_ref_device().approximate_digit_width() * 15;
        auto nMinWidth = GetDrawingArea()->get_ref_device().approximate_digit_width() * COMBO_WIDTH_IN_CHARS;
        Size aSize(nMinWidth, aTxtSize.Height());
        aSize.AdjustWidth( -(aTxtSize.Width()) );
        aSize.AdjustWidth( -6 );
@@ -728,10 +817,57 @@ class SfxStyleControllerItem_Impl : public SfxStatusListener
        SvxStyleToolBoxControl& rControl;
};

#define BUTTON_WIDTH 20
#define BUTTON_PADDING 10
#define ITEM_HEIGHT 30

SvxStyleBox_Base::SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
                                   const OUString& rCommand,
                                   SfxStyleFamily eFamily,
                                   const Reference< XDispatchProvider >& rDispatchProvider,
                                   const Reference< XFrame >& _xFrame,
                                   const OUString& rClearFormatKey,
                                   const OUString& rMoreKey,
                                   bool bInSpec, SvxStyleToolBoxControl& rCtrl)
    : m_rCtrl(rCtrl)
    , m_xMenuBuilder(Application::CreateBuilder(nullptr, "svx/ui/stylemenu.ui"))
    , m_xMenu(m_xMenuBuilder->weld_menu("menu"))
    , m_xWidget(std::move(xWidget))
    , eStyleFamily( eFamily )
    , m_nMaxUserDrawFontWidth(0)
    , bRelease( true )
    , bVisible(false)
    , m_xDispatchProvider( rDispatchProvider )
    , m_xFrame(_xFrame)
    , m_aCommand( rCommand )
    , aClearFormatKey( rClearFormatKey )
    , aMoreKey( rMoreKey )
    , bInSpecialMode( bInSpec )
{
    m_xWidget->connect_changed(LINK(this, SvxStyleBox_Base, SelectHdl));
    m_xWidget->connect_key_press(LINK(this, SvxStyleBox_Base, KeyInputHdl));
    m_xWidget->connect_entry_activate(LINK(this, SvxStyleBox_Base, ActivateHdl));
    m_xWidget->connect_focus_out(LINK(this, SvxStyleBox_Base, FocusOutHdl));
    m_xWidget->connect_get_property_tree(LINK(this, SvxStyleBox_Base, DumpAsPropertyTreeHdl));
    m_xWidget->set_help_id(HID_STYLE_LISTBOX);
    m_xWidget->set_entry_completion(true);
    m_xMenu->connect_activate(LINK(this, SvxStyleBox_Base, MenuSelectHdl));

    m_xWidget->connect_custom_get_size(LINK(this, SvxStyleBox_Base, CustomGetSizeHdl));
    m_xWidget->connect_custom_render(LINK(this, SvxStyleBox_Base, CustomRenderHdl));
    m_xWidget->set_custom_renderer();

    int nCharWidth = m_xWidget->get_approximate_digit_width() * COMBO_WIDTH_IN_CHARS;
    // set width in chars low so the size request will not be overridden
    m_xWidget->set_entry_width_chars(1);
    m_xWidget->set_size_request(nCharWidth, -1);
}

IMPL_LINK(SvxStyleBox_Base, CustomGetSizeHdl, OutputDevice&, rArg, Size)
{
    CalcOptimalExtraUserWidth(rArg);
    return Size(m_nMaxUserDrawFontWidth, ITEM_HEIGHT);
}

SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
                                   const OUString& rCommand,
                                   SfxStyleFamily eFamily,
@@ -739,55 +875,16 @@ SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
                                   const Reference< XFrame >& _xFrame,
                                   const OUString& rClearFormatKey,
                                   const OUString& rMoreKey,
                                   bool bInSpec)
    : ComboBox(pParent, WB_SORT | WB_BORDER | WB_HIDE | WB_DROPDOWN | WB_AUTOHSCROLL)
    , eStyleFamily( eFamily )
    , nCurSel(0)
    , bRelease( true )
    , aLogicalSize(60, 86)
    , bVisible(false)
    , m_xDispatchProvider( rDispatchProvider )
    , m_xFrame(_xFrame)
    , m_aCommand( rCommand )
    , aClearFormatKey( rClearFormatKey )
    , aMoreKey( rMoreKey )
    , bInSpecialMode( bInSpec )
    , m_aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/stylemenu.ui", "")
    , m_pMenu(m_aBuilder.get_menu("menu"))
                                   bool bInSpec, SvxStyleToolBoxControl& rCtrl)
    : InterimItemWindow(pParent, "svx/ui/applystylebox.ui", "ApplyStyleBox")
    , SvxStyleBox_Base(m_xBuilder->weld_combo_box("applystyle"), rCommand, eFamily,
                       rDispatchProvider, _xFrame, rClearFormatKey, rMoreKey, bInSpec, rCtrl)
{
    SetHelpId(HID_STYLE_LISTBOX);
    m_pMenu->SetSelectHdl( LINK( this, SvxStyleBox_Impl, MenuSelectHdl ) );
    for(VclPtr<MenuButton> & rpButton : m_pButtons)
        rpButton = nullptr;
    SetOptimalSize();
    EnableAutocomplete( true );
    EnableUserDraw( true );
    AddEventListener(LINK(this, SvxStyleBox_Impl, CalcOptimalExtraUserWidth));
    SetUserItemSize( Size( 0, ITEM_HEIGHT ) );
    set_id("applystyle");
    SetOptimalSize();
}

SvxStyleBox_Impl::~SvxStyleBox_Impl()
{
    disposeOnce();
}

void SvxStyleBox_Impl::dispose()
{
    RemoveEventListener(LINK(this, SvxStyleBox_Impl, CalcOptimalExtraUserWidth));

    for (VclPtr<MenuButton>& rButton : m_pButtons)
    {
        rButton.disposeAndClear();
    }

    m_pMenu.clear();
    m_aBuilder.disposeBuilder();

    ComboBox::dispose();
}

void SvxStyleBox_Impl::ReleaseFocus()
void SvxStyleBox_Base::ReleaseFocus()
{
    if ( !bRelease )
    {
@@ -798,56 +895,60 @@ void SvxStyleBox_Impl::ReleaseFocus()
        m_xFrame->getContainerWindow()->setFocus();
}

IMPL_LINK( SvxStyleBox_Impl, MenuSelectHdl, Menu*, pMenu, bool)
IMPL_LINK(SvxStyleBox_Base, MenuSelectHdl, const OString&, rMenuIdent, void)
{
    OUString sEntry = GetSelectedEntry();
    OString sMenuIdent = pMenu->GetCurItemIdent();
    OUString sEntry = m_xWidget->get_active_text();

    ReleaseFocus(); // It must be after getting entry pos!
    if (IsInDropDown())
        ToggleDropDown();
    Sequence< PropertyValue > aArgs( 2 );
    Sequence<PropertyValue> aArgs(2);
    aArgs[0].Name   = "Param";
    aArgs[0].Value  <<= sEntry;
    aArgs[1].Name   = "Family";
    aArgs[1].Value  <<= sal_Int16( eStyleFamily );

    if (sMenuIdent == "update")
    if (rMenuIdent == "update")
    {
        SfxToolBoxControl::Dispatch( m_xDispatchProvider,
            ".uno:StyleUpdateByExample", aArgs );
    }
    else if (sMenuIdent == "edit")
    else if (rMenuIdent == "edit")
    {
        SfxToolBoxControl::Dispatch( m_xDispatchProvider,
            ".uno:EditStyle", aArgs );
    }

    return false;
}

IMPL_STATIC_LINK_NOARG(SvxStyleBox_Impl, ShowMoreHdl, void*, void)
IMPL_STATIC_LINK_NOARG(SvxStyleBox_Base, ShowMoreHdl, void*, void)
{
    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    DBG_ASSERT( pViewFrm, "SvxStyleBox_Impl::Select(): no viewframe" );
    DBG_ASSERT( pViewFrm, "SvxStyleBox_Base::Select(): no viewframe" );
    if (!pViewFrm)
        return;
    pViewFrm->ShowChildWindow(SID_SIDEBAR);
    ::sfx2::sidebar::Sidebar::ShowPanel("StyleListPanel", pViewFrm->GetFrame().GetFrameInterface(), true);
}

void SvxStyleBox_Impl::Select()
IMPL_LINK(SvxStyleBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)
{
    // Tell base class about selection so that AT get informed about it.
    ComboBox::Select();
    Select(rCombo.changed_by_direct_pick()); // only when picked from the list
}

    if ( IsTravelSelect() )
IMPL_LINK_NOARG(SvxStyleBox_Base, ActivateHdl, weld::ComboBox&, bool)
{
    Select(true);
    return true;
}

void SvxStyleBox_Base::Select(bool bNonTravelSelect)
{
    if (!bNonTravelSelect)
        return;

    OUString aSearchEntry( GetText() );
    OUString aSearchEntry(m_xWidget->get_active_text());
    bool bDoIt = true, bClear = false;
    if( bInSpecialMode )
    {
        if( aSearchEntry == aClearFormatKey && GetSelectedEntryPos() == 0 )
        if( aSearchEntry == aClearFormatKey && m_xWidget->get_active() == 0 )
        {
            aSearchEntry = sDefaultStyle;
            bClear = true;
@@ -856,11 +957,11 @@ void SvxStyleBox_Impl::Select()
            SfxToolBoxControl::Dispatch( m_xDispatchProvider, ".uno:ResetAttributes",
                aEmptyVals);
        }
        else if( aSearchEntry == aMoreKey && GetSelectedEntryPos() == ( GetEntryCount() - 1 ) )
        else if (aSearchEntry == aMoreKey && m_xWidget->get_active() == (m_xWidget->get_count() - 1))
        {
            Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Impl, ShowMoreHdl));
            Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Base, ShowMoreHdl));
            //tdf#113214 change text back to previous entry
            SetText(GetSavedValue());
            set_active_or_entry_text(m_xWidget->get_saved_value());
            bDoIt = false;
        }
    }
@@ -896,8 +997,8 @@ void SvxStyleBox_Impl::Select()
    if( bDoIt )
    {
        if ( bClear )
            SetText( aSearchEntry );
        SaveValue();
            set_active_or_entry_text(aSearchEntry);
        m_xWidget->save_value();

        Sequence< PropertyValue > aArgs( 2 );
        aArgs[0].Value  <<= aSearchEntry;
@@ -916,67 +1017,50 @@ void SvxStyleBox_Impl::Select()
    }
}

void SvxStyleBox_Impl::SetFamily( SfxStyleFamily eNewFamily )
void SvxStyleBox_Base::SetFamily( SfxStyleFamily eNewFamily )
{
    eStyleFamily = eNewFamily;
}

bool SvxStyleBox_Impl::PreNotify( NotifyEvent& rNEvt )
IMPL_LINK_NOARG(SvxStyleBox_Base, FocusOutHdl, weld::Widget&, void)
{
    MouseNotifyEvent nType = rNEvt.GetType();

    if ( MouseNotifyEvent::MOUSEBUTTONDOWN == nType || MouseNotifyEvent::GETFOCUS == nType )
        nCurSel = GetSelectedEntryPos();
    else if ( MouseNotifyEvent::LOSEFOCUS == nType )
    {
        // don't handle before our Select() is called
        if (!HasFocus() && !HasChildPathFocus() && !IsChild(rNEvt.GetWindow()))
            SetText( GetSavedValue() );
    }
    return ComboBox::PreNotify( rNEvt );
    if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
        set_active_or_entry_text(m_xWidget->get_saved_value());
}

bool SvxStyleBox_Impl::EventNotify( NotifyEvent& rNEvt )
IMPL_LINK(SvxStyleBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    return DoKeyInput(rKEvt);
}

bool SvxStyleBox_Base::DoKeyInput(const KeyEvent& rKEvt)
{
    bool bHandled = false;

    if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
    sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();

    switch (nCode)
    {
        sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();

        switch ( nCode )
        {
            case KEY_CONTEXTMENU:
        case KEY_TAB:
            bRelease = false;
            Select(true);
            break;
        case KEY_ESCAPE:
            set_active_or_entry_text(m_xWidget->get_saved_value());
            if (!m_rCtrl.IsInSidebar())
            {
                if(IsInDropDown())
                {
                    const sal_Int32 nItem = GetSelectedEntryPos() - 1;
                    if(nItem < MAX_STYLES_ENTRIES)
                        m_pButtons[nItem]->ExecuteMenu();
                    bHandled = true;
                }
                break;
            }
            case KEY_RETURN:
            case KEY_TAB:
            {
                if ( KEY_TAB == nCode )
                    bRelease = false;
                else
                    bHandled = true;
                Select();
                break;
            }

            case KEY_ESCAPE:
                SelectEntryPos( nCurSel );
                if ( typeid( *GetParent() ) != typeid( sfx2::sidebar::SidebarToolBox ) )
                    ReleaseFocus();
                ReleaseFocus();
                bHandled = true;
                break;
        }
            }
            break;
    }
    return bHandled || ComboBox::EventNotify( rNEvt );

    return bHandled;
}

bool SvxStyleBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
{
    return SvxStyleBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
}

void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
@@ -987,37 +1071,21 @@ void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
        SetOptimalSize();
    }

    ComboBox::DataChanged( rDCEvt );
    InterimItemWindow::DataChanged( rDCEvt );
}

void SvxStyleBox_Impl::StateChanged( StateChangedType nStateChange )
{
    ComboBox::StateChanged( nStateChange );

    if ( nStateChange == StateChangedType::Visible )
    {
        bVisible = IsReallyVisible();
        aVisibilityListener.Call( *this );
    }
    else if ( nStateChange == StateChangedType::InitShow )
    {
        bVisible = true;
        aVisibilityListener.Call( *this );
    }
}

bool SvxStyleBox_Impl::AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rectangle const & rTextRect, long nHeight)
bool SvxStyleBox_Base::AdjustFontForItemHeight(OutputDevice& rDevice, tools::Rectangle const & rTextRect, long nHeight)
{
    if (rTextRect.Bottom() > nHeight)
    {
        // the text does not fit, adjust the font size
        double ratio = static_cast< double >( nHeight ) / rTextRect.Bottom();
        vcl::Font aFont(pDevice->GetFont());
        vcl::Font aFont(rDevice.GetFont());
        Size aPixelSize(aFont.GetFontSize());
        aPixelSize.setWidth( aPixelSize.Width() * ratio );
        aPixelSize.setHeight( aPixelSize.Height() * ratio );
        aFont.SetFontSize(aPixelSize);
        pDevice->SetFont(aFont);
        rDevice.SetFont(aFont);
        return true;
    }
    return false;
@@ -1025,42 +1093,46 @@ bool SvxStyleBox_Impl::AdjustFontForItemHeight(OutputDevice* pDevice, tools::Rec

void SvxStyleBox_Impl::SetOptimalSize()
{
    Size aSize(LogicToPixel(aLogicalSize, MapMode(MapUnit::MapAppFont)));
    set_width_request(aSize.Width());
    set_height_request(aSize.Height());
    SetSizePixel(aSize);
    SetSizePixel(get_preferred_size());
}

void SvxStyleBox_Impl::UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName)
void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const OUString &rStyleName)
{
    vcl::RenderContext *pDevice = rUDEvt.GetRenderContext();

    // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
    // nBorder, and we are adding 1 in order to look better when
    // italics is present
    const int nLeftDistance = 8;

    tools::Rectangle aTextRect;
    pDevice->GetTextBoundRect(aTextRect, rStyleName);
    rRenderContext.GetTextBoundRect(aTextRect, rStyleName);

    Point aPos( rUDEvt.GetRect().TopLeft() );
    Point aPos(rRect.TopLeft());
    aPos.AdjustX(nLeftDistance );

    if (!AdjustFontForItemHeight(pDevice, aTextRect, rUDEvt.GetRect().GetHeight()))
        aPos.AdjustY(( rUDEvt.GetRect().GetHeight() - aTextRect.Bottom() ) / 2 );
    if (!AdjustFontForItemHeight(rRenderContext, aTextRect, rRect.GetHeight()))
        aPos.AdjustY((rRect.GetHeight() - aTextRect.Bottom() ) / 2);

    pDevice->DrawText(aPos, rStyleName);
    rRenderContext.DrawText(aPos, rStyleName);
}

void SvxStyleBox_Impl::SetupEntry(vcl::RenderContext& rRenderContext, vcl::Window* pParent, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected)
void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, const OUString& rStyleName, bool bIsNotSelected)
{
    unsigned int nId = rRect.GetHeight() != 0 ? (rRect.getY() / rRect.GetHeight()) : MAX_STYLES_ENTRIES;
    if (nItem == 0 || nItem == GetEntryCount() - 1)
    {
        if(nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
            m_pButtons[nId]->Hide();
    }
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    if (!bIsNotSelected)
        rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
    else
        rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());

    // handle the push-button
    if (!bIsNotSelected)
    {
        if (nItem == 0 || nItem == m_xWidget->get_count() - 1)
            m_xWidget->set_item_menu(OString::number(nItem), nullptr);
        else
            m_xWidget->set_item_menu(OString::number(nItem), m_xMenu.get());
    }

    if (nItem > 0 && nItem < m_xWidget->get_count() - 1)
    {
        SfxObjectShell *pShell = SfxObjectShell::Current();
        SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
@@ -1181,93 +1253,69 @@ void SvxStyleBox_Impl::SetupEntry(vcl::RenderContext& rRenderContext, vcl::Windo
                // set text color
                if ( aFontCol != COL_AUTO )
                    rRenderContext.SetTextColor(aFontCol);

                // handle the push-button
                if (bIsNotSelected)
                {
                    if (nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
                        m_pButtons[nId]->Hide();
                }
                else
                {
                    if (nId < MAX_STYLES_ENTRIES)
                    {
                        if (!m_pButtons[nId] && pParent)
                        {
                            m_pButtons[nId] = VclPtr<MenuButton>::Create(pParent, WB_FLATBUTTON | WB_NOPOINTERFOCUS);
                            m_pButtons[nId]->SetSizePixel(Size(BUTTON_WIDTH, rRect.GetHeight()));
                            m_pButtons[nId]->SetPopupMenu(m_pMenu);
                        }
                        m_pButtons[nId]->SetPosPixel(Point(rRect.GetWidth() - BUTTON_WIDTH, rRect.getY()));
                        m_pButtons[nId]->Show();
                    }
                }
            }
        }
    }
}

void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
IMPL_LINK(SvxStyleBox_Base, CustomRenderHdl, weld::ComboBox::render_args, aPayload, void)
{
    sal_uInt16 nItem = rUDEvt.GetItemId();
    OUString aStyleName( GetEntry( nItem ) );
    vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
    const ::tools::Rectangle& rRect = std::get<1>(aPayload);
    bool bSelected = std::get<2>(aPayload);
    const OUString& rId = std::get<3>(aPayload);

    vcl::RenderContext *pDevice = rUDEvt.GetRenderContext();
    pDevice->Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
    sal_uInt32 nIndex = rId.toUInt32();

    const tools::Rectangle& rRect(rUDEvt.GetRect());
    bool bIsNotSelected = rUDEvt.GetItemId() != GetSelectedEntryPos();
    OUString aStyleName(m_xWidget->get_text(nIndex));

    SetupEntry(*pDevice, rUDEvt.GetWindow(), nItem, rRect, aStyleName, bIsNotSelected);
    rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);

    UserDrawEntry(rUDEvt, aStyleName);
    SetupEntry(rRenderContext, nIndex, rRect, aStyleName, !bSelected);

    pDevice->Pop();
    // draw separator, if present
    DrawEntry( rUDEvt, false, false );
    UserDrawEntry(rRenderContext, rRect, aStyleName);

    rRenderContext.Pop();
}

IMPL_LINK(SvxStyleBox_Impl, CalcOptimalExtraUserWidth, VclWindowEvent&, event, void)
void SvxStyleBox_Base::CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext)
{
    // perform the calculation only when we are opening the dropdown
    if (event.GetId() != VclEventId::DropdownPreOpen)
    if (m_nMaxUserDrawFontWidth)
        return;

    long nMaxNormalFontWidth = 0;
    sal_Int32 nEntryCount = GetEntryCount();
    sal_Int32 nEntryCount = m_xWidget->get_count();
    for (sal_Int32 i = 0; i < nEntryCount; ++i)
    {
        OUString sStyleName(GetEntry(i));
        OUString sStyleName(get_text(i));
        tools::Rectangle aTextRectForDefaultFont;
        GetTextBoundRect(aTextRectForDefaultFont, sStyleName);
        rRenderContext.GetTextBoundRect(aTextRectForDefaultFont, sStyleName);

        const long nWidth = aTextRectForDefaultFont.GetWidth();

        nMaxNormalFontWidth = std::max(nWidth, nMaxNormalFontWidth);
    }

    long nMaxUserDrawFontWidth = nMaxNormalFontWidth;
    m_nMaxUserDrawFontWidth = nMaxNormalFontWidth;
    for (sal_Int32 i = 1; i < nEntryCount-1; ++i)
    {
        OUString sStyleName(GetEntry(i));
        OUString sStyleName(get_text(i));

        Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
        SetupEntry(*this /*FIXME rendercontext*/, this, i, tools::Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), sStyleName, true);
        rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
        SetupEntry(rRenderContext, i, tools::Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), sStyleName, true);
        tools::Rectangle aTextRectForActualFont;
        GetTextBoundRect(aTextRectForActualFont, sStyleName);
        if (AdjustFontForItemHeight(this, aTextRectForActualFont, ITEM_HEIGHT))
        rRenderContext.GetTextBoundRect(aTextRectForActualFont, sStyleName);
        if (AdjustFontForItemHeight(rRenderContext, aTextRectForActualFont, ITEM_HEIGHT))
        {
            //Font didn't fit, so it was changed, refetch with final font size
            GetTextBoundRect(aTextRectForActualFont, sStyleName);
            rRenderContext.GetTextBoundRect(aTextRectForActualFont, sStyleName);
        }
        Pop();
        rRenderContext.Pop();

        const long nWidth = aTextRectForActualFont.GetWidth() + BUTTON_WIDTH + BUTTON_PADDING;
        const int nWidth = aTextRectForActualFont.GetWidth() + m_xWidget->get_menu_button_width() + BUTTON_PADDING;

        nMaxUserDrawFontWidth = std::max(nWidth, nMaxUserDrawFontWidth);
        m_nMaxUserDrawFontWidth = std::max(nWidth, m_nMaxUserDrawFontWidth);
    }

    SetUserItemSize(Size(nMaxUserDrawFontWidth, ITEM_HEIGHT));
}

// test is the color between Font- and background-color to be identify
@@ -1275,7 +1323,7 @@ IMPL_LINK(SvxStyleBox_Impl, CalcOptimalExtraUserWidth, VclWindowEvent&, event, v
//        when both light or dark, change the Contrast
//        in other case do not change the origin color
//        when the color is R=G=B=128 the DecreaseContrast make 128 the need an exception
Color SvxStyleBox_Impl::TestColorsVisible(const Color &FontCol, const Color &BackCol)
Color SvxStyleBox_Base::TestColorsVisible(const Color &FontCol, const Color &BackCol)
{
    const sal_uInt8  ChgVal = 60;       // increase/decrease the Contrast

@@ -1293,38 +1341,35 @@ Color SvxStyleBox_Impl::TestColorsVisible(const Color &FontCol, const Color &Bac
    return retCol;
}

boost::property_tree::ptree SvxStyleBox_Impl::DumpAsPropertyTree()
IMPL_LINK(SvxStyleBox_Base, DumpAsPropertyTreeHdl, boost::property_tree::ptree&, rTree, void)
{
    boost::property_tree::ptree aTree(ComboBox::DumpAsPropertyTree());

    boost::property_tree::ptree aEntries;

    for (int i = 0; i < GetEntryCount(); ++i)
    for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; ++i)
    {
        boost::property_tree::ptree aEntry;
        aEntry.put("", GetEntry(i));
        aEntry.put("", m_xWidget->get_text(i));
        aEntries.push_back(std::make_pair("", aEntry));
    }

    aTree.add_child("entries", aEntries);
    rTree.add_child("entries", aEntries);

    boost::property_tree::ptree aSelected;

    for (int i = 0; i < GetSelectedEntryCount(); ++i)
    int nActive = m_xWidget->get_active();

    if (nActive != -1)
    {
        boost::property_tree::ptree aEntry;
        aEntry.put("", GetSelectedEntryPos(i));
        aEntry.put("", nActive);
        aSelected.push_back(std::make_pair("", aEntry));
    }

    aTree.put("selectedCount", GetSelectedEntryCount());
    aTree.add_child("selectedEntries", aSelected);
    aTree.put("command", ".uno:StyleApply");

    return aTree;
    rTree.put("selectedCount", nActive == -1 ? 0 : 1);
    rTree.add_child("selectedEntries", aSelected);
    rTree.put("command", ".uno:StyleApply");
}


static bool lcl_GetDocFontList(const FontList** ppFontList, SvxFontNameBox_Base* pBox)
{
    bool bChanged = false;
@@ -1400,7 +1445,7 @@ SvxFontNameBox_Base::SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget
                                         const Reference<XFrame>& rFrame,
                                         SvxFontNameToolBoxControl& rCtrl)
    : m_rCtrl(rCtrl)
    , m_nCharWidth(xWidget->get_approximate_digit_width() * 16)
    , m_nCharWidth(xWidget->get_approximate_digit_width() * COMBO_WIDTH_IN_CHARS)
    , m_xWidget(new FontNameBox(std::move(xWidget)))
    , pFontList(nullptr)
    , nFtCount(0)
@@ -1443,7 +1488,6 @@ void SvxFontNameBox_Base::FillList()
    // Did Doc-Fontlist change?
    lcl_GetDocFontList(&pFontList, this);

    aCurText = m_xWidget->get_active_text();
    m_xWidget->select_entry_region(nStartPos, nEndPos);
}

@@ -1524,7 +1568,7 @@ bool SvxFontNameBox_Base::DoKeyInput(const KeyEvent& rKEvt)
            break;

        case KEY_ESCAPE:
            set_active_or_entry_text(aCurText);
            set_active_or_entry_text(m_xWidget->get_saved_value());
            if (!m_rCtrl.IsInSidebar())
            {
                ReleaseFocus_Impl();
@@ -2464,17 +2508,24 @@ struct SvxStyleToolBoxControl::Impl
    bool                     bSpecModeWriter;
    bool                     bSpecModeCalc;

    VclPtr<SvxStyleBox_Impl> m_xVclBox;
    std::unique_ptr<SvxStyleBox_Base> m_xWeldBox;
    SvxStyleBox_Base* m_pBox;

    Impl()
        :aClearForm         ( SvxResId( RID_SVXSTR_CLEARFORM ) )
        ,aMore              ( SvxResId( RID_SVXSTR_MORE_STYLES ) )
        ,bSpecModeWriter    ( false )
        ,bSpecModeCalc      ( false )
        ,m_pBox             ( nullptr )
    {


    }
    void InitializeStyles(const Reference < frame::XModel >& xModel)
    {
        aDefaultStyles.clear();

        //now convert the default style names to the localized names
        try
        {
@@ -2564,14 +2615,12 @@ static const char* StyleSlotToStyleCommand[MAX_FAMILIES] =
    ".uno:TemplateFamily5"
};

SvxStyleToolBoxControl::SvxStyleToolBoxControl(
    sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
    :   SfxToolBoxControl   ( nSlotId, nId, rTbx ),
        pImpl               ( new Impl ),
        pStyleSheetPool     ( nullptr ),
        nActFamily          ( 0xffff )
SvxStyleToolBoxControl::SvxStyleToolBoxControl()
    : pImpl(new Impl)
    , pStyleSheetPool(nullptr)
    , nActFamily(0xffff)
{
    for ( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
    for (sal_uInt16 i = 0; i < MAX_FAMILIES; ++i)
    {
        pBoundItems[i] = nullptr;
        m_xBoundItems[i].clear();
@@ -2583,9 +2632,9 @@ SvxStyleToolBoxControl::~SvxStyleToolBoxControl()
{
}

void SAL_CALL SvxStyleToolBoxControl::initialize( const Sequence< Any >& aArguments )
void SAL_CALL SvxStyleToolBoxControl::initialize(const Sequence<Any>& rArguments)
{
    SfxToolBoxControl::initialize( aArguments );
    svt::ToolboxController::initialize(rArguments);

    // After initialize we should have a valid frame member where we can retrieve our
    // dispatch provider.
@@ -2608,7 +2657,20 @@ void SAL_CALL SvxStyleToolBoxControl::initialize( const Sequence< Any >& aArgume
// XComponent
void SAL_CALL SvxStyleToolBoxControl::dispose()
{
    SfxToolBoxControl::dispose();
    svt::ToolboxController::dispose();

    SolarMutexGuard aSolarMutexGuard;
    pImpl->m_xVclBox.disposeAndClear();
    pImpl->m_xWeldBox.reset();
    pImpl->m_pBox = nullptr;

    for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
    {
        if (!pBoundItem)
            continue;
        pBoundItem->UnBind();
    }
    unbindListener();

    for( sal_uInt16 i=0; i<MAX_FAMILIES; i++ )
    {
@@ -2631,18 +2693,34 @@ void SAL_CALL SvxStyleToolBoxControl::dispose()
    pImpl.reset();
}

OUString SvxStyleToolBoxControl::getImplementationName()
{
    return "com.sun.star.comp.svx.StyleToolBoxControl";
}

sal_Bool SvxStyleToolBoxControl::supportsService( const OUString& rServiceName )
{
    return cppu::supportsService( this, rServiceName );
}

css::uno::Sequence< OUString > SvxStyleToolBoxControl::getSupportedServiceNames()
{
    return { "com.sun.star.frame.ToolbarController" };
}

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
com_sun_star_comp_svx_StyleToolBoxControl_get_implementation(
    css::uno::XComponentContext*,
    css::uno::Sequence<css::uno::Any> const & )
{
    return cppu::acquire( new SvxStyleToolBoxControl() );
}

void SAL_CALL SvxStyleToolBoxControl::update()
{
    // Do nothing, we will start binding our listener when we are visible.
    // See link SvxStyleToolBoxControl::VisibilityNotification.
    SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
    if ( pBox->IsVisible() )
    {
        for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
            pBoundItem->ReBind();

        bindListener();
    }
    for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
        pBoundItem->ReBind();
    bindListener();
}

SfxStyleFamily SvxStyleToolBoxControl::GetActFamily() const
@@ -2663,7 +2741,7 @@ SfxStyleFamily SvxStyleToolBoxControl::GetActFamily() const

void SvxStyleToolBoxControl::FillStyleBox()
{
    SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
    SvxStyleBox_Base* pBox = pImpl->m_pBox;

    DBG_ASSERT( pStyleSheetPool, "StyleSheetPool not found!" );
    DBG_ASSERT( pBox,            "Control not found!" );
@@ -2681,7 +2759,7 @@ void SvxStyleToolBoxControl::FillStyleBox()
        pStyle = pStyleSheetPool->First();
        //!!! TODO: This condition isn't right any longer, because we always show some default entries
        //!!! so the list doesn't show the count
        if ( nCount != pBox->GetEntryCount() )
        if ( nCount != pBox->get_count() )
        {
            bDoFill = true;
        }
@@ -2690,7 +2768,7 @@ void SvxStyleToolBoxControl::FillStyleBox()
            sal_uInt16 i= 0;
            while ( pStyle && !bDoFill )
            {
                bDoFill = ( pBox->GetEntry(i) != pStyle->GetName() );
                bDoFill = ( pBox->get_text(i) != pStyle->GetName() );
                pStyle = pStyleSheetPool->Next();
                i++;
            }
@@ -2698,8 +2776,11 @@ void SvxStyleToolBoxControl::FillStyleBox()

        if ( bDoFill )
        {
            pBox->SetUpdateMode( false );
            pBox->Clear();
            OUString aStrSel(pBox->get_active_text());
            pBox->freeze();
            pBox->clear();

            std::vector<OUString> aStyles;

            {
                pStyle = pStyleSheetPool->Next();
@@ -2721,7 +2802,7 @@ void SvxStyleToolBoxControl::FillStyleBox()
                        }

                        if( bInsert )
                            pBox->InsertEntry( aName );
                            aStyles.push_back(aName);
                        pStyle = pStyleSheetPool->Next();
                    }
                }
@@ -2729,64 +2810,54 @@ void SvxStyleToolBoxControl::FillStyleBox()
                {
                    while ( pStyle )
                    {
                        pBox->InsertEntry( pStyle->GetName() );
                        aStyles.push_back(pStyle->GetName());
                        pStyle = pStyleSheetPool->Next();
                    }
                }
            }

            if( pImpl->bSpecModeWriter || pImpl->bSpecModeCalc )
            if (pImpl->bSpecModeWriter || pImpl->bSpecModeCalc)
            {
                // disable sort to preserve special order
                WinBits nWinBits = pBox->GetStyle();
                nWinBits &= ~WB_SORT;
                pBox->SetStyle( nWinBits );
                pBox->append_text(pImpl->aClearForm);
                pBox->insert_separator(1, "separator");

                // insert default styles
                sal_uInt16 nPos = 1;
                for( auto const & _i: pImpl->aDefaultStyles )
                {
                    pBox->InsertEntry( _i, nPos );
                    ++nPos;
                }

                pBox->InsertEntry( pImpl->aClearForm, 0 );
                pBox->SetSeparatorPos( 0 );

                pBox->InsertEntry( pImpl->aMore );

                // enable sort again
                nWinBits |= WB_SORT;
                pBox->SetStyle( nWinBits );
                for (const auto &rStyle : pImpl->aDefaultStyles)
                    pBox->append_text(rStyle);
            }

            pBox->SetUpdateMode( true );
            pBox->SetFamily( eFamily );
            std::sort(aStyles.begin(), aStyles.end());

            sal_uInt16 nLines = static_cast<sal_uInt16>(
                    std::min( pBox->GetEntryCount(), static_cast<sal_Int32>(MAX_STYLES_ENTRIES)));
            pBox->SetDropDownLineCount( nLines );
            for (const auto& rStyle : aStyles)
                pBox->append_text(rStyle);

            if (pImpl->bSpecModeWriter || pImpl->bSpecModeCalc)
                pBox->append_text(pImpl->aMore);

            pBox->thaw();
            pBox->set_active_or_entry_text(aStrSel);
            pBox->SetFamily( eFamily );
        }
    }
}

void SvxStyleToolBoxControl::SelectStyle( const OUString& rStyleName )
{
    SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>(GetToolBox().GetItemWindow( GetId() ));
    SvxStyleBox_Base* pBox = pImpl->m_pBox;
    DBG_ASSERT( pBox, "Control not found!" );

    if ( pBox )
    {
        OUString aStrSel( pBox->GetText() );
        OUString aStrSel(pBox->get_active_text());

        if ( !rStyleName.isEmpty() )
        {
            if ( rStyleName != aStrSel )
                pBox->SetText( rStyleName );
                pBox->set_active_or_entry_text( rStyleName );
        }
        else
            pBox->SetNoSelection();
        pBox->SaveValue();
            pBox->set_active(-1);
        pBox->save_value();
    }
}

@@ -2841,81 +2912,71 @@ void SvxStyleToolBoxControl::SetFamilyState( sal_uInt16 nIdx,
    Update();
}

IMPL_LINK_NOARG(SvxStyleToolBoxControl, VisibilityNotification, SvxStyleBox_Impl&, void)
void SvxStyleToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent )
{
    // Call ReBind() && UnBind() according to visibility
    SvxStyleBox_Impl* pBox = static_cast<SvxStyleBox_Impl*>( GetToolBox().GetItemWindow( GetId() ));
    SolarMutexGuard aGuard;

    if ( pBox && pBox->IsVisible() && !isBound() )
    {
        for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
            pBoundItem->ReBind();

        bindListener();
    }
    else if ( (!pBox || !pBox->IsVisible()) && isBound() )
    {
        for (SfxStyleControllerItem_Impl* pBoundItem : pBoundItems)
            pBoundItem->UnBind();
        unbindListener();
    }
}

void SvxStyleToolBoxControl::StateChanged(
    sal_uInt16 , SfxItemState eState, const SfxPoolItem* pState )
{
    sal_uInt16       nId    = GetId();
    ToolBox&     rTbx   = GetToolBox();
    SvxStyleBox_Impl* pBox   = static_cast<SvxStyleBox_Impl*>(rTbx.GetItemWindow( nId ));
    TriState     eTri   = TRISTATE_FALSE;

    DBG_ASSERT( pBox, "Control not found!" );

    if ( SfxItemState::DISABLED == eState )
        pBox->Disable();
    if (m_pToolbar)
        m_pToolbar->set_item_sensitive(m_aCommandURL.toUtf8(), rEvent.IsEnabled);
    else
        pBox->Enable();

    rTbx.EnableItem( nId, SfxItemState::DISABLED != eState );

    switch ( eState )
    {
        case SfxItemState::DEFAULT:
            eTri = static_cast<const SfxTemplateItem*>(pState)->GetValue() != SfxStyleSearchBits::Auto
                        ? TRISTATE_TRUE
                        : TRISTATE_FALSE;
            break;

        case SfxItemState::DONTCARE:
            eTri = TRISTATE_INDET;
            break;

        default:
            break;
        ToolBox* pToolBox = nullptr;
        sal_uInt16 nId = 0;
        if (!getToolboxId( nId, &pToolBox ) )
            return;
        pToolBox->EnableItem( nId, rEvent.IsEnabled );
    }

    rTbx.SetItemState( nId, eTri );

    if ( SfxItemState::DISABLED != eState )
    if (rEvent.IsEnabled)
        Update();
}

VclPtr<vcl::Window> SvxStyleToolBoxControl::CreateItemWindow( vcl::Window *pParent )
css::uno::Reference<css::awt::XWindow> SvxStyleToolBoxControl::createItemWindow(const css::uno::Reference< css::awt::XWindow>& rParent)
{
    VclPtrInstance<SvxStyleBox_Impl> pBox( pParent,
                                           OUString( ".uno:StyleApply" ),
                                           SfxStyleFamily::Para,
                                           Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
                                           m_xFrame,
                                           pImpl->aClearForm,
                                           pImpl->aMore,
                                           pImpl->bSpecModeWriter || pImpl->bSpecModeCalc );
    if( !pImpl->aDefaultStyles.empty())
        pBox->SetDefaultStyle( pImpl->aDefaultStyles[0] );
    // Set visibility listener to bind/unbind controller
    pBox->SetVisibilityListener( LINK( this, SvxStyleToolBoxControl, VisibilityNotification ));
    uno::Reference< awt::XWindow > xItemWindow;

    return pBox.get();
    if (m_pBuilder)
    {
        SolarMutexGuard aSolarMutexGuard;

        std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("applystyle"));

        xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));

        pImpl->m_xWeldBox.reset(new SvxStyleBox_Base(std::move(xWidget),
                                                     ".uno:StyleApply",
                                                     SfxStyleFamily::Para,
                                                     Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
                                                     m_xFrame,
                                                     pImpl->aClearForm,
                                                     pImpl->aMore,
                                                     pImpl->bSpecModeWriter || pImpl->bSpecModeCalc, *this));
        pImpl->m_pBox = pImpl->m_xWeldBox.get();
    }
    else
    {
        VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
        if ( pParent )
        {
            SolarMutexGuard aSolarMutexGuard;

            pImpl->m_xVclBox = VclPtr<SvxStyleBox_Impl>::Create(pParent,
                                                                ".uno:StyleApply",
                                                                SfxStyleFamily::Para,
                                                                Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ),
                                                                m_xFrame,
                                                                pImpl->aClearForm,
                                                                pImpl->aMore,
                                                                pImpl->bSpecModeWriter || pImpl->bSpecModeCalc, *this);
            pImpl->m_pBox = pImpl->m_xVclBox.get();
            xItemWindow = VCLUnoHelper::GetInterface(pImpl->m_xVclBox);
        }
    }

    if (pImpl->m_pBox && !pImpl->aDefaultStyles.empty())
        pImpl->m_pBox->SetDefaultStyle(pImpl->aDefaultStyles[0]);

    return xItemWindow;
}

SvxFontNameToolBoxControl::SvxFontNameToolBoxControl()
@@ -2960,7 +3021,7 @@ void SvxFontNameToolBoxControl::statusChanged( const css::frame::FeatureStateEve
    }
}

css::uno::Reference< css::awt::XWindow > SvxFontNameToolBoxControl::createItemWindow( const css::uno::Reference< css::awt::XWindow >& rParent )
css::uno::Reference<css::awt::XWindow> SvxFontNameToolBoxControl::createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent)
{
    uno::Reference< awt::XWindow > xItemWindow;

diff --git a/svx/uiconfig/ui/applystylebox.ui b/svx/uiconfig/ui/applystylebox.ui
new file mode 100644
index 0000000..3dcd64b
--- /dev/null
+++ b/svx/uiconfig/ui/applystylebox.ui
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface domain="svx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkBox" id="ApplyStyleBox">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="spacing">6</property>
    <child>
      <object class="GtkComboBoxText" id="applystyle">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="hexpand">True</property>
        <property name="has_entry">True</property>
        <property name="popup_fixed_width">False</property>
        <child internal-child="entry">
          <object class="GtkEntry">
            <property name="can_focus">True</property>
          </object>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
  </object>
</interface>
diff --git a/svx/uiconfig/ui/sidebarlists.ui b/svx/uiconfig/ui/sidebarlists.ui
index 2f28064..3937f21 100644
--- a/svx/uiconfig/ui/sidebarlists.ui
+++ b/svx/uiconfig/ui/sidebarlists.ui
@@ -26,7 +26,6 @@
              <object class="GtkMenuToolButton" id=".uno:DefaultBullet">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="is_important">True</property>
                <property name="use_underline">True</property>
              </object>
              <packing>
@@ -38,7 +37,6 @@
              <object class="GtkMenuToolButton" id=".uno:DefaultNumbering">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="is_important">True</property>
                <property name="use_underline">True</property>
              </object>
              <packing>
diff --git a/svx/uiconfig/ui/sidebarparagraph.ui b/svx/uiconfig/ui/sidebarparagraph.ui
index ce0b0dd..49d18ae 100644
--- a/svx/uiconfig/ui/sidebarparagraph.ui
+++ b/svx/uiconfig/ui/sidebarparagraph.ui
@@ -627,7 +627,6 @@
                  <object class="GtkMenuToolButton" id=".uno:DefaultBullet">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="is_important">True</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
@@ -639,7 +638,6 @@
                  <object class="GtkMenuToolButton" id=".uno:DefaultNumbering">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="is_important">True</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
diff --git a/svx/uiconfig/ui/sidebarstylespanel.ui b/svx/uiconfig/ui/sidebarstylespanel.ui
index a495547..7e87f0a 100644
--- a/svx/uiconfig/ui/sidebarstylespanel.ui
+++ b/svx/uiconfig/ui/sidebarstylespanel.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.22.2 -->
<interface domain="svx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkGrid" id="SidebarStylesPanel">
@@ -21,19 +21,35 @@
            <property name="hexpand">True</property>
            <property name="orientation">vertical</property>
            <child>
              <object class="sfxlo-SidebarToolBox" id="fontstyletoolbox">
              <object class="GtkToolbar" id="fontstyletoolbox">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="toolbar_style">icons</property>
                <property name="show_arrow">False</property>
                <child>
                  <object class="GtkToolButton" id="fontstyle">
                  <object class="GtkToolItem" id=".uno:StyleApply">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="is_important">True</property>
                    <property name="action_name">.uno:StyleApply</property>
                    <property name="can_focus">False</property>
                    <property name="hexpand">True</property>
                    <child>
                      <object class="GtkComboBoxText" id="applystyle">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="hexpand">True</property>
                        <property name="has_entry">True</property>
                        <property name="popup_fixed_width">False</property>
                        <child internal-child="entry">
                          <object class="GtkEntry">
                            <property name="can_focus">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                  <packing>
                    <property name="expand">True</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
              </object>
@@ -55,15 +71,25 @@
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="sfxlo-SidebarToolBox" id="styleupdate">
              <object class="GtkToolbar" id="style">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="toolbar_style">icons</property>
                <property name="show_arrow">False</property>
                <child>
                  <object class="GtkToolButton" id="styleupdateexample">
                  <object class="GtkToolButton" id=".uno:StyleUpdateByExample">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="is_important">True</property>
                    <property name="action_name">.uno:StyleUpdateByExample</property>
                  </object>
                  <packing>
                    <property name="expand">True</property>
                    <property name="homogeneous">True</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkToolButton" id=".uno:StyleNewByExample">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                  </object>
                  <packing>
                    <property name="expand">True</property>
@@ -77,29 +103,6 @@
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="sfxlo-SidebarToolBox" id="stylenew">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <child>
                  <object class="GtkToolButton" id="stylenewexample">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="is_important">True</property>
                    <property name="action_name">.uno:StyleNewByExample</property>
                  </object>
                  <packing>
                    <property name="expand">True</property>
                    <property name="homogeneous">True</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
diff --git a/svx/util/svxcore.component b/svx/util/svxcore.component
index 2c5a103..f5a8113 100644
--- a/svx/util/svxcore.component
+++ b/svx/util/svxcore.component
@@ -62,6 +62,10 @@
    constructor="com_sun_star_comp_svx_FontNameToolBoxControl_get_implementation">
    <service name="com.sun.star.frame.ToolbarController"/>
  </implementation>
  <implementation name="com.sun.star.comp.svx.StyleToolBoxControl"
    constructor="com_sun_star_comp_svx_StyleToolBoxControl_get_implementation">
    <service name="com.sun.star.frame.ToolbarController"/>
  </implementation>
  <implementation name="com.sun.star.comp.svx.LineEndToolBoxControl"
      constructor="com_sun_star_comp_svx_LineEndToolBoxControl_get_implementation">
    <service name="com.sun.star.frame.ToolbarController"/>
diff --git a/sw/source/uibase/app/swmodule.cxx b/sw/source/uibase/app/swmodule.cxx
index d68c2ef..59b5d1e 100644
--- a/sw/source/uibase/app/swmodule.cxx
+++ b/sw/source/uibase/app/swmodule.cxx
@@ -286,8 +286,6 @@ void SwDLL::RegisterControls()
    SvxFillToolBoxControl::RegisterControl(SID_ATTR_FILL_STYLE, pMod );
    SvxLineWidthToolBoxControl::RegisterControl(SID_ATTR_LINE_WIDTH, pMod );

    SvxStyleToolBoxControl::RegisterControl(SID_STYLE_APPLY, pMod );

    SwZoomControl::RegisterControl(SID_ATTR_ZOOM, pMod );
    SwPreviewZoomControl::RegisterControl(FN_PREVIEW_ZOOM, pMod);
    SvxPosSizeStatusBarControl::RegisterControl(0, pMod );
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 35c6049..5313ae3 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -5691,6 +5691,8 @@ protected:
    // owner for ListBox/ComboBox UserData
    std::vector<std::unique_ptr<OUString>> m_aUserData;
    VclPtr<vcl_type> m_xComboBox;
    ScopedVclPtr<MenuButton> m_xMenuButton;
    OUString m_sMenuButtonRow;

public:
    SalInstanceComboBox(vcl_type* pComboBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
@@ -5714,7 +5716,10 @@ public:

    // ComboBoxes are comprised of multiple subwidgets, consider the lot as
    // one thing for focus
    virtual bool has_focus() const override { return m_xWidget->HasChildPathFocus(); }
    virtual bool has_focus() const override
    {
        return m_xWidget->HasChildPathFocus() || (m_xMenuButton && (m_xMenuButton->HasFocus() || m_xMenuButton->InPopupMode()));
    }

    virtual OUString get_active_id() const override
    {
@@ -5827,8 +5832,19 @@ public:
    {
        vcl::RenderContext* pRenderContext = pEvent->GetRenderContext();
        auto nPos = pEvent->GetItemId();
        signal_custom_render(*pRenderContext, pEvent->GetRect(), pEvent->IsSelected(), get_id(nPos));
        const tools::Rectangle& rRect = pEvent->GetRect();
        const OUString sId = get_id(nPos);
        signal_custom_render(*pRenderContext, rRect, pEvent->IsSelected(), sId);
        m_xComboBox->DrawEntry(*pEvent, false, false);  // draw separator

        if (m_xMenuButton && m_xMenuButton->IsVisible() && m_sMenuButtonRow == sId)
        {
            if (m_xMenuButton->GetParent() != pEvent->GetWindow())
                m_xMenuButton->SetParent(pEvent->GetWindow());
            int nButtonWidth = get_menu_button_width();
            m_xMenuButton->SetSizePixel(Size(nButtonWidth, rRect.GetHeight()));
            m_xMenuButton->SetPosPixel(Point(rRect.GetWidth() - nButtonWidth, rRect.getY()));
        }
    }

    VclPtr<VirtualDevice> create_render_virtual_device() const override
@@ -5836,10 +5852,30 @@ public:
        return VclPtr<VirtualDevice>::Create();
    }

    virtual void HandleEventListener(VclWindowEvent& rEvent) override
    virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) override
    {
        if (rEvent.GetId() == VclEventId::DropdownPreOpen
            || rEvent.GetId() == VclEventId::DropdownClose)
        SalInstanceMenu* pInstanceMenu = dynamic_cast<SalInstanceMenu*>(pMenu);

        PopupMenu* pPopup = pInstanceMenu ? pInstanceMenu->getMenu() : nullptr;

        if (!m_xMenuButton)
            m_xMenuButton = VclPtr<MenuButton>::Create(m_xComboBox, WB_FLATBUTTON | WB_NOPOINTERFOCUS);

        m_xMenuButton->SetPopupMenu(pPopup);
        m_xMenuButton->Show(pPopup != nullptr);
        m_sMenuButtonRow = OUString::fromUtf8(rIdent);
    }

    int get_menu_button_width() const override
    {
        const int nButtonWidth = 20;
        return nButtonWidth;
    }

    void CallHandleEventListener(VclWindowEvent& rEvent)
    {
        if (rEvent.GetId() == VclEventId::DropdownPreOpen ||
            rEvent.GetId() == VclEventId::DropdownClose)
        {
            signal_popup_toggled();
            return;
@@ -5947,6 +5983,11 @@ public:
        assert(false && "not implemented");
    }

    virtual void HandleEventListener(VclWindowEvent& rEvent) override
    {
        CallHandleEventListener(rEvent);
    }

    virtual ~SalInstanceComboBoxWithoutEdit() override
    {
        m_xComboBox->SetSelectHdl(Link<ListBox&, void>());
@@ -6083,9 +6124,7 @@ public:
        auto nOldEntryHeight = m_xComboBox->GetDropDownEntryHeight();
        auto nDropDownLineCount = m_xComboBox->GetDropDownLineCount();

        Size aRowSize(signal_custom_get_size(*m_xComboBox, OUString()));
        m_xComboBox->EnableUserDraw(true);
        m_xComboBox->SetUserItemSize(aRowSize);
        m_xComboBox->SetUserDrawHdl(LINK(this, SalInstanceComboBoxWithEdit, UserDrawHdl));

        // adjust the line count to fit approx the height it would have been before
@@ -6115,6 +6154,16 @@ public:
        m_xComboBox->SetMRUEntries(rEntries);
    }

    virtual void HandleEventListener(VclWindowEvent& rEvent) override
    {
        if (rEvent.GetId() == VclEventId::DropdownPreOpen)
        {
            Size aRowSize(signal_custom_get_size(*m_xComboBox));
            m_xComboBox->SetUserItemSize(aRowSize);
        }
        CallHandleEventListener(rEvent);
    }

    virtual ~SalInstanceComboBoxWithEdit() override
    {
        m_xComboBox->SetTextFilter(nullptr);
@@ -6251,6 +6300,17 @@ public:
        assert(false && "not implemented");
    }

    virtual void set_item_menu(const OString&, weld::Menu*) override
    {
        assert(false && "not implemented");
    }

    int get_menu_button_width() const override
    {
        assert(false && "not implemented");
        return 0;
    }

    VclPtr<VirtualDevice> create_render_virtual_device() const override
    {
        return VclPtr<VirtualDevice>::Create();
diff --git a/vcl/uiconfig/ui/combobox.ui b/vcl/uiconfig/ui/combobox.ui
index e5d3174..24b0787 100644
--- a/vcl/uiconfig/ui/combobox.ui
+++ b/vcl/uiconfig/ui/combobox.ui
@@ -64,6 +64,20 @@
      <class name="linked"/>
    </style>
  </object>
  <object class="GtkMenuButton" id="overlaybutton">
    <property name="can_focus">True</property>
    <property name="receives_default">True</property>
    <property name="no_show_all">True</property>
    <property name="draw_indicator">True</property>
    <property name="use_popover">False</property>
    <child>
      <object class="GtkImage" id="overlayarrow">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="icon_name">pan-down-symbolic</property>
      </object>
    </child>
  </object>
  <object class="GtkWindow" id="popup">
    <property name="name">gtk-combobox-popup-window</property>
    <property name="can_focus">False</property>
@@ -75,26 +89,34 @@
      <placeholder/>
    </child>
    <child>
      <object class="GtkScrolledWindow" id="scrolledwindow">
      <object class="GtkOverlay" id="overlay">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hscrollbar_policy">never</property>
        <property name="shadow_type">in</property>
        <property name="overlay_scrolling">False</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkTreeView" id="treeview">
          <object class="GtkScrolledWindow" id="scrolledwindow">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="headers_visible">False</property>
            <property name="headers_clickable">False</property>
            <property name="enable_search">False</property>
            <property name="search_column">0</property>
            <property name="show_expanders">False</property>
            <property name="activate_on_single_click">True</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection"/>
            <property name="hscrollbar_policy">never</property>
            <property name="shadow_type">in</property>
            <property name="overlay_scrolling">False</property>
            <child>
              <object class="GtkTreeView" id="treeview">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="headers_visible">False</property>
                <property name="enable_search">False</property>
                <property name="search_column">0</property>
                <property name="show_expanders">False</property>
                <property name="activate_on_single_click">True</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection"/>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="index">-1</property>
          </packing>
        </child>
      </object>
    </child>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 4a0f975..04a6f68 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -8899,6 +8899,21 @@ int get_height_rows(int nRowHeight, int nSeparatorHeight, int nRows)
    return (nRowHeight * nRows) + (nSeparatorHeight * (nRows + 1));
}

tools::Rectangle get_row_area(GtkTreeView* pTreeView, GList* pColumns, GtkTreePath* pPath)
{
    tools::Rectangle aRet;

    GdkRectangle aRect;
    for (GList* pEntry = g_list_last(pColumns); pEntry; pEntry = g_list_previous(pEntry))
    {
        GtkTreeViewColumn* pColumn = GTK_TREE_VIEW_COLUMN(pEntry->data);
        gtk_tree_view_get_cell_area(pTreeView, pPath, pColumn, &aRect);
        aRet.Union(tools::Rectangle(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y + aRect.height));
    }

    return aRet;
}

class GtkInstanceTreeView : public GtkInstanceContainer, public virtual weld::TreeView
{
private:
@@ -11042,22 +11057,11 @@ public:

    virtual tools::Rectangle get_row_area(const weld::TreeIter& rIter) const override
    {
        tools::Rectangle aRet;

        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreePath* pPath = gtk_tree_model_get_path(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter));

        GdkRectangle aRect;
        for (GList* pEntry = g_list_last(m_pColumns); pEntry; pEntry = g_list_previous(pEntry))
        {
            GtkTreeViewColumn* pColumn = GTK_TREE_VIEW_COLUMN(pEntry->data);
            gtk_tree_view_get_cell_area(m_pTreeView, pPath, pColumn, &aRect);
            aRet.Union(tools::Rectangle(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y + aRect.height));
        }

        tools::Rectangle aRet = ::get_row_area(m_pTreeView, m_pColumns, pPath);
        gtk_tree_path_free(pPath);

        return aRet;
    }

@@ -12529,12 +12533,32 @@ struct GtkTreeRowReferenceDeleter
    }
};

// pop down the toplevel combobox menu when something is activated from a custom
// submenu, i.e. wysiwyg style menu
class CustomRenderMenuButtonHelper : public MenuHelper
{
private:
    GtkToggleButton* m_pComboBox;
public:
    CustomRenderMenuButtonHelper(GtkMenu* pMenu, GtkToggleButton* pComboBox)
        : MenuHelper(pMenu, false)
        , m_pComboBox(pComboBox)
    {
    }
    virtual void signal_activate(GtkMenuItem*) override
    {
        gtk_toggle_button_set_active(m_pComboBox, false);
    }
};

class GtkInstanceComboBox : public GtkInstanceContainer, public vcl::ISearchableStringList, public virtual weld::ComboBox
{
private:
    GtkBuilder* m_pComboBuilder;
    GtkComboBox* m_pComboBox;
    GtkOverlay* m_pOverlay;
    GtkTreeView* m_pTreeView;
    GtkMenuButton* m_pOverlayButton; // button that the StyleDropdown uses on an active row
    GtkWindow* m_pMenuWindow;
    GtkTreeModel* m_pTreeModel;
    GtkCellRenderer* m_pButtonTextRenderer;
@@ -12542,11 +12566,14 @@ private:
    GtkWidget* m_pToggleButton;
    GtkWidget* m_pEntry;
    GtkCellView* m_pCellView;
    std::unique_ptr<CustomRenderMenuButtonHelper> m_xCustomMenuButtonHelper;
    std::unique_ptr<vcl::Font> m_xFont;
    std::unique_ptr<comphelper::string::NaturalStringSorter> m_xSorter;
    vcl::QuickSelectionEngine m_aQuickSelectionEngine;
    std::vector<std::unique_ptr<GtkTreeRowReference, GtkTreeRowReferenceDeleter>> m_aSeparatorRows;
    OUString m_sMenuButtonRow;
    bool m_bHoverSelection;
    bool m_bMouseInOverlayButton;
    bool m_bPopupActive;
    bool m_bAutoComplete;
    bool m_bAutoCompleteCaseSensitive;
@@ -13296,7 +13323,7 @@ private:
    void signal_motion()
    {
        // if hover-selection was disabled after pressing a key, then turn it back on again
        if (!m_bHoverSelection)
        if (!m_bHoverSelection && !m_bMouseInOverlayButton)
        {
            gtk_tree_view_set_hover_selection(m_pTreeView, true);
            m_bHoverSelection = true;
@@ -13366,8 +13393,6 @@ private:
                    break;
                }
            }

//TODO            set_active(0);
        }

        while (m_nMRUCount > m_nMaxMRUCount)
@@ -13489,12 +13514,70 @@ private:
        enable_notify_events();
    }

    static gboolean signalGetChildPosition(GtkOverlay*, GtkWidget*, GdkRectangle* pAllocation, gpointer widget)
    {
        GtkInstanceComboBox* pThis = static_cast<GtkInstanceComboBox*>(widget);
        return pThis->signal_get_child_position(pAllocation);
    }

    bool signal_get_child_position(GdkRectangle* pAllocation)
    {
        if (!gtk_widget_get_visible(GTK_WIDGET(m_pOverlayButton)))
            return false;
        if (!gtk_widget_get_realized(GTK_WIDGET(m_pTreeView)))
            return false;
        int nRow = find_id_including_mru(m_sMenuButtonRow, true);
        if (nRow == -1)
            return false;

        gtk_widget_get_preferred_width(GTK_WIDGET(m_pOverlayButton), &pAllocation->width, nullptr);

        GtkTreePath* pPath = gtk_tree_path_new_from_indices(nRow, -1);
        GList* pColumns = gtk_tree_view_get_columns(m_pTreeView);
        tools::Rectangle aRect = get_row_area(m_pTreeView, pColumns, pPath);
        gtk_tree_path_free(pPath);
        g_list_free(pColumns);

        pAllocation->x = aRect.Right() - pAllocation->width;
        pAllocation->y = aRect.Top();
        pAllocation->height = aRect.GetHeight();

        return true;
    }

    static gboolean signalOverlayButtonCrossing(GtkWidget*, GdkEventCrossing* pEvent, gpointer widget)
    {
        GtkInstanceComboBox* pThis = static_cast<GtkInstanceComboBox*>(widget);
        pThis->signal_overlay_button_crossing(pEvent->type == GDK_ENTER_NOTIFY);
        return false;
    }

    void signal_overlay_button_crossing(bool bEnter)
    {
        m_bMouseInOverlayButton = bEnter;
        if (bEnter)
        {
            if (m_bHoverSelection)
            {
                // once toggled button is pressed, turn off hover selection until
                // mouse leaves the overlay button
                gtk_tree_view_set_hover_selection(m_pTreeView, false);
                m_bHoverSelection = false;
            }
            int nRow = find_id_including_mru(m_sMenuButtonRow, true);
            assert(nRow != -1);
            tree_view_set_cursor(nRow); // select the buttons row
        }
    }

public:
    GtkInstanceComboBox(GtkBuilder* pComboBuilder, GtkComboBox* pComboBox, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
        : GtkInstanceContainer(GTK_CONTAINER(gtk_builder_get_object(pComboBuilder, "box")), pBuilder, bTakeOwnership)
        , m_pComboBuilder(pComboBuilder)
        , m_pComboBox(pComboBox)
        , m_pOverlay(GTK_OVERLAY(gtk_builder_get_object(pComboBuilder, "overlay")))
        , m_pTreeView(GTK_TREE_VIEW(gtk_builder_get_object(pComboBuilder, "treeview")))
        , m_pOverlayButton(GTK_MENU_BUTTON(gtk_builder_get_object(pComboBuilder, "overlaybutton")))
        , m_pMenuWindow(GTK_WINDOW(gtk_builder_get_object(pComboBuilder, "popup")))
        , m_pTreeModel(gtk_combo_box_get_model(pComboBox))
        , m_pButtonTextRenderer(nullptr)
@@ -13503,6 +13586,7 @@ public:
        , m_pCellView(nullptr)
        , m_aQuickSelectionEngine(*this)
        , m_bHoverSelection(false)
        , m_bMouseInOverlayButton(false)
        , m_bPopupActive(false)
        , m_bAutoComplete(false)
        , m_bAutoCompleteCaseSensitive(false)
@@ -13615,6 +13699,11 @@ public:
        // support typeahead for the menu itself, typing into the menu will
        // select via the vcl selection engine, a matching entry.
        g_signal_connect(m_pMenuWindow, "key-press-event", G_CALLBACK(signalKeyPress), this);

        g_signal_connect(m_pOverlay, "get-child-position", G_CALLBACK(signalGetChildPosition), this);
        gtk_overlay_add_overlay(m_pOverlay, GTK_WIDGET(m_pOverlayButton));
        g_signal_connect(m_pOverlayButton, "leave-notify-event", G_CALLBACK(signalOverlayButtonCrossing), this);
        g_signal_connect(m_pOverlayButton, "enter-notify-event", G_CALLBACK(signalOverlayButtonCrossing), this);
    }

    virtual int get_active() const override
@@ -13986,7 +14075,9 @@ public:

    virtual bool has_focus() const override
    {
        return gtk_widget_has_focus(m_pToggleButton) || gtk_widget_has_focus(m_pEntry) || GtkInstanceWidget::has_focus();
        return gtk_widget_has_focus(m_pToggleButton) || gtk_widget_has_focus(m_pEntry) ||
               gtk_widget_has_focus(GTK_WIDGET(m_pOverlayButton)) ||
               gtk_widget_has_focus(GTK_WIDGET(m_pTreeView)) || GtkInstanceWidget::has_focus();
    }

    virtual bool changed_by_direct_pick() const override
@@ -14017,9 +14108,9 @@ public:
        signal_custom_render(rOutput, rRect, bSelected, rId);
    }

    Size call_signal_custom_get_size(VirtualDevice& rOutput, const OUString& rId)
    Size call_signal_custom_get_size(VirtualDevice& rOutput)
    {
        return signal_custom_get_size(rOutput, rId);
        return signal_custom_get_size(rOutput);
    }

    VclPtr<VirtualDevice> create_render_virtual_device() const override
@@ -14027,6 +14118,19 @@ public:
        return create_virtual_device();
    }

    virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) override
    {
        m_xCustomMenuButtonHelper.reset();
        GtkInstanceMenu* pPopoverWidget = dynamic_cast<GtkInstanceMenu*>(pMenu);
        GtkWidget* pMenuWidget = GTK_WIDGET(pPopoverWidget ? pPopoverWidget->getMenu() : nullptr);
        gtk_menu_button_set_popup(m_pOverlayButton, pMenuWidget);
        gtk_widget_set_visible(GTK_WIDGET(m_pOverlayButton), pMenuWidget != nullptr);
        gtk_widget_queue_resize_no_redraw(GTK_WIDGET(m_pOverlayButton)); // force location recalc
        if (pMenuWidget)
            m_xCustomMenuButtonHelper.reset(new CustomRenderMenuButtonHelper(GTK_MENU(pMenuWidget), GTK_TOGGLE_BUTTON(m_pToggleButton)));
        m_sMenuButtonRow = OUString::fromUtf8(rIdent);
    }

    OUString get_mru_entries() const override
    {
        const sal_Unicode cSep = ';';
@@ -14073,8 +14177,21 @@ public:
        m_nMRUCount = nMRUCount;
    }

    int get_menu_button_width() const override
    {
        bool bVisible = gtk_widget_get_visible(GTK_WIDGET(m_pOverlayButton));
        if (!bVisible)
            gtk_widget_set_visible(GTK_WIDGET(m_pOverlayButton), true);
        gint nWidth;
        gtk_widget_get_preferred_width(GTK_WIDGET(m_pOverlayButton), &nWidth, nullptr);
        if (!bVisible)
            gtk_widget_set_visible(GTK_WIDGET(m_pOverlayButton), false);
        return nWidth;
    }

    virtual ~GtkInstanceComboBox() override
    {
        m_xCustomMenuButtonHelper.reset();
        do_clear();
        if (m_nAutoCompleteIdleId)
            g_source_remove(m_nAutoCompleteIdleId);
@@ -14129,7 +14246,7 @@ bool custom_cell_renderer_surface_get_preferred_size(GtkCellRenderer *cell,
    if (GtkInstanceTreeView* pTreeView = dynamic_cast<GtkInstanceTreeView*>(pWidget))
        aSize = pTreeView->call_signal_custom_get_size(*cellsurface->device, sId);
    else if (GtkInstanceComboBox* pComboBox = dynamic_cast<GtkInstanceComboBox*>(pWidget))
        aSize = pComboBox->call_signal_custom_get_size(*cellsurface->device, sId);
        aSize = pComboBox->call_signal_custom_get_size(*cellsurface->device);

    if (orientation == GTK_ORIENTATION_HORIZONTAL)
    {
@@ -14446,11 +14563,22 @@ public:
        assert(false && "not implemented");
    }

    virtual void set_item_menu(const OString&, weld::Menu*) override
    {
        assert(false && "not implemented");
    }

    VclPtr<VirtualDevice> create_render_virtual_device() const override
    {
        return create_virtual_device();
    }

    int get_menu_button_width() const override
    {
        assert(false && "not implemented");
        return 0;
    }

    virtual ~GtkInstanceEntryTreeView() override
    {
        if (m_nAutoCompleteIdleId)