Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/svx/source/tbxctrls/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 149 kB image not shown  

Quelle  tbcontrl.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <utility>

#include <comphelper/configurationlistener.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/propertyvalue.hxx>
#include <tools/color.hxx>
#include <svl/numformat.hxx>
#include <svl/poolitem.hxx>
#include <svl/itemset.hxx>
#include <svl/itempool.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <vcl/event.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/customweld.hxx>
#include <vcl/vclptr.hxx>
#include <vcl/weldutils.hxx>
#include <svtools/valueset.hxx>
#include <svtools/ctrlbox.hxx>
#include <svl/style.hxx>
#include <svtools/ctrltool.hxx>
#include <svtools/borderhelper.hxx>
#include <vcl/InterimItemWindow.hxx>
#include <sfx2/tbxctrl.hxx>
#include <sfx2/tplpitem.hxx>
#include <sfx2/sfxstatuslistener.hxx>
#include <sfx2/viewsh.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/virdev.hxx>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <svx/strings.hrc>
#include <svx/svxids.hrc>
#include <helpids.h>
#include <sfx2/sidebar/Sidebar.hxx>
#include <svx/xtable.hxx>
#include <editeng/editids.hrc>
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/charreliefitem.hxx>
#include <editeng/contouritem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/crossedoutitem.hxx>
#include <editeng/emphasismarkitem.hxx>
#include <editeng/flstitem.hxx>
#include <editeng/lineitem.hxx>
#include <editeng/postitem.hxx>
#include <editeng/shdditem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/svxfont.hxx>
#include <editeng/cmapitem.hxx>
#include <svx/colorwindow.hxx>
#include <svx/colorbox.hxx>
#include <svx/tbcontrl.hxx>
#include <svx/dialmgr.hxx>
#include <svx/PaletteManager.hxx>
#include <memory>

#include <tbxcolorupdate.hxx>
#include <editeng/eerdll.hxx>
#include <editeng/editrids.hrc>
#include <svx/xdef.hxx>
#include <svx/xfillit0.hxx>
#include <svx/xflclit.hxx>
#include <svl/currencytable.hxx>
#include <svtools/langtab.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <officecfg/Office/Common.hxx>
#include <o3tl/temporary.hxx>
#include <o3tl/safeint.hxx>
#include <o3tl/string_view.hxx>
#include <o3tl/typed_flags_set.hxx>
#include <bitmaps.hlst>
#include <sal/log.hxx>
#include <unotools/collatorwrapper.hxx>
#include <sfx2/IDocumentModelAccessor.hxx>

#include <comphelper/lok.hxx>
#include <tools/json_writer.hxx>

#include <editeng/editeng.hxx>

#define MAX_MRU_FONTNAME_ENTRIES    5

#define COMBO_WIDTH_IN_CHARS        18

// namespaces
using namespace ::editeng;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;

namespace
{
struct ScriptInfo
{
    tools::Long textWidth;
    SvtScriptType scriptType;
    sal_Int32 changePos;
    ScriptInfo(SvtScriptType scrptType, sal_Int32 position)
        : textWidth(0)
        , scriptType(scrptType)
        , changePos(position)
    {
    }
};

class SvxStyleBox_Base
{
public:
    SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget, OUString  rCommand, SfxStyleFamily eFamily,
                     const Reference<XFrame>& _xFrame, OUString aClearFormatKey,
                     OUString aMoreKey, bool bInSpecialMode, SvxStyleToolBoxControl& rCtrl);

    virtual ~SvxStyleBox_Base()
    {
    }

    void            SetFamily( SfxStyleFamily eNewFamily );

    void            SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }

    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(); }

    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);
    }

    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);
    }

    int find_text(const OUString& rText)
    {
        return m_xWidget->find_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:
    std::optional<SvxFont> m_oFont;
    std::optional<SvxFont> m_oCJKFont;
    std::optional<SvxFont> m_oCTLFont;

    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, tools::JsonWriter&, 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);

    tools::Rectangle CalcBoundRect(vcl::RenderContext& rRenderContext, const OUString &rStyleName, std::vector<ScriptInfo>& rScriptChanges, double fRatio = 1);

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;
    int                             m_nMaxUserDrawFontWidth;
    int                             m_nLastItemWithMenu;
    bool                            bRelease;
    Reference< XFrame >             m_xFrame;
    OUString                        m_aCommand;
    OUString                        aClearFormatKey;
    OUString                        aMoreKey;
    OUString                        sDefaultStyle;
    bool                            bInSpecialMode;

    void            ReleaseFocus();
    static Color    TestColorsVisible(const Color &FontCol, const Color &BackCol);
    void            UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle&&nbsp;rRect, const tools::Rectangle& rTextRect, const OUString &rStyleName, const std::vector<ScriptInfo>& rScriptChanges);
    void            SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, std::u16string_view rStyleName, bool bIsNotSelected);
    DECL_LINK(MenuSelectHdl, const OUString&, void);
    DECL_STATIC_LINK(SvxStyleBox_Base, ShowMoreHdl, void*, void);
};

class SvxStyleBox_Impl final : public InterimItemWindow
                             , public SvxStyleBox_Base
{
public:
    SvxStyleBox_Impl(vcl::Window* pParent, const OUString& rCommand, SfxStyleFamily eFamily,
                     const Reference< XFrame >& _xFrame,const OUString& rClearFormatKey, const OUString&&nbsp;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 DataChanged(const DataChangedEvent& rDCEvt) override;
    void  SetOptimalSize();
};

class SvxFontNameBox_Impl;
class SvxFontNameBox_Base;

class SvxFontNameToolBoxControl final : public cppu::ImplInheritanceHelper<svt::ToolboxController,
                                                                           css::lang::XServiceInfo>
{
public:
    SvxFontNameToolBoxControl();

    // XStatusListener
    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;

    // 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:
    VclPtr<SvxFontNameBox_Impl> m_xVclBox;
    std::unique_ptr<SvxFontNameBox_Base> m_xWeldBox;
    SvxFontNameBox_Base* m_pBox;
};

class FontOptionsListener final : public comphelper::ConfigurationListenerProperty<bool>
{
private:
    SvxFontNameBox_Base& m_rBox;

    virtual void setProperty(const css::uno::Any &rProperty) override;
public:
    FontOptionsListener(const rtl::Reference<comphelper::ConfigurationListener>& rListener, const OUString& rProp, SvxFontNameBox_Base& rBox)
        : comphelper::ConfigurationListenerProperty<bool>(rListener, rProp)
        , m_rBox(rBox)
    {
    }
};

class SvxFontNameBox_Base
{
private:
    rtl::Reference<comphelper::ConfigurationListener> m_xListener;
    FontOptionsListener m_aWYSIWYG;
    FontOptionsListener m_aHistory;

protected:
    SvxFontNameToolBoxControl& m_rCtrl;

    std::unique_ptr<FontNameBox>   m_xWidget;
    const FontList*                pFontList;
    ::std::unique_ptr<FontList>    m_aOwnFontList;
    vcl::Font                      aCurFont;
    sal_uInt16                     nFtCount;
    bool                           bRelease;
    Reference< XFrame >            m_xFrame;
    bool            mbCheckingUnknownFont;
    bool            mbDropDownActive;

    void            ReleaseFocus_Impl();

    void            Select(bool bNonTravelSelect);

    void            EndPreview()
    {
        Sequence< PropertyValue > aArgs;
        const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
        SfxToolBoxControl::Dispatch(xProvider, u".uno:CharEndPreviewFontName"_ustr, aArgs);
    }

    bool            CheckFontIsAvailable(std::u16string_view fontname);
    void            CheckAndMarkUnknownFont();

public:
    SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget, const Reference<XFrame>&&nbsp;rFrame,
                        SvxFontNameToolBoxControl& rCtrl);
    virtual ~SvxFontNameBox_Base()
    {
        m_xListener->dispose();
    }

    void            FillList();
    void            Update( const css::awt::FontDescriptor* pFontDesc );
    sal_uInt16      GetListCount() const { return nFtCount; }
    void            Clear() { m_xWidget->clear(); nFtCount = 0; }
    void            Fill( const FontList* pList )
    {
        m_xWidget->Fill(pList);
        nFtCount = pList->GetFontNameCount();
    }

    void SetOwnFontList(::std::unique_ptr<FontList> && _aOwnFontList) { m_aOwnFontList = std::move(_aOwnFontList); }

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

    void set_active_or_entry_text(const OUString& rText);

    void statusChanged_Impl(const css::frame::FeatureStateEvent& rEvent);

    virtual bool DoKeyInput(const KeyEvent& rKEvt);

    void EnableControls();

    DECL_LINK(SelectHdl, weld::ComboBox&, void);
    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
    DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
    DECL_LINK(FocusInHdl, weld::Widget&, void);
    DECL_LINK(FocusOutHdl, weld::Widget&, void);
    DECL_LINK(PopupToggledHdl, weld::ComboBox&, void);
    DECL_LINK(LivePreviewHdl, const FontMetric&, void);
    DECL_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void);
};

void FontOptionsListener::setProperty(const css::uno::Any &rProperty)
{
    comphelper::ConfigurationListenerProperty<bool>::setProperty(rProperty);
    m_rBox.EnableControls();
}

class SvxFontNameBox_Impl final : public InterimItemWindow
                                , public SvxFontNameBox_Base
{
private:
    virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
    virtual void GetFocus() override
    {
        if (m_xWidget)
            m_xWidget->grab_focus();
        InterimItemWindow::GetFocus();
    }

    void            SetOptimalSize();

    virtual bool DoKeyInput(const KeyEvent& rKEvt) override;

public:
    SvxFontNameBox_Impl(vcl::Window* pParent,
                        const Reference<XFrame>& rFrame, SvxFontNameToolBoxControl& rCtrl);

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

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

    virtual Reference< css::accessibility::XAccessible > CreateAccessible() override;

    virtual void StateChanged(StateChangedType nStateChange) override
    {
        if (nStateChange == StateChangedType::Enable)
            m_xWidget->set_sensitive(IsEnabled());
        InterimItemWindow::StateChanged(nStateChange);
    }

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


// SelectHdl needs the Modifiers, get them in MouseButtonUp
class SvxFrmValueSet_Impl final : public ValueSet
{
private:
    sal_uInt16 nModifier;

    virtual bool MouseButtonUp(const MouseEvent& rMEvt) override
    {
        nModifier = rMEvt.GetModifier();
        return ValueSet::MouseButtonUp(rMEvt);
    }

public:
    SvxFrmValueSet_Impl()
        : ValueSet(nullptr)
        , nModifier(0)
    {
    }
    sal_uInt16 GetModifier() const {return nModifier;}
};

}

namespace {

class SvxFrameToolBoxControl;

class SvxFrameWindow_Impl final : public WeldToolbarPopup
{
private:
    rtl::Reference<SvxFrameToolBoxControl> mxControl;
    std::unique_ptr<SvxFrmValueSet_Impl> mxFrameSet;
    std::unique_ptr<weld::CustomWeld> mxFrameSetWin;
    std::vector<std::pair<BitmapEx, OUString>> aImgVec;
    bool                        bParagraphMode;
    bool                        m_bIsWriter;
    bool                        m_bIsCalc;

    void InitImageList();
    void CalcSizeValueSet();
    DECL_LINK( SelectHdl, ValueSet*, void );

    void SetDiagonalDownBorder(const SvxLineItem& dDownLineItem);
    void SetDiagonalUpBorder(const SvxLineItem& dUpLineItem);

public:
    SvxFrameWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent);
    virtual void GrabFocus() override
    {
        mxFrameSet->GrabFocus();
    }

    virtual void    statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
};

class SvxFrameToolBoxControl : public svt::PopupWindowController
{
public:
    explicit SvxFrameToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rContext );

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

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() override;
    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;

    virtual void SAL_CALL execute(sal_Int16 nKeyModifier) override;
private:
    virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
    virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
};

    class LineListBox final : public ValueSet
    {
    public:
        typedef Color (*ColorFunc)(Color);
        typedef Color (*ColorDistFunc)(Color, Color);

        LineListBox();

        /** Set the width in Twips */
        Size SetWidth( tools::Long nWidth )
        {
            tools::Long nOldWidth = m_nWidth;
            m_nWidth = nWidth;
            return UpdateEntries( nOldWidth );
        }

        void SetNone( const OUString& sNone )
        {
            m_sNone = sNone;
        }

        /** Insert a listbox entry with all widths in Twips. */
        void            InsertEntry(const BorderWidthImpl& rWidthImpl,
                            SvxBorderLineStyle nStyle, tools::Long nMinWidth = 0,
                            ColorFunc pColor1Fn = &sameColor,
                            ColorFunc pColor2Fn = &sameColor,
                            ColorDistFunc pColorDistFn = &sameDistColor);

        SvxBorderLineStyle GetEntryStyle( sal_Int32 nPos ) const;

        SvxBorderLineStyle GetSelectEntryStyle() const;

        void            SetSourceUnit( FieldUnit eNewUnit ) { eSourceUnit = eNewUnit; }

        const Color&    GetColor() const { return aColor; }

        virtual void    SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
    private:

        void         ImpGetLine(tools::Long nLine1, tools::Long nLine2, tools::Long nDistance,
                                Color nColor1, Color nColor2, Color nColorDist,
                                SvxBorderLineStyle nStyle, BitmapEx& rBmp);

        void            UpdatePaintLineColor();       // returns sal_True if maPaintCol has changed

        Size            UpdateEntries( tools::Long nOldWidth );
        sal_Int32       GetStylePos( sal_Int32  nListPos, tools::Long nWidth );

        const Color& GetPaintColor() const
        {
            return maPaintCol;
        }

        Color   GetColorLine1( sal_Int32  nPos );
        Color   GetColorLine2( sal_Int32  nPos );
        Color   GetColorDist( sal_Int32  nPos );

                        LineListBox( const LineListBox& ) = delete;
        LineListBox&    operator =( const LineListBox& ) = delete;

        std::vector<std::unique_ptr<ImpLineListData>> m_vLineList;
        tools::Long            m_nWidth;
        OUString        m_sNone;
        ScopedVclPtr<VirtualDevice>   aVirDev;
        Size            aTxtSize;
        Color const     aColor;
        Color           maPaintCol;
        FieldUnit       eSourceUnit;
    };

    SvxBorderLineStyle LineListBox::GetSelectEntryStyle() const
    {
        SvxBorderLineStyle nStyle = SvxBorderLineStyle::SOLID;
        size_t nPos = GetSelectItemPos();
        if (nPos != VALUESET_ITEM_NOTFOUND)
        {
            if (!m_sNone.isEmpty())
                --nPos;
            nStyle = GetEntryStyle( nPos );
        }

        return nStyle;
    }

    void LineListBox::ImpGetLine( tools::Long nLine1, tools::Long nLine2, tools::Long nDistance,
                                Color aColor1, Color aColor2, Color aColorDist,
                                SvxBorderLineStyle nStyle, BitmapEx& rBmp )
    {
        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 );

        // SourceUnit to Twips
        if ( eSourceUnit == FieldUnit::POINT )
        {
            nLine1      /= 5;
            nLine2      /= 5;
            nDistance   /= 5;
        }

        // Paint the lines
        aSize = aVirDev->PixelToLogic( aSize );
        tools::Long nPix = aVirDev->PixelToLogic( Size( 0, 1 ) ).Height();
        sal_uInt32 n1 = nLine1;
        sal_uInt32 n2 = nLine2;
        tools::Long nDist  = nDistance;
        n1 += nPix-1;
        n1 -= n1%nPix;
        if ( n2 )
        {
            nDist += nPix-1;
            nDist -= nDist%nPix;
            n2    += nPix-1;
            n2    -= n2%nPix;
        }
        tools::Long nVirHeight = n1+nDist+n2;
        if ( nVirHeight > aSize.Height() )
            aSize.setHeight( nVirHeight );
        // negative width should not be drawn
        if ( aSize.Width() <= 0 )
            return;

        Size aVirSize = aVirDev->LogicToPixel( aSize );
        if ( aVirDev->GetOutputSizePixel() != aVirSize )
            aVirDev->SetOutputSizePixel( aVirSize );
        aVirDev->SetFillColor( aColorDist );
        aVirDev->DrawRect( tools::Rectangle( Point(), aSize ) );

        aVirDev->SetFillColor( aColor1 );

        double y1 = double( n1 ) / 2;
        svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y1 ), basegfx::B2DPoint( aSize.Width( ), y1 ), n1, nStyle );

        if ( n2 )
        {
            double y2 =  n1 + nDist + double( n2 ) / 2;
            aVirDev->SetFillColor( aColor2 );
            svtools::DrawLine( *aVirDev, basegfx::B2DPoint( 0, y2 ), basegfx::B2DPoint( aSize.Width(), y2 ), n2, SvxBorderLineStyle::SOLID );
        }
        rBmp = aVirDev->GetBitmapEx( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
    }

    LineListBox::LineListBox()
        : ValueSet(nullptr)
        , m_nWidth( 5 )
        , aVirDev(VclPtr<VirtualDevice>::Create())
        , aColor(Application::GetSettings().GetStyleSettings().GetWindowTextColor())
        , maPaintCol(COL_BLACK)
        , eSourceUnit(FieldUnit::POINT)
    {
        aVirDev->SetLineColor();
        aVirDev->SetMapMode( MapMode( MapUnit::MapTwip ) );
    }

    void LineListBox::SetDrawingArea(weld::DrawingArea* pDrawingArea)
    {
        ValueSet::SetDrawingArea(pDrawingArea);

        OutputDevice& rDevice = pDrawingArea->get_ref_device();

        aTxtSize.setWidth( rDevice.approximate_digit_width() );
        aTxtSize.setHeight( rDevice.GetTextHeight() );

        UpdatePaintLineColor();
    }

    sal_Int32 LineListBox::GetStylePos( sal_Int32 nListPos, tools::Long nWidth )
    {
        sal_Int32 nPos = -1;
        if (!m_sNone.isEmpty())
            nListPos--;

        sal_Int32 n = 0;
        size_t i = 0;
        size_t nCount = m_vLineList.size();
        while ( nPos == -1 && i < nCount )
        {
            auto& pData = m_vLineList[ i ];
            if ( pData->GetMinWidth() <= nWidth )
            {
                if ( nListPos == n )
                    nPos = static_cast<sal_Int32>(i);
                n++;
            }
            i++;
        }

        return nPos;
    }

    void LineListBox::InsertEntry(
        const BorderWidthImpl& rWidthImpl, SvxBorderLineStyle nStyle, tools::Long nMinWidth,
        ColorFunc pColor1Fn, ColorFunc pColor2Fn, ColorDistFunc pColorDistFn )
    {
        m_vLineList.emplace_back(new ImpLineListData(
            rWidthImpl, nStyle, nMinWidth, pColor1Fn, pColor2Fn, pColorDistFn));
    }

    SvxBorderLineStyle LineListBox::GetEntryStyle( sal_Int32 nPos ) const
    {
        ImpLineListData* pData = (0 <= nPos && o3tl::make_unsigned(nPos) < m_vLineList.size()) ? m_vLineList[ nPos ].get() : nullptr;
        return pData ? pData->GetStyle() : SvxBorderLineStyle::NONE;
    }

    void LineListBox::UpdatePaintLineColor()
    {
        const StyleSettings&    rSettings = Application::GetSettings().GetStyleSettings();
        Color                   aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );

        bool bRet = aNewCol != maPaintCol;

        if( bRet )
            maPaintCol = aNewCol;
    }

    Size LineListBox::UpdateEntries( tools::Long nOldWidth )
    {
        Size aSize;

        UpdatePaintLineColor( );

        sal_Int32      nSelEntry = GetSelectItemPos();
        sal_Int32       nTypePos = GetStylePos( nSelEntry, nOldWidth );

        // Remove the old entries
        Clear();

        sal_uInt16 nId(1);

        // Add the new entries based on the defined width
        if (!m_sNone.isEmpty())
            InsertItem(nId++, Image(), m_sNone);

        sal_uInt16 n = 0;
        sal_uInt16 nCount = m_vLineList.size( );
        while ( n < nCount )
        {
            auto& pData = m_vLineList[ n ];
            if ( pData->GetMinWidth() <= m_nWidth )
            {
                BitmapEx aBmp;
                ImpGetLine( pData->GetLine1ForWidth( m_nWidth ),
                        pData->GetLine2ForWidth( m_nWidth ),
                        pData->GetDistForWidth( m_nWidth ),
                        GetColorLine1( GetItemCount( ) ),
                        GetColorLine2( GetItemCount( ) ),
                        GetColorDist( GetItemCount( ) ),
                        pData->GetStyle(), aBmp );
                InsertItem(nId, Image(aBmp), SvtLineListBox::GetLineStyleName(pData->GetStyle()));
                Size aBmpSize = aBmp.GetSizePixel();
                if (aBmpSize.Width() > aSize.Width())
                    aSize.setWidth(aBmpSize.getWidth());
                if (aBmpSize.Height() > aSize.Height())
                    aSize.setHeight(aBmpSize.getHeight());
                if ( n == nTypePos )
                    SelectItem(nId);
            }
            else if ( n == nTypePos )
                SetNoSelection();
            n++;
            ++nId;
        }

        Invalidate();

        return aSize;
    }

    Color LineListBox::GetColorLine1( sal_Int32 nPos )
    {
        sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
        if (nStyle == -1)
            return GetPaintColor( );
        auto& pData = m_vLineList[ nStyle ];
        return pData->GetColorLine1( GetColor( ) );
    }

    Color LineListBox::GetColorLine2( sal_Int32 nPos )
    {
        sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
        if (nStyle == -1)
            return GetPaintColor( );
        auto& pData = m_vLineList[ nStyle ];
        return pData->GetColorLine2( GetColor( ) );
    }

    Color LineListBox::GetColorDist( sal_Int32 nPos )
    {
        Color rResult = Application::GetSettings().GetStyleSettings().GetFieldColor();

        sal_Int32 nStyle = GetStylePos( nPos, m_nWidth );
        if (nStyle == -1)
            return rResult;
        auto& pData = m_vLineList[ nStyle ];
        return pData->GetColorDist( GetColor( ), rResult );
    }
}

namespace {

class SvxLineWindow_Impl final : public WeldToolbarPopup
{
private:
    rtl::Reference<SvxFrameToolBoxControl> m_xControl;
    std::unique_ptr<LineListBox> m_xLineStyleLb;
    std::unique_ptr<weld::CustomWeld> m_xLineStyleLbWin;
    bool                m_bIsWriter;

    DECL_LINK( SelectHdl, ValueSet*, void );

public:
    SvxLineWindow_Impl(SvxFrameToolBoxControl* pControl, weld::Widget* pParent);
    virtual void GrabFocus() override
    {
        m_xLineStyleLb->GrabFocus();
    }
};

}

class SvxStyleToolBoxControl;

class SfxStyleControllerItem_Impl : public SfxStatusListener
{
    public:
        SfxStyleControllerItem_Impl( const Reference< XDispatchProvider >& rDispatchProvider,
                                     sal_uInt16 nSlotId,
                                     const OUString& rCommand,
                                     SvxStyleToolBoxControl& rTbxCtl );

    protected:
        virtual void StateChangedAtStatusListener( SfxItemState eState, const SfxPoolItem* pState ) override;

    private:
        SvxStyleToolBoxControl& rControl;
};

#define BUTTON_PADDING 10
#define ITEM_HEIGHT 30

SvxStyleBox_Base::SvxStyleBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
                                   OUString aCommand,
                                   SfxStyleFamily eFamily,
                                   const Reference< XFrame >& _xFrame,
                                   OUString _aClearFormatKey,
                                   OUString _aMoreKey,
                                   bool bInSpec, SvxStyleToolBoxControl& rCtrl)
    : m_rCtrl(rCtrl)
    , m_xMenuBuilder(Application::CreateBuilder(nullptr, u"svx/ui/stylemenu.ui"_ustr))
    , m_xMenu(m_xMenuBuilder->weld_menu(u"menu"_ustr))
    , m_xWidget(std::move(xWidget))
    , eStyleFamily( eFamily )
    , m_nMaxUserDrawFontWidth(0)
    , m_nLastItemWithMenu(-1)
    , bRelease( true )
    , m_xFrame(_xFrame)
    , m_aCommand(std::move( aCommand ))
    , aClearFormatKey(std::move( _aClearFormatKey ))
    , aMoreKey(std::move( _aMoreKey ))
    , 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(true);

    m_xWidget->set_entry_width_chars(COMBO_WIDTH_IN_CHARS + 3);
}

IMPL_LINK(SvxStyleBox_Base, CustomGetSizeHdl, OutputDevice&, rArg, Size)
{
    CalcOptimalExtraUserWidth(rArg);
    if (comphelper::LibreOfficeKit::isActive())
        return Size(m_nMaxUserDrawFontWidth * rArg.GetDPIX() / 96, ITEM_HEIGHT * rArg.GetDPIY() / 96);
    return Size(m_nMaxUserDrawFontWidth, ITEM_HEIGHT);
}

SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
                                   const OUString& rCommand,
                                   SfxStyleFamily eFamily,
                                   const Reference< XFrame >& _xFrame,
                                   const OUString& rClearFormatKey,
                                   const OUString& rMoreKey,
                                   bool bInSpec, SvxStyleToolBoxControl& rCtrl)
    : InterimItemWindow(pParent, u"svx/ui/applystylebox.ui"_ustr, u"ApplyStyleBox"_ustr)
    , SvxStyleBox_Base(m_xBuilder->weld_combo_box(u"applystyle"_ustr), rCommand, eFamily, _xFrame,
                       rClearFormatKey, rMoreKey, bInSpec, rCtrl)
{
    InitControlBase(m_xWidget.get());

    set_id(u"applystyle"_ustr);
    SetOptimalSize();
}

void SvxStyleBox_Base::ReleaseFocus()
{
    if ( !bRelease )
    {
        bRelease = true;
        return;
    }
    if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
        m_xFrame->getContainerWindow()->setFocus();
}

IMPL_LINK(SvxStyleBox_Base, MenuSelectHdl, const OUString&, rMenuIdent, void)
{
    if (m_nLastItemWithMenu < 0 || m_nLastItemWithMenu >= m_xWidget->get_count())
        return;

    OUString sEntry = m_xWidget->get_text(m_nLastItemWithMenu);

    ReleaseFocus(); // It must be after getting entry pos!
    Sequence<PropertyValue> aArgs{ comphelper::makePropertyValue(u"Param"_ustr, sEntry),
                                   comphelper::makePropertyValue(u"Family"_ustr,
                                                                 sal_Int16( eStyleFamily )) };

    const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
    if (rMenuIdent == "update")
    {
        SfxToolBoxControl::Dispatch(xProvider, u".uno:StyleUpdateByExample"_ustr, aArgs);
    }
    else if (rMenuIdent == "edit")
    {
        SfxToolBoxControl::Dispatch(xProvider, u".uno:EditStyle"_ustr, aArgs);
    }
}

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

IMPL_LINK(SvxStyleBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)
{
    Select(rCombo.changed_by_direct_pick()); // only when picked from the list
}

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

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

    OUString aSearchEntry(m_xWidget->get_active_text());
    bool bDoIt = true, bClear = false;
    if( bInSpecialMode )
    {
        if( aSearchEntry == aClearFormatKey && m_xWidget->get_active() == 0 )
        {
            aSearchEntry = sDefaultStyle;
            bClear = true;
            //not only apply default style but also call 'ClearFormatting'
            Sequence< PropertyValue > aEmptyVals;
            const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
            SfxToolBoxControl::Dispatch(xProvider, u".uno:ResetAttributes"_ustr, aEmptyVals);
        }
        else if (aSearchEntry == aMoreKey && m_xWidget->get_active() == (m_xWidget->get_count() - 1))
        {
            Application::PostUserEvent(LINK(nullptr, SvxStyleBox_Base, ShowMoreHdl));
            //tdf#113214 change text back to previous entry
            set_active_or_entry_text(m_xWidget->get_saved_value());
            bDoIt = false;
        }
    }

    //Do we need to create a new style?
    SfxObjectShell *pShell = SfxObjectShell::Current();
    if (!pShell)
        return;

    SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
    SfxStyleSheetBase* pStyle = nullptr;

    bool bCreateNew = false;

    if ( pPool )
    {
        pStyle = pPool->First(eStyleFamily);
        while ( pStyle && pStyle->GetName() != aSearchEntry )
            pStyle = pPool->Next();
    }

    if ( !pStyle )
    {
        // cannot find the style for whatever reason
        // therefore create a new style
        bCreateNew = true;
    }

    /*  #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
        This instance may be deleted in the meantime (i.e. when a dialog is opened
        while in Dispatch()), accessing members will crash in this case. */

    ReleaseFocus();

    if( !bDoIt )
        return;

    if ( bClear )
        set_active_or_entry_text(aSearchEntry);
    m_xWidget->save_value();

    Sequence< PropertyValue > aArgs( 2 );
    auto pArgs = aArgs.getArray();
    pArgs[0].Value  <<= aSearchEntry;
    pArgs[1].Name   = "Family";
    pArgs[1].Value  <<= sal_Int16( eStyleFamily );

    const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
    if( bCreateNew )
    {
        pArgs[0].Name   = "Param";
        SfxToolBoxControl::Dispatch(xProvider, u".uno:StyleNewByExample"_ustr, aArgs);
    }
    else
    {
        pArgs[0].Name   = "Template";
        SfxToolBoxControl::Dispatch(xProvider, m_aCommand, aArgs);
    }
}

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

IMPL_LINK_NOARG(SvxStyleBox_Base, FocusOutHdl, weld::Widget&, void)
{
    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());
}

IMPL_LINK(SvxStyleBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    return DoKeyInput(rKEvt);
}

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

    sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();

    switch (nCode)
    {
        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())
            {
                ReleaseFocus();
                bHandled = true;
            }
            break;
    }

    return bHandled;
}

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

void SvxStyleBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
         (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
    {
        SetOptimalSize();
    }

    InterimItemWindow::DataChanged( rDCEvt );
}

void SvxStyleBox_Impl::SetOptimalSize()
{
    // set width in chars low so the size request will not be overridden
    m_xWidget->set_entry_width_chars(1);
    // tdf#132338 purely using this calculation to keep things their traditional width
    Size aSize(LogicToPixel(Size((COMBO_WIDTH_IN_CHARS + 3) * 4, 0), MapMode(MapUnit::MapAppFont)));
    m_xWidget->set_size_request(aSize.Width(), -1);

    SetSizePixel(get_preferred_size());
}

namespace
{
std::vector<ScriptInfo> CheckScript(const OUString &rStyleName)
{
    assert(!rStyleName.isEmpty()); // must have a preview text here!

    std::vector<ScriptInfo> aScriptChanges;

    auto aEditEngine = EditEngine(nullptr);
    aEditEngine.SetText(rStyleName);

    auto aScript = aEditEngine.GetScriptType({ 0, 0, 0, 0 });
    for (sal_Int32 i = 1; i <= rStyleName.getLength(); i++)
    {
        auto aNextScript = aEditEngine.GetScriptType({ 0, i, 0, i });
        if (aNextScript != aScript || i == rStyleName.getLength())
            aScriptChanges.emplace_back(aScript, i);
        aScript = aNextScript;
    }

    return aScriptChanges;
}
}

tools::Rectangle SvxStyleBox_Base::CalcBoundRect(vcl::RenderContext& rRenderContext, const OUString &rStyleName, std::vector<ScriptInfo>& rScriptChanges, double fRatio)
{
    tools::Rectangle aTextRect;

    SvtScriptType aScript;
    sal_uInt16 nIdx = 0;
    sal_Int32 nStart = 0;
    sal_Int32 nEnd;
    size_t nCnt = rScriptChanges.size();

    if (nCnt)
    {
        nEnd = rScriptChanges[nIdx].changePos;
        aScript = rScriptChanges[nIdx].scriptType;
    }
    else
    {
        nEnd = rStyleName.getLength();
        aScript = SvtScriptType::LATIN;
    }

    do
    {
        auto oFont = (aScript == SvtScriptType::ASIAN) ?
                         m_oCJKFont :
                         ((aScript == SvtScriptType::COMPLEX) ?
                             m_oCTLFont :
                             m_oFont);

        rRenderContext.Push(vcl::PushFlags::FONT);

        if (oFont)
            rRenderContext.SetFont(*oFont);

        if (fRatio != 1)
        {
            vcl::Font aFont(rRenderContext.GetFont());
            Size aPixelSize(aFont.GetFontSize());
            aPixelSize.setWidth(aPixelSize.Width() * fRatio);
            aPixelSize.setHeight(aPixelSize.Height() * fRatio);
            aFont.SetFontSize(aPixelSize);
            rRenderContext.SetFont(aFont);
        }

        tools::Rectangle aRect;
        rRenderContext.GetTextBoundRect(aRect, rStyleName, nStart, nStart, nEnd - nStart);
        aTextRect = aTextRect.Union(aRect);

        tools::Long nWidth = rRenderContext.GetTextWidth(rStyleName, nStart, nEnd - nStart);

        rRenderContext.Pop();

        if (nIdx >= rScriptChanges.size())
            break;

        rScriptChanges[nIdx++].textWidth = nWidth;

        if (nEnd < rStyleName.getLength() && nIdx < nCnt)
        {
            nStart = nEnd;
            nEnd = rScriptChanges[nIdx].changePos;
            aScript = rScriptChanges[nIdx].scriptType;
        }
        else
            break;
    }
    while(true);

    return aTextRect;
}

void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const tools::Rectangle& rTextRect, const OUString &rStyleName, const std::vector<ScriptInfo>& rScriptChanges)
{
    // 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;

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

    double fRatio = 1;
    if (rTextRect.Bottom() > rRect.GetHeight())
        fRatio = static_cast<double>(rRect.GetHeight()) / rTextRect.Bottom();
    else
        aPos.AdjustY((rRect.GetHeight() - rTextRect.Bottom()) / 2);

    SvtScriptType aScript;
    sal_uInt16 nIdx = 0;
    sal_Int32 nStart = 0;
    sal_Int32 nEnd;
    size_t nCnt = rScriptChanges.size();

    if (nCnt)
    {
        nEnd = rScriptChanges[nIdx].changePos;
        aScript = rScriptChanges[nIdx].scriptType;
    }
    else
    {
        nEnd = rStyleName.getLength();
        aScript = SvtScriptType::LATIN;
    }


    do
    {
        auto oFont = (aScript == SvtScriptType::ASIAN) ?
                         m_oCJKFont :
                         ((aScript == SvtScriptType::COMPLEX) ?
                             m_oCTLFont :
                             m_oFont);

        rRenderContext.Push(vcl::PushFlags::FONT);

        if (oFont)
            rRenderContext.SetFont(*oFont);

        if (fRatio != 1)
        {
            vcl::Font aFont(rRenderContext.GetFont());
            Size aPixelSize(aFont.GetFontSize());
            aPixelSize.setWidth(aPixelSize.Width() * fRatio);
            aPixelSize.setHeight(aPixelSize.Height() * fRatio);
            aFont.SetFontSize(aPixelSize);
            rRenderContext.SetFont(aFont);
        }

        rRenderContext.DrawText(aPos, rStyleName, nStart, nEnd - nStart);

        rRenderContext.Pop();

        aPos.AdjustX(rScriptChanges[nIdx++].textWidth * fRatio);
        if (nEnd < rStyleName.getLength() && nIdx < nCnt)
        {
            nStart = nEnd;
            nEnd = rScriptChanges[nIdx].changePos;
            aScript = rScriptChanges[nIdx].scriptType;
        }
        else
            break;
    }
    while(true);
}

static bool GetWhich(const SfxItemSet& rSet, sal_uInt16 nSlot, sal_uInt16& rWhich)
{
    rWhich = rSet.GetPool()->GetWhichIDFromSlotID(nSlot);
    return rSet.GetItemState(rWhich) >= SfxItemState::DEFAULT;
}

static bool SetFont(const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont)
{
    sal_uInt16 nWhich;
    if (GetWhich(rSet, nSlot, nWhich))
    {
        const auto& rFontItem = static_cast<const SvxFontItem&>(rSet.Get(nWhich));
        rFont.SetFamilyName(rFontItem.GetFamilyName());
        rFont.SetStyleName(rFontItem.GetStyleName());
        return true;
    }
    return false;
}

static bool SetFontSize(const vcl::RenderContext& rRenderContext, const SfxItemSet&&nbsp;rSet, sal_uInt16 nSlot, SvxFont& rFont)
{
    sal_uInt16 nWhich;
    if (GetWhich(rSet, nSlot, nWhich))
    {
        const auto& rFontHeightItem = static_cast<const SvxFontHeightItem&>(rSet.Get(nWhich));
        if (SfxObjectShell *pShell = SfxObjectShell::Current())
        {
            Size aFontSize(0, rFontHeightItem.GetHeight());
            Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
            rFont.SetFontSize(aPixelSize);
            return true;
        }
    }
    return false;
}

static void SetFontStyle(const SfxItemSet& rSet, sal_uInt16 nPosture, sal_uInt16 nWeight, SvxFont& rFont)
{
    sal_uInt16 nWhich;
    if (GetWhich(rSet, nPosture, nWhich))
    {
        const auto& rItem = static_cast<const SvxPostureItem&>(rSet.Get(nWhich));
        rFont.SetItalic(rItem.GetPosture());
    }

    if (GetWhich(rSet, nWeight, nWhich))
    {
        const auto& rItem = static_cast<const SvxWeightItem&>(rSet.Get(nWhich));
        rFont.SetWeight(rItem.GetWeight());
    }
}

void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 nItem, const tools::Rectangle& rRect, std::u16string_view rStyleName, bool bIsNotSelected)
{
    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(OUString::number(nItem), nullptr);
        else
        {
            m_nLastItemWithMenu = nItem;
            m_xWidget->set_item_menu(OUString::number(nItem), m_xMenu.get());
        }
    }

    if (nItem <= 0 || nItem >= m_xWidget->get_count() - 1)
        return;

    SfxObjectShell *pShell = SfxObjectShell::Current();
    if (!pShell)
        return;

    SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
    if (!pPool)
        return;

    SfxStyleSheetBase* pStyle = pPool->First(eStyleFamily);
    while (pStyle && pStyle->GetName() != rStyleName)
        pStyle = pPool->Next();

    if (!pStyle )
        return;

    std::optional<SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
    if (!pItemSet) return;

    SvxFont aFont;
    SvxFont aCJKFont;
    SvxFont aCTLFont;

    SetFontStyle(*pItemSet, SID_ATTR_CHAR_POSTURE, SID_ATTR_CHAR_WEIGHT, aFont);
    SetFontStyle(*pItemSet, SID_ATTR_CHAR_CJK_POSTURE, SID_ATTR_CHAR_CJK_WEIGHT, aCJKFont);
    SetFontStyle(*pItemSet, SID_ATTR_CHAR_CTL_POSTURE, SID_ATTR_CHAR_CTL_WEIGHT, aCTLFont);

    const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR );
    if ( pItem )
    {
        auto aVal = static_castconst SvxContourItem* >( pItem )->GetValue();
        aFont.SetOutline(aVal);
        aCJKFont.SetOutline(aVal);
        aCTLFont.SetOutline(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_SHADOWED );
    if ( pItem )
    {
        auto aVal = static_castconst SvxShadowedItem* >( pItem )->GetValue();
        aFont.SetShadow(aVal);
        aCJKFont.SetShadow(aVal);
        aCTLFont.SetShadow(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_RELIEF );
    if ( pItem )
    {
        auto aVal = static_castconst SvxCharReliefItem* >( pItem )->GetValue();
        aFont.SetRelief(aVal);
        aCJKFont.SetRelief(aVal);
        aCTLFont.SetRelief(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_UNDERLINE );
    if ( pItem )
    {
        auto aVal = static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle();
        aFont.SetUnderline(aVal);
        aCJKFont.SetUnderline(aVal);
        aCTLFont.SetUnderline(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_OVERLINE );
    if ( pItem )
    {
        auto aVal = static_castconst SvxOverlineItem* >( pItem )->GetValue();
        aFont.SetOverline(aVal);
        aCJKFont.SetOverline(aVal);
        aCTLFont.SetOverline(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_STRIKEOUT );
    if ( pItem )
    {
        auto aVal = static_castconst SvxCrossedOutItem* >( pItem )->GetStrikeout();
        aFont.SetStrikeout(aVal);
        aCJKFont.SetStrikeout(aVal);
        aCTLFont.SetStrikeout(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_CASEMAP );
    if ( pItem )
    {
        auto aVal = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap();
        aFont.SetCaseMap(aVal);
        aCJKFont.SetCaseMap(aVal);
        aCTLFont.SetCaseMap(aVal);
    }

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_EMPHASISMARK );
    if ( pItem )
    {
        auto aVal = static_castconst SvxEmphasisMarkItem* >( pItem )->GetEmphasisMark();
        aFont.SetEmphasisMark(aVal);
        aCJKFont.SetEmphasisMark(aVal);
        aCTLFont.SetEmphasisMark(aVal);
    }

    // setup the device & draw
    Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;

    pItem = pItemSet->GetItem( SID_ATTR_CHAR_COLOR );
    // text color, when nothing is selected
    if ( (nullptr != pItem) && bIsNotSelected)
        aFontCol = static_castconst SvxColorItem* >( pItem )->GetValue();

    drawing::FillStyle style = drawing::FillStyle_NONE;
    // which kind of Fill style is selected
    pItem = pItemSet->GetItem( XATTR_FILLSTYLE );
    // only when ok and not selected
    if ( (nullptr != pItem) && bIsNotSelected)
        style = static_castconst XFillStyleItem* >( pItem )->GetValue();

    switch(style)
    {
        case drawing::FillStyle_SOLID:
        {
            // set background color
            pItem = pItemSet->GetItem( XATTR_FILLCOLOR );
            if ( nullptr != pItem )
                aBackCol = static_castconst XFillColorItem* >( pItem )->GetColorValue();

            if ( aBackCol != COL_AUTO )
            {
                rRenderContext.SetFillColor(aBackCol);
                rRenderContext.DrawRect(rRect);
            }
        }
        break;

        defaultbreak;
        //TODO Draw the other background styles: gradient, hatching and bitmap
    }

    // when the font and background color are too similar, adjust the Font-Color
    if( (aFontCol != COL_AUTO) || (aBackCol != COL_AUTO) )
        aFontCol = TestColorsVisible(aFontCol, (aBackCol != COL_AUTO) ? aBackCol : rRenderContext.GetBackground().GetColor());

    // set text color
    if ( aFontCol != COL_AUTO )
        rRenderContext.SetTextColor(aFontCol);

    if (SetFont(*pItemSet, SID_ATTR_CHAR_FONT, aFont) &&
        SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_FONTHEIGHT, aFont))
        m_oFont = aFont;

    if (SetFont(*pItemSet, SID_ATTR_CHAR_CJK_FONT, aCJKFont) &&
        SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_CJK_FONTHEIGHT, aCJKFont))
        m_oCJKFont = aCJKFont;

    if (SetFont(*pItemSet, SID_ATTR_CHAR_CTL_FONT, aCTLFont) &&
        SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_CTL_FONTHEIGHT, aCTLFont))
        m_oCTLFont = aCTLFont;
}

IMPL_LINK(SvxStyleBox_Base, CustomRenderHdl, weld::ComboBox::render_args, aPayload, void)
{
    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);

    sal_uInt32 nIndex = rId.toUInt32();

    OUString aStyleName(m_xWidget->get_text(nIndex));

    rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT | vcl::PushFlags::TEXTCOLOR);

    SetupEntry(rRenderContext, nIndex, rRect, aStyleName, !bSelected);
    auto aScriptChanges = CheckScript(aStyleName);
    auto aTextRect = CalcBoundRect(rRenderContext, aStyleName, aScriptChanges);
    UserDrawEntry(rRenderContext, rRect, aTextRect, aStyleName, aScriptChanges);

    rRenderContext.Pop();
}

void SvxStyleBox_Base::CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderContext)
{
    if (m_nMaxUserDrawFontWidth)
        return;

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

        const tools::Long nWidth = aTextRectForDefaultFont.GetWidth();

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

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

        if (sStyleName.isEmpty())
            continue;

        rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT | vcl::PushFlags::TEXTCOLOR);
        SetupEntry(rRenderContext, i, tools::Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), sStyleName, true);
        auto aScriptChanges = CheckScript(sStyleName);
        tools::Rectangle aTextRectForActualFont = CalcBoundRect(rRenderContext, sStyleName, aScriptChanges);
        if (aTextRectForActualFont.Bottom() > ITEM_HEIGHT)
        {
            //Font didn't fit, re-calculate with adjustment ratio.
            double fRatio = static_cast<double>(ITEM_HEIGHT) / aTextRectForActualFont.Bottom();
            aTextRectForActualFont = CalcBoundRect(rRenderContext, sStyleName, aScriptChanges, fRatio);
        }
        rRenderContext.Pop();

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

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

// test is the color between Font- and background-color to be identify
// return is always the Font-Color
//        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_Base::TestColorsVisible(const Color &FontCol, const Color &BackCol)
{
    constexpr sal_uInt8  ChgVal = 60;       // increase/decrease the Contrast

    Color  retCol = FontCol;
    if ((FontCol.IsDark() == BackCol.IsDark()) && (FontCol.IsBright() == BackCol.IsBright()))
    {
        sal_uInt8 lumi = retCol.GetLuminance();

        if((lumi > 120) && (lumi < 140))
            retCol.DecreaseLuminance(ChgVal / 2);
        else
            retCol.DecreaseContrast(ChgVal);
    }

    return retCol;
}

IMPL_LINK(SvxStyleBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
{
    if (!m_xWidget)
        return;

    {
        auto entriesNode = rJsonWriter.startNode("entries");
        for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; ++i)
        {
            auto entryNode = rJsonWriter.startNode("");
            rJsonWriter.put("", m_xWidget->get_text(i));
        }
    }

    int nActive = m_xWidget->get_active();
    rJsonWriter.put("selectedCount"static_cast<sal_Int32>(nActive == -1 ? 0 : 1));

    {
        auto selectedNode = rJsonWriter.startNode("selectedEntries");
        if (nActive != -1)
        {
            auto node = rJsonWriter.startNode("");
            rJsonWriter.put(""static_cast<sal_Int32>(nActive));
        }
    }

    rJsonWriter.put("command"".uno:StyleApply");
}

static bool lcl_GetDocFontList(const FontList** ppFontList, SvxFontNameBox_Base& rBox)
{
    bool bChanged = false;
    const SfxObjectShell* pDocSh = SfxObjectShell::Current();
    const SvxFontListItem* pFontListItem = nullptr;

    if ( pDocSh )
        pFontListItem =
            static_cast<const SvxFontListItem*>(pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ));
    else
    {
        ::std::unique_ptr<FontList> aFontList(new FontList(Application::GetDefaultDevice()));
        *ppFontList = aFontList.get();
        rBox.SetOwnFontList(std::move(aFontList));
        bChanged = true;
    }

    if ( pFontListItem )
    {
        const FontList* pNewFontList = pFontListItem->GetFontList();
        DBG_ASSERT( pNewFontList, "Doc-FontList not available!" );

        // No old list, but a new list
        if ( !*ppFontList && pNewFontList )
        {
            // => take over
            *ppFontList = pNewFontList;
            bChanged = true;
        }
        else
        {
            // Comparing the font lists is not perfect.
            // When you change the font list in the Doc, you can track
            // changes here only on the Listbox, because ppFontList
            // has already been updated.
            bChanged = !pNewFontList ||
                       *ppFontList != pNewFontList ||
                       rBox.GetListCount() != pNewFontList->GetFontNameCount();
            // HACK: Comparing is incomplete

            if ( bChanged )
                *ppFontList = pNewFontList;
        }

        rBox.set_sensitive(true);
    }
    else if ( pDocSh || !ppFontList)
    {
        // Disable box only when we have a SfxObjectShell and didn't get a font list OR
        // we don't have a SfxObjectShell and no current font list.
        // It's possible that we currently have no SfxObjectShell, but a current font list.
        // See #i58471: When a user set the focus into the font name combo box and opens
        // the help window with F1. After closing the help window, we disable the font name
        // combo box. The SfxObjectShell::Current() method returns in that case zero. But the
        // font list hasn't changed and therefore the combo box shouldn't be disabled!
        rBox.set_sensitive(false);
    }

    // Fill the FontBox, also the new list if necessary
    if ( bChanged )
    {
        if (ppFontList && *ppFontList)
            rBox.Fill( *ppFontList );
        else
            rBox.Clear();
    }
    return bChanged;
}

SvxFontNameBox_Base::SvxFontNameBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
                                         const Reference<XFrame>& rFrame,
                                         SvxFontNameToolBoxControl& rCtrl)
    : m_xListener(new comphelper::ConfigurationListener(u"/org.openoffice.Office.Common/Font/View"_ustr))
    , m_aWYSIWYG(m_xListener, u"ShowFontBoxWYSIWYG"_ustr, *this)
    , m_aHistory(m_xListener, u"History"_ustr, *this)
    , m_rCtrl(rCtrl)
    , m_xWidget(new FontNameBox(std::move(xWidget)))
    , pFontList(nullptr)
    , nFtCount(0)
    , bRelease(true)
    , m_xFrame(rFrame)
    , mbCheckingUnknownFont(false)
    , mbDropDownActive(false)
{
    EnableControls();

    m_xWidget->connect_changed(LINK(this, SvxFontNameBox_Base, SelectHdl));
    m_xWidget->connect_key_press(LINK(this, SvxFontNameBox_Base, KeyInputHdl));
    m_xWidget->connect_entry_activate(LINK(this, SvxFontNameBox_Base, ActivateHdl));
    m_xWidget->connect_focus_in(LINK(this, SvxFontNameBox_Base, FocusInHdl));
    m_xWidget->connect_focus_out(LINK(this, SvxFontNameBox_Base, FocusOutHdl));
    m_xWidget->connect_popup_toggled(LINK(this, SvxFontNameBox_Base, PopupToggledHdl));
    m_xWidget->connect_live_preview(LINK(this, SvxFontNameBox_Base, LivePreviewHdl));
    m_xWidget->connect_get_property_tree(LINK(this, SvxFontNameBox_Base, DumpAsPropertyTreeHdl));

    m_xWidget->set_entry_width_chars(COMBO_WIDTH_IN_CHARS + 5);
}

SvxFontNameBox_Impl::SvxFontNameBox_Impl(vcl::Window* pParent, const Reference<XFrame>& rFrame,
                                         SvxFontNameToolBoxControl& rCtrl)
    : InterimItemWindow(pParent, u"svx/ui/fontnamebox.ui"_ustr, u"FontNameBox"_ustr, truereinterpret_cast<sal_uInt64>(SfxViewShell::Current()))
    , SvxFontNameBox_Base(m_xBuilder->weld_combo_box(u"fontnamecombobox"_ustr), rFrame, rCtrl)
{
    set_id(u"fontnamecombobox"_ustr);
    SetOptimalSize();
}

void SvxFontNameBox_Base::FillList()
{
    if (!m_xWidget) // e.g. disposed
        return;
    // Save old Selection, set back in the end
    int nStartPos, nEndPos;
    m_xWidget->get_entry_selection_bounds(nStartPos, nEndPos);

    // Did Doc-Fontlist change?
    lcl_GetDocFontList(&pFontList, *this);

    m_xWidget->select_entry_region(nStartPos, nEndPos);
}

bool SvxFontNameBox_Base::CheckFontIsAvailable(std::u16string_view fontname)
{
    lcl_GetDocFontList(&pFontList, *this);
    return pFontList && pFontList->IsAvailable(fontname);
}

void SvxFontNameBox_Base::CheckAndMarkUnknownFont()
{
    if (mbCheckingUnknownFont) //tdf#117537 block rentry
        return;
    mbCheckingUnknownFont = true;
    OUString fontname = m_xWidget->get_active_text();
    // tdf#154680 If a font is set and that font is unknown, show it in italic.
    vcl::Font font = m_xWidget->get_entry_font();
    if (fontname.isEmpty() || CheckFontIsAvailable(fontname))
    {
        if( font.GetItalicMaybeAskConfig() != ITALIC_NONE )
        {
            font.SetItalic( ITALIC_NONE );
            m_xWidget->set_entry_font(font);
            m_xWidget->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME));
        }
    }
    else
    {
        if( font.GetItalicMaybeAskConfig() != ITALIC_NORMAL )
        {
            font.SetItalic( ITALIC_NORMAL );
            m_xWidget->set_entry_font(font);
            m_xWidget->set_tooltip_text(SvxResId(RID_SVXSTR_CHARFONTNAME_NOTAVAILABLE));
        }
    }
    mbCheckingUnknownFont = false;
}

void SvxFontNameBox_Base::Update( const css::awt::FontDescriptor* pFontDesc )
{
    if ( pFontDesc )
    {
        aCurFont.SetFamilyName  ( pFontDesc->Name );
        aCurFont.SetFamily      ( FontFamily( pFontDesc->Family ) );
        aCurFont.SetStyleName   ( pFontDesc->StyleName );
        aCurFont.SetPitch       ( FontPitch( pFontDesc->Pitch ) );
        aCurFont.SetCharSet     ( rtl_TextEncoding( pFontDesc->CharSet ) );
    }
    OUString aCurName = aCurFont.GetFamilyName();
    OUString aText = m_xWidget->get_active_text();
    if (aText != aCurName)
        set_active_or_entry_text(aCurName);
}

void SvxFontNameBox_Base::set_active_or_entry_text(const OUString& rText)
{
    m_xWidget->set_active_or_entry_text(rText);
    CheckAndMarkUnknownFont();
}

IMPL_LINK_NOARG(SvxFontNameBox_Base, FocusInHdl, weld::Widget&, void)
{
    FillList();
}

IMPL_LINK(SvxFontNameBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    return DoKeyInput(rKEvt);
}

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

    sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();

    switch (nCode)
    {
        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())
            {
                ReleaseFocus_Impl();
                bHandled = true;
            }
            break;
    }

    return bHandled;
}

bool SvxFontNameBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
{
    return SvxFontNameBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
}

IMPL_LINK_NOARG(SvxFontNameBox_Base, FocusOutHdl, weld::Widget&, void)
{
    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());
        // send EndPreview
        EndPreview();
    }
}

IMPL_LINK(SvxFontNameBox_Base, LivePreviewHdl, const FontMetric&, rFontMetric, void)
{
    Sequence<PropertyValue> aArgs(1);

    SvxFontItem aFontItem(rFontMetric.GetFamilyType(),
                          rFontMetric.GetFamilyName(),
                          rFontMetric.GetStyleName(),
                          rFontMetric.GetPitch(),
                          rFontMetric.GetCharSet(),
                          SID_ATTR_CHAR_FONT);
    PropertyValue* pArgs = aArgs.getArray();
    aFontItem.QueryValue(pArgs[0].Value);
    pArgs[0].Name = "CharPreviewFontName";
    const Reference<XDispatchProvider> xProvider(m_xFrame, UNO_QUERY);
    SfxToolBoxControl::Dispatch(xProvider, u".uno:CharPreviewFontName"_ustr, aArgs);
}

IMPL_LINK_NOARG(SvxFontNameBox_Base, PopupToggledHdl, weld::ComboBox&, void)
{
    mbDropDownActive = !mbDropDownActive;
    if (!mbDropDownActive)
        EndPreview();
}

void SvxFontNameBox_Impl::SetOptimalSize()
{
    // set width in chars low so the size request will not be overridden
    m_xWidget->set_entry_width_chars(1);
    // tdf#132338 purely using this calculation to keep things their traditional width
    Size aSize(LogicToPixel(Size((COMBO_WIDTH_IN_CHARS +5) * 4, 0), MapMode(MapUnit::MapAppFont)));
    m_xWidget->set_size_request(aSize.Width(), -1);

    SetSizePixel(get_preferred_size());
}

void SvxFontNameBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
         (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
    {
        SetOptimalSize();
    }
    else if ( ( rDCEvt.GetType() == DataChangedEventType::FONTS ) ||
              ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) )
    {
        // The old font list in shell has likely been destroyed at this point, so we need to get
        // the new one before doing anything further.
        lcl_GetDocFontList( &pFontList, *this );
    }
}

void SvxFontNameBox_Base::ReleaseFocus_Impl()
{
    if ( !bRelease )
    {
        bRelease = true;
        return;
    }
    if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
        m_xFrame->getContainerWindow()->setFocus();
}

void SvxFontNameBox_Base::EnableControls()
{
    bool bEnableMRU = m_aHistory.get();
    sal_uInt16 nEntries = bEnableMRU ? MAX_MRU_FONTNAME_ENTRIES : 0;

    bool bNewWYSIWYG = m_aWYSIWYG.get();
    bool bOldWYSIWYG = m_xWidget->IsWYSIWYGEnabled();

    if (m_xWidget->get_max_mru_count() != nEntries || bNewWYSIWYG != bOldWYSIWYG)
    {
        // refill in the next GetFocus-Handler
        pFontList = nullptr;
        Clear();
        m_xWidget->set_max_mru_count(nEntries);
    }

    if (bNewWYSIWYG != bOldWYSIWYG)
        m_xWidget->EnableWYSIWYG(bNewWYSIWYG);
}

IMPL_LINK(SvxFontNameBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)
{
    Select(rCombo.changed_by_direct_pick()); // only when picked from the list
}

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

void SvxFontNameBox_Base::Select(bool bNonTravelSelect)
{
    Sequence< PropertyValue > aArgs( 1 );
    auto pArgs = aArgs.getArray();
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=97 G=95

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.