weld SvxBorderTabPage

Change-Id: I33f12f160ac5fea14c9a53c3846c6d31c7fd0084
Reviewed-on: https://gerrit.libreoffice.org/59954
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index f2926cf..1c61854 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -183,7 +183,6 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
    cui/source/tabpages/autocdlg \
    cui/source/tabpages/backgrnd \
    cui/source/tabpages/bbdlg \
    cui/source/tabpages/borderconn \
    cui/source/tabpages/border \
    cui/source/tabpages/chardlg \
    cui/source/tabpages/connect \
diff --git a/cui/source/inc/border.hxx b/cui/source/inc/border.hxx
index e596380..80dea4e 100644
--- a/cui/source/inc/border.hxx
+++ b/cui/source/inc/border.hxx
@@ -19,12 +19,15 @@
#ifndef INCLUDED_CUI_SOURCE_INC_BORDER_HXX
#define INCLUDED_CUI_SOURCE_INC_BORDER_HXX

#include <editeng/shaditem.hxx>
#include <svtools/ctrlbox.hxx>
#include <vcl/group.hxx>
#include <vcl/field.hxx>
#include <vcl/fixed.hxx>
#include <vcl/weld.hxx>
#include <svtools/valueset.hxx>
#include <sfx2/tabdlg.hxx>
#include <svx/algitem.hxx>
#include <svx/colorbox.hxx>
#include <svx/frmsel.hxx>
#include <svx/flagsdef.hxx>
@@ -38,6 +41,37 @@ namespace editeng
    class SvxBorderLine;
}

class ShadowControlsWrapper
{
public:
    explicit ShadowControlsWrapper(SvtValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor);

    SvxShadowItem GetControlValue(const SvxShadowItem& rItem) const;
    void SetControlValue(const SvxShadowItem& rItem);

private:
    SvtValueSet&                        mrVsPos;
    weld::MetricSpinButton&             mrMfSize;
    ColorListBox&                       mrLbColor;
};

class MarginControlsWrapper
{
public:
    explicit MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
                                   weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom);

    SvxMarginItem GetControlValue(const SvxMarginItem& rItem) const;
    void SetControlValue(const SvxMarginItem& rItem);

    bool get_value_changed_from_saved() const;

private:
    weld::MetricSpinButton& mrLeftWrp;
    weld::MetricSpinButton& mrRightWrp;
    weld::MetricSpinButton& mrTopWrp;
    weld::MetricSpinButton& mrBottomWrp;
};

class SvxBorderTabPage : public SfxTabPage
{
@@ -65,49 +99,15 @@ protected:
    virtual void        DataChanged( const DataChangedEvent& rDCEvt ) override;

private:
    SvxBorderTabPage( vcl::Window* pParent, const SfxItemSet& rCoreAttrs );
    SvxBorderTabPage(TabPageParent pParent, const SfxItemSet& rCoreAttrs);

    // Controls
    VclPtr<ValueSet>           m_pWndPresets;
    VclPtr<FixedText>          m_pUserDefFT;
    VclPtr<svx::FrameSelector> m_pFrameSel;

    VclPtr<LineListBox>        m_pLbLineStyle;
    VclPtr<SvxColorListBox>    m_pLbLineColor;
    VclPtr<MetricField>        m_pLineWidthMF;

    VclPtr<VclContainer>       m_pSpacingFrame;
    VclPtr<FixedText>          m_pLeftFT;
    VclPtr<MetricField>        m_pLeftMF;
    VclPtr<FixedText>          m_pRightFT;
    VclPtr<MetricField>        m_pRightMF;
    VclPtr<FixedText>          m_pTopFT;
    VclPtr<MetricField>        m_pTopMF;
    VclPtr<FixedText>          m_pBottomFT;
    VclPtr<MetricField>        m_pBottomMF;
    VclPtr<CheckBox>           m_pSynchronizeCB;

    VclPtr<VclContainer>       m_pShadowFrame;
    VclPtr<ValueSet>           m_pWndShadows;
    VclPtr<FixedText>          m_pFtShadowSize;
    VclPtr<MetricField>        m_pEdShadowSize;
    VclPtr<FixedText>          m_pFtShadowColor;
    VclPtr<SvxColorListBox>    m_pLbShadowColor;


    VclPtr<VclContainer>       m_pPropertiesFrame;///< properties - "Merge with next paragraph" in Writer
    VclPtr<CheckBox>           m_pMergeWithNextCB;
    // #i29550#
    VclPtr<CheckBox>           m_pMergeAdjacentBordersCB;
    VclPtr<CheckBox>           m_pRemoveAdjcentCellBordersCB;
    VclPtr<FixedText>          m_pRemoveAdjcentCellBordersFT;

    std::vector<BitmapEx>      m_aShadowImgVec;
    std::vector<BitmapEx>      m_aBorderImgVec;
    std::vector<BitmapEx> m_aShadowImgVec;
    std::vector<BitmapEx> m_aBorderImgVec;

    long                nMinValue;  ///< minimum distance
    SwBorderModes       nSWMode;    ///< table, textframe, paragraph
    sal_uInt16          mnBoxSlot;
    sal_uInt16          mnShadowSlot;

    bool                mbHorEnabled;       ///< true = Inner horizontal border enabled.
    bool                mbVerEnabled;       ///< true = Inner vertical border enabled.
@@ -121,16 +121,55 @@ private:

    std::set<SvxBorderLineStyle> maUsedBorderStyles;

    // Controls
    svx::FrameSelector m_aFrameSel;
    std::unique_ptr<SvtValueSet> m_xWndPresets;
    std::unique_ptr<weld::CustomWeld> m_xWndPresetsWin;
    std::unique_ptr<weld::Label> m_xUserDefFT;
    std::unique_ptr<weld::CustomWeld> m_xFrameSelWin;

    std::unique_ptr<SvtLineListBox> m_xLbLineStyle;
    std::unique_ptr<ColorListBox> m_xLbLineColor;
    std::unique_ptr<weld::MetricSpinButton> m_xLineWidthMF;

    std::unique_ptr<weld::Container> m_xSpacingFrame;
    std::unique_ptr<weld::Label> m_xLeftFT;
    std::unique_ptr<weld::MetricSpinButton> m_xLeftMF;
    std::unique_ptr<weld::Label> m_xRightFT;
    std::unique_ptr<weld::MetricSpinButton> m_xRightMF;
    std::unique_ptr<weld::Label> m_xTopFT;
    std::unique_ptr<weld::MetricSpinButton> m_xTopMF;
    std::unique_ptr<weld::Label> m_xBottomFT;
    std::unique_ptr<weld::MetricSpinButton> m_xBottomMF;
    std::unique_ptr<weld::CheckButton> m_xSynchronizeCB;

    std::unique_ptr<weld::Container> m_xShadowFrame;
    std::unique_ptr<SvtValueSet> m_xWndShadows;
    std::unique_ptr<weld::CustomWeld> m_xWndShadowsWin;
    std::unique_ptr<weld::Label> m_xFtShadowSize;
    std::unique_ptr<weld::MetricSpinButton> m_xEdShadowSize;
    std::unique_ptr<weld::Label> m_xFtShadowColor;
    std::unique_ptr<ColorListBox> m_xLbShadowColor;

    std::unique_ptr<weld::Container> m_xPropertiesFrame;///< properties - "Merge with next paragraph" in Writer
    std::unique_ptr<weld::CheckButton> m_xMergeWithNextCB;
    // #i29550#
    std::unique_ptr<weld::CheckButton> m_xMergeAdjacentBordersCB;
    std::unique_ptr<weld::CheckButton> m_xRemoveAdjcentCellBordersCB;
    std::unique_ptr<weld::Label> m_xRemoveAdjcentCellBordersFT;
    std::unique_ptr<ShadowControlsWrapper> m_xShadowControls;
    std::unique_ptr<MarginControlsWrapper> m_xMarginControls;

    // Handler
    DECL_LINK( SelStyleHdl_Impl, ListBox&, void );
    DECL_LINK( SelColHdl_Impl, SvxColorListBox&, void );
    DECL_LINK( SelPreHdl_Impl, ValueSet*, void );
    DECL_LINK( SelSdwHdl_Impl, ValueSet*, void );
    DECL_LINK( LinesChanged_Impl, LinkParamNone*, void );
    DECL_LINK( ModifyDistanceHdl_Impl, Edit&, void);
    DECL_LINK( ModifyWidthHdl_Impl, Edit&, void);
    DECL_LINK( SyncHdl_Impl, Button*, void);
    DECL_LINK( RemoveAdjacentCellBorderHdl_Impl, Button*, void);
    DECL_LINK(SelStyleHdl_Impl, SvtLineListBox&, void);
    DECL_LINK(SelColHdl_Impl, ColorListBox&, void);
    DECL_LINK(SelPreHdl_Impl, SvtValueSet*, void);
    DECL_LINK(SelSdwHdl_Impl, SvtValueSet*, void);
    DECL_LINK(LinesChanged_Impl, LinkParamNone*, void);
    DECL_LINK(ModifyDistanceHdl_Impl, weld::MetricSpinButton&, void);
    DECL_LINK(ModifyWidthHdl_Impl, weld::MetricSpinButton&, void);
    DECL_LINK(SyncHdl_Impl, weld::ToggleButton&, void);
    DECL_LINK(RemoveAdjacentCellBorderHdl_Impl, weld::ToggleButton&, void);

    sal_uInt16          GetPresetImageId(sal_uInt16 nValueSetIdx) const;
    const char*         GetPresetStringId(sal_uInt16 nValueSetIdx) const;
diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
index d638e86..9789441 100644
--- a/cui/source/tabpages/border.cxx
+++ b/cui/source/tabpages/border.cxx
@@ -30,7 +30,7 @@
#include <svx/xtable.hxx>
#include <svx/drawitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/shaditem.hxx>
#include <editeng/lineitem.hxx>
#include <border.hxx>
#include <svx/dlgutil.hxx>
#include <dialmgr.hxx>
@@ -45,7 +45,6 @@
#include <sfx2/itemconnect.hxx>
#include <sal/macros.h>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include "borderconn.hxx"

using namespace ::editeng;
using ::com::sun::star::uno::Reference;
@@ -79,11 +78,11 @@ const sal_uInt16 SvxBorderTabPage::pRanges[] =
    0
};

static void lcl_SetDecimalDigitsTo1(MetricField& rField)
static void lcl_SetDecimalDigitsTo1(weld::MetricSpinButton& rField)
{
    sal_Int64 nMin = rField.Denormalize( rField.GetMin( FUNIT_TWIP ) );
    rField.SetDecimalDigits(1);
    rField.SetMin( rField.Normalize( nMin ), FUNIT_TWIP );
    auto nMin = rField.denormalize(rField.get_min(FUNIT_TWIP));
    rField.set_digits(1);
    rField.set_min(rField.normalize(nMin), FUNIT_TWIP);
}

// number of preset images to show
@@ -92,11 +91,126 @@ const sal_uInt16 SVX_BORDER_PRESET_COUNT = 5;
// number of shadow images to show
const sal_uInt16 SVX_BORDER_SHADOW_COUNT = 5;

SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCoreAttrs)
    : SfxTabPage(pParent, "BorderPage", "cui/ui/borderpage.ui", &rCoreAttrs)
ShadowControlsWrapper::ShadowControlsWrapper(SvtValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor)
    : mrVsPos(rVsPos)
    , mrMfSize(rMfSize)
    , mrLbColor(rLbColor)
{
}

SvxShadowItem ShadowControlsWrapper::GetControlValue(const SvxShadowItem& rItem) const
{
    SvxShadowItem aItem(rItem);
    if (!mrVsPos.IsNoSelection())
    {
        switch (mrVsPos.GetSelectedItemId())
        {
            case 1:
                aItem.SetLocation(SvxShadowLocation::NONE);
                break;
            case 2:
                aItem.SetLocation(SvxShadowLocation::BottomRight);
                break;
            case 3:
                aItem.SetLocation(SvxShadowLocation::TopRight);
                break;
            case 4:
                aItem.SetLocation(SvxShadowLocation::BottomLeft);
                break;
            case 5:
                aItem.SetLocation(SvxShadowLocation::TopLeft);
                break;
            default:
                aItem.SetLocation(SvxShadowLocation::NONE);
                break;
        }
    }
    // Default value was saved; so don't change the aItem's width if the control
    // has not changed its value, to avoid round-trip errors (like twip->cm->twip)
    // E.g., initial 100 twip will become 0.18 cm, which will return as 102 twip
    if (mrMfSize.get_value_changed_from_saved())
        aItem.SetWidth(mrMfSize.denormalize(mrMfSize.get_value(FUNIT_TWIP)));
    if (!mrLbColor.IsNoSelection())
        aItem.SetColor(mrLbColor.GetSelectEntryColor());
    return aItem;
}

void ShadowControlsWrapper::SetControlValue(const SvxShadowItem& rItem)
{
    switch (rItem.GetLocation())
    {
        case SvxShadowLocation::NONE:
            mrVsPos.SelectItem(1);
            break;
        case SvxShadowLocation::BottomRight:
            mrVsPos.SelectItem(2);
            break;
        case SvxShadowLocation::TopRight:
            mrVsPos.SelectItem(3);
            break;
        case SvxShadowLocation::BottomLeft:
            mrVsPos.SelectItem(4);
            break;
        case SvxShadowLocation::TopLeft:
            mrVsPos.SelectItem(5);
            break;
        default:
            mrVsPos.SetNoSelection();
            break;
    }
    mrMfSize.set_value(mrMfSize.normalize(rItem.GetWidth()), FUNIT_TWIP);
    mrLbColor.SelectEntry(rItem.GetColor());
}

MarginControlsWrapper::MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
                                             weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom)
    : mrLeftWrp(rMfLeft)
    , mrRightWrp(rMfRight)
    , mrTopWrp(rMfTop)
    , mrBottomWrp(rMfBottom)
{
}

SvxMarginItem MarginControlsWrapper::GetControlValue(const SvxMarginItem &rItem) const
{
    SvxMarginItem aItem(rItem);
    if (mrLeftWrp.get_sensitive())
        aItem.SetLeftMargin(mrLeftWrp.denormalize(mrLeftWrp.get_value(FUNIT_TWIP)));
    if (mrRightWrp.get_sensitive())
        aItem.SetRightMargin(mrRightWrp.denormalize(mrRightWrp.get_value(FUNIT_TWIP)));
    if (mrTopWrp.get_sensitive())
        aItem.SetTopMargin(mrTopWrp.denormalize(mrTopWrp.get_value(FUNIT_TWIP)));
    if (mrBottomWrp.get_sensitive())
        aItem.SetBottomMargin(mrBottomWrp.denormalize(mrBottomWrp.get_value(FUNIT_TWIP)));
    return aItem;
}

bool MarginControlsWrapper::get_value_changed_from_saved() const
{
    return mrLeftWrp.get_value_changed_from_saved() ||
           mrRightWrp.get_value_changed_from_saved() ||
           mrTopWrp.get_value_changed_from_saved() ||
           mrBottomWrp.get_value_changed_from_saved();
}

void MarginControlsWrapper::SetControlValue(const SvxMarginItem& rItem)
{
    mrLeftWrp.set_value(mrLeftWrp.normalize(rItem.GetLeftMargin()), FUNIT_TWIP);
    mrRightWrp.set_value(mrRightWrp.normalize(rItem.GetRightMargin()), FUNIT_TWIP);
    mrTopWrp.set_value(mrTopWrp.normalize(rItem.GetTopMargin()), FUNIT_TWIP);
    mrBottomWrp.set_value(mrBottomWrp.normalize(rItem.GetBottomMargin()), FUNIT_TWIP);
    mrLeftWrp.save_value();
    mrRightWrp.save_value();
    mrTopWrp.save_value();
    mrBottomWrp.save_value();
}

SvxBorderTabPage::SvxBorderTabPage(TabPageParent pParent, const SfxItemSet& rCoreAttrs)
    : SfxTabPage(pParent, "cui/ui/borderpage.ui", "BorderPage", &rCoreAttrs)
    , nMinValue(0)
    , nSWMode(SwBorderModes::NONE)
    , mnBoxSlot(SID_ATTR_BORDER_OUTER)
    , mnShadowSlot(SID_ATTR_BORDER_SHADOW)
    , mbHorEnabled(false)
    , mbVerEnabled(false)
    , mbTLBREnabled(false)
@@ -106,38 +220,36 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore
    , mbSync(true)
    , mbRemoveAdjacentCellBorders(false)
    , bIsCalcDoc(false)
    , m_xWndPresets(new SvtValueSet(m_xBuilder->weld_scrolled_window("presetswin")))
    , m_xWndPresetsWin(new weld::CustomWeld(*m_xBuilder, "presets", *m_xWndPresets))
    , m_xUserDefFT(m_xBuilder->weld_label("userdefft"))
    , m_xFrameSelWin(new weld::CustomWeld(*m_xBuilder, "framesel", m_aFrameSel))
    , m_xLbLineStyle(new SvtLineListBox(m_xBuilder->weld_menu_button("linestylelb")))
    , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"), GetFrameWeld()))
    , m_xLineWidthMF(m_xBuilder->weld_metric_spin_button("linewidthmf", FUNIT_POINT))
    , m_xSpacingFrame(m_xBuilder->weld_container("spacing"))
    , m_xLeftFT(m_xBuilder->weld_label("leftft"))
    , m_xLeftMF(m_xBuilder->weld_metric_spin_button("leftmf", FUNIT_MM))
    , m_xRightFT(m_xBuilder->weld_label("rightft"))
    , m_xRightMF(m_xBuilder->weld_metric_spin_button("rightmf", FUNIT_MM))
    , m_xTopFT(m_xBuilder->weld_label("topft"))
    , m_xTopMF(m_xBuilder->weld_metric_spin_button("topmf", FUNIT_MM))
    , m_xBottomFT(m_xBuilder->weld_label("bottomft"))
    , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottommf", FUNIT_MM))
    , m_xSynchronizeCB(m_xBuilder->weld_check_button("sync"))
    , m_xShadowFrame(m_xBuilder->weld_container("shadow"))
    , m_xWndShadows(new SvtValueSet(m_xBuilder->weld_scrolled_window("shadowswin")))
    , m_xWndShadowsWin(new weld::CustomWeld(*m_xBuilder, "shadows", *m_xWndShadows))
    , m_xFtShadowSize(m_xBuilder->weld_label("distanceft"))
    , m_xEdShadowSize(m_xBuilder->weld_metric_spin_button("distancemf", FUNIT_MM))
    , m_xFtShadowColor(m_xBuilder->weld_label("shadowcolorft"))
    , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("shadowcolorlb"), GetFrameWeld()))
    , m_xPropertiesFrame(m_xBuilder->weld_container("properties"))
    , m_xMergeWithNextCB(m_xBuilder->weld_check_button("mergewithnext"))
    , m_xMergeAdjacentBordersCB(m_xBuilder->weld_check_button("mergeadjacent"))
    , m_xRemoveAdjcentCellBordersCB(m_xBuilder->weld_check_button("rmadjcellborders"))
    , m_xRemoveAdjcentCellBordersFT(m_xBuilder->weld_label("rmadjcellbordersft"))
{
    get(m_pWndPresets, "presets");
    get(m_pUserDefFT, "userdefft");
    get(m_pFrameSel, "framesel");
    get(m_pLbLineStyle, "linestylelb");
    get(m_pLbLineColor, "linecolorlb");
    get(m_pLineWidthMF, "linewidthmf");

    get(m_pSpacingFrame, "spacing");
    get(m_pLeftFT, "leftft");
    get(m_pLeftMF, "leftmf");
    get(m_pRightFT, "rightft");
    get(m_pRightMF, "rightmf");
    get(m_pTopFT, "topft");
    get(m_pTopMF, "topmf");
    get(m_pBottomFT, "bottomft");
    get(m_pBottomMF, "bottommf");
    get(m_pSynchronizeCB, "sync");

    get(m_pShadowFrame, "shadow");
    get(m_pWndShadows, "shadows");
    get(m_pFtShadowSize, "distanceft");
    get(m_pEdShadowSize, "distancemf");
    get(m_pFtShadowColor, "shadowcolorft");
    get(m_pLbShadowColor, "shadowcolorlb");

    get(m_pPropertiesFrame, "properties");
    get(m_pMergeWithNextCB, "mergewithnext");
    get(m_pMergeAdjacentBordersCB, "mergeadjacent");
    get(m_pRemoveAdjcentCellBordersCB, "rmadjcellborders");
    get(m_pRemoveAdjcentCellBordersFT, "rmadjcellbordersft");

    static const OUStringLiteral pnBorderImgIds[] =
    {
        RID_SVXBMP_CELL_NONE,
@@ -209,7 +321,7 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore
    {
        // The caller specifies default line width.  Honor it.
        const SfxInt64Item* p = static_cast<const SfxInt64Item*>(pItem);
        m_pLineWidthMF->SetValue(p->GetValue());
        m_xLineWidthMF->set_value(p->GetValue(), FUNIT_POINT);
    }

    // set metric
@@ -249,7 +361,7 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore
        }
    }

    SetFieldUnit(*m_pEdShadowSize, eFUnit);
    SetFieldUnit(*m_xEdShadowSize, eFUnit);

    sal_uInt16 nWhich = GetWhich( SID_ATTR_BORDER_INNER, false );
    bool bIsDontCare = true;
@@ -267,30 +379,30 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore

        if(pBoxInfo->IsDist())
        {
            SetFieldUnit(*m_pLeftMF, eFUnit);
            SetFieldUnit(*m_pRightMF, eFUnit);
            SetFieldUnit(*m_pTopMF, eFUnit);
            SetFieldUnit(*m_pBottomMF, eFUnit);
            m_pSynchronizeCB->SetClickHdl(LINK(this, SvxBorderTabPage, SyncHdl_Impl));
            m_pLeftMF->SetModifyHdl(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            m_pRightMF->SetModifyHdl(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            m_pTopMF->SetModifyHdl(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            m_pBottomMF->SetModifyHdl(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            SetFieldUnit(*m_xLeftMF, eFUnit);
            SetFieldUnit(*m_xRightMF, eFUnit);
            SetFieldUnit(*m_xTopMF, eFUnit);
            SetFieldUnit(*m_xBottomMF, eFUnit);
            m_xSynchronizeCB->connect_toggled(LINK(this, SvxBorderTabPage, SyncHdl_Impl));
            m_xLeftMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            m_xRightMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            m_xTopMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
            m_xBottomMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
        }
        else
        {
            m_pSpacingFrame->Hide();
            m_xSpacingFrame->hide();
        }
        bIsDontCare = !pBoxInfo->IsValid( SvxBoxInfoItemValidFlags::DISABLE );
    }
    if(!mbUseMarginItem && eFUnit == FUNIT_MM && MapUnit::MapTwip == rCoreAttrs.GetPool()->GetMetric( GetWhich( SID_ATTR_BORDER_INNER ) ))
    {
        //#i91548# changing the number of decimal digits changes the minimum values, too
        lcl_SetDecimalDigitsTo1(*m_pLeftMF);
        lcl_SetDecimalDigitsTo1(*m_pRightMF);
        lcl_SetDecimalDigitsTo1(*m_pTopMF);
        lcl_SetDecimalDigitsTo1(*m_pBottomMF);
        lcl_SetDecimalDigitsTo1(*m_pEdShadowSize);
        lcl_SetDecimalDigitsTo1(*m_xLeftMF);
        lcl_SetDecimalDigitsTo1(*m_xRightMF);
        lcl_SetDecimalDigitsTo1(*m_xTopMF);
        lcl_SetDecimalDigitsTo1(*m_xBottomMF);
        lcl_SetDecimalDigitsTo1(*m_xEdShadowSize);
    }

    FrameSelFlags nFlags = FrameSelFlags::Outer;
@@ -304,20 +416,19 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore
        nFlags |= FrameSelFlags::DiagonalBLTR;
    if( bIsDontCare )
        nFlags |= FrameSelFlags::DontCare;
    m_pFrameSel->Initialize( nFlags );
    m_aFrameSel.Initialize( nFlags );

    m_pFrameSel->SetSelectHdl(LINK(this, SvxBorderTabPage, LinesChanged_Impl));
    m_pLbLineStyle->SetSelectHdl( LINK( this, SvxBorderTabPage, SelStyleHdl_Impl ) );
    m_pLbLineColor->SetSelectHdl( LINK( this, SvxBorderTabPage, SelColHdl_Impl ) );
    m_pLineWidthMF->SetModifyHdl( LINK( this, SvxBorderTabPage, ModifyWidthHdl_Impl ) );
    m_pWndPresets->SetSelectHdl( LINK( this, SvxBorderTabPage, SelPreHdl_Impl ) );
    m_pWndShadows->SetSelectHdl( LINK( this, SvxBorderTabPage, SelSdwHdl_Impl ) );
    m_aFrameSel.SetSelectHdl(LINK(this, SvxBorderTabPage, LinesChanged_Impl));
    m_xLbLineStyle->SetSelectHdl( LINK( this, SvxBorderTabPage, SelStyleHdl_Impl ) );
    m_xLbLineColor->SetSelectHdl( LINK( this, SvxBorderTabPage, SelColHdl_Impl ) );
    m_xLineWidthMF->connect_value_changed( LINK( this, SvxBorderTabPage, ModifyWidthHdl_Impl ) );
    m_xWndPresets->SetSelectHdl( LINK( this, SvxBorderTabPage, SelPreHdl_Impl ) );
    m_xWndShadows->SetSelectHdl( LINK( this, SvxBorderTabPage, SelSdwHdl_Impl ) );

    FillValueSets();
    FillLineListBox_Impl();

    // connections
    sal_uInt16 nShadowSlot = SID_ATTR_BORDER_SHADOW;
    if (rCoreAttrs.HasItem(GetWhich(SID_ATTR_CHAR_GRABBAG), &pItem))
    {
        const SfxGrabBagItem* pGrabBag = static_cast<const SfxGrabBagItem*>(pItem);
@@ -328,29 +439,25 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore
            it->second >>= bDialogUseCharAttr;
            if (bDialogUseCharAttr)
            {
                nShadowSlot = SID_ATTR_CHAR_SHADOW;
                mnShadowSlot = SID_ATTR_CHAR_SHADOW;
                mnBoxSlot = SID_ATTR_CHAR_BOX;
            }
        }
    }

    bool bSupportsShadow = !SfxItemPool::IsSlot( GetWhich( nShadowSlot ) );
    bool bSupportsShadow = !SfxItemPool::IsSlot(GetWhich(mnShadowSlot));
    if( bSupportsShadow )
        AddItemConnection( svx::CreateShadowConnection( nShadowSlot, rCoreAttrs, *m_pWndShadows, *m_pEdShadowSize, *m_pLbShadowColor ) );
        m_xShadowControls.reset(new ShadowControlsWrapper(*m_xWndShadows, *m_xEdShadowSize, *m_xLbShadowColor));
    else
        HideShadowControls();

    if( mbUseMarginItem )
        AddItemConnection( svx::CreateMarginConnection( rCoreAttrs, *m_pLeftMF, *m_pRightMF, *m_pTopMF, *m_pBottomMF ) );
    if( m_pFrameSel->IsBorderEnabled( svx::FrameBorderType::TLBR ) )
        AddItemConnection( svx::CreateFrameLineConnection( SID_ATTR_BORDER_DIAG_TLBR, *m_pFrameSel, svx::FrameBorderType::TLBR ) );
    if( m_pFrameSel->IsBorderEnabled( svx::FrameBorderType::BLTR ) )
        AddItemConnection( svx::CreateFrameLineConnection( SID_ATTR_BORDER_DIAG_BLTR, *m_pFrameSel, svx::FrameBorderType::BLTR ) );
    if (mbUseMarginItem)
        m_xMarginControls.reset(new MarginControlsWrapper(*m_xLeftMF, *m_xRightMF, *m_xTopMF, *m_xBottomMF));

    // checkbox "Merge with next paragraph" only visible for Writer dialog format.paragraph
    m_pMergeWithNextCB->Hide();
    m_xMergeWithNextCB->hide();
    // checkbox "Merge adjacent line styles" only visible for Writer dialog format.table
    m_pMergeAdjacentBordersCB->Hide();
    m_xMergeAdjacentBordersCB->hide();

    SfxObjectShell* pDocSh = SfxObjectShell::Current();
    if (pDocSh)
@@ -361,14 +468,14 @@ SvxBorderTabPage::SvxBorderTabPage(vcl::Window* pParent, const SfxItemSet& rCore
    }
    if( bIsCalcDoc )
    {
        m_pRemoveAdjcentCellBordersCB->SetClickHdl(LINK(this, SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl));
        m_pRemoveAdjcentCellBordersCB->Show();
        m_pRemoveAdjcentCellBordersCB->Enable( false );
        m_xRemoveAdjcentCellBordersCB->connect_toggled(LINK(this, SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl));
        m_xRemoveAdjcentCellBordersCB->show();
        m_xRemoveAdjcentCellBordersCB->set_sensitive(false);
    }
    else
    {
        m_pRemoveAdjcentCellBordersCB->Hide();
        m_pRemoveAdjcentCellBordersFT->Hide();
        m_xRemoveAdjcentCellBordersCB->hide();
        m_xRemoveAdjcentCellBordersFT->hide();
    }
}

@@ -379,50 +486,31 @@ SvxBorderTabPage::~SvxBorderTabPage()

void SvxBorderTabPage::dispose()
{
    m_pWndPresets.clear();
    m_pUserDefFT.clear();
    m_pFrameSel.clear();
    m_pLbLineStyle.clear();
    m_pLbLineColor.clear();
    m_pLineWidthMF.clear();
    m_pSpacingFrame.clear();
    m_pLeftFT.clear();
    m_pLeftMF.clear();
    m_pRightFT.clear();
    m_pRightMF.clear();
    m_pTopFT.clear();
    m_pTopMF.clear();
    m_pBottomFT.clear();
    m_pBottomMF.clear();
    m_pSynchronizeCB.clear();
    m_pShadowFrame.clear();
    m_pWndShadows.clear();
    m_pFtShadowSize.clear();
    m_pEdShadowSize.clear();
    m_pFtShadowColor.clear();
    m_pLbShadowColor.clear();
    m_pPropertiesFrame.clear();
    m_pMergeWithNextCB.clear();
    m_pMergeAdjacentBordersCB.clear();
    m_pRemoveAdjcentCellBordersCB.clear();
    m_pRemoveAdjcentCellBordersFT.clear();
    m_xLbShadowColor.reset();
    m_xWndShadowsWin.reset();
    m_xWndShadows.reset();
    m_xLbLineColor.reset();
    m_xLbLineStyle.reset();
    m_xFrameSelWin.reset();
    m_xWndPresetsWin.reset();
    m_xWndPresets.reset();
    SfxTabPage::dispose();
}

VclPtr<SfxTabPage> SvxBorderTabPage::Create( TabPageParent pParent,
                                             const SfxItemSet* rAttrSet )
{
    return VclPtr<SvxBorderTabPage>::Create( pParent.pParent, *rAttrSet );
    return VclPtr<SvxBorderTabPage>::Create(pParent, *rAttrSet);
}

void SvxBorderTabPage::ResetFrameLine_Impl( svx::FrameBorderType eBorder, const SvxBorderLine* pCoreLine, bool bValid )
{
    if( m_pFrameSel->IsBorderEnabled( eBorder ) )
    if( m_aFrameSel.IsBorderEnabled( eBorder ) )
    {
        if( bValid )
            m_pFrameSel->ShowBorder( eBorder, pCoreLine );
            m_aFrameSel.ShowBorder( eBorder, pCoreLine );
        else
            m_pFrameSel->SetBorderDontCare( eBorder );
            m_aFrameSel.SetBorderDontCare( eBorder );
    }
}

@@ -437,24 +525,49 @@ bool SvxBorderTabPage::IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) con

void SvxBorderTabPage::Reset( const SfxItemSet* rSet )
{
    SfxTabPage::Reset( rSet );

    SfxItemPool* pPool = rSet->GetPool();

    if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR))
    {
        sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_TLBR);
        const SvxLineItem& rLineItem(*static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)));
        m_aFrameSel.ShowBorder(svx::FrameBorderType::TLBR, rLineItem.GetLine());
    }

    if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR))
    {
        sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_BLTR);
        const SvxLineItem& rLineItem(*static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)));
        m_aFrameSel.ShowBorder(svx::FrameBorderType::BLTR, rLineItem.GetLine());
    }

    if (m_xShadowControls)
    {
        sal_uInt16 nShadowId = pPool->GetWhich(mnShadowSlot);
        m_xShadowControls->SetControlValue(*static_cast<const SvxShadowItem*>(rSet->GetItem(nShadowId)));
    }

    if (m_xMarginControls)
    {
        sal_uInt16 nAlignMarginId = pPool->GetWhich(SID_ATTR_ALIGN_MARGIN);
        m_xMarginControls->SetControlValue(*static_cast<const SvxMarginItem*>(rSet->GetItem(nAlignMarginId)));
    }

    sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
    const SfxBoolItem *pMergeAdjacentBorders = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeAdjacentBordersId));
    if (!pMergeAdjacentBorders)
        m_pMergeAdjacentBordersCB->SetState(TRISTATE_INDET);
        m_xMergeAdjacentBordersCB->set_state(TRISTATE_INDET);
    else
        m_pMergeAdjacentBordersCB->Check(pMergeAdjacentBorders->GetValue());
    m_pMergeAdjacentBordersCB->SaveValue();
        m_xMergeAdjacentBordersCB->set_active(pMergeAdjacentBorders->GetValue());
    m_xMergeAdjacentBordersCB->save_state();

    sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
    const SfxBoolItem *pMergeWithNext = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeWithNextId));
    if (!pMergeWithNext)
        m_pMergeWithNextCB->SetState(TRISTATE_INDET);
        m_xMergeWithNextCB->set_state(TRISTATE_INDET);
    else
        m_pMergeWithNextCB->Check(pMergeWithNext->GetValue());
    m_pMergeWithNextCB->SaveValue();
        m_xMergeWithNextCB->set_active(pMergeWithNext->GetValue());
    m_xMergeWithNextCB->save_state();

    const SvxBoxItem*       pBoxItem;
    const SvxBoxInfoItem*   pBoxInfoItem;
@@ -481,89 +594,68 @@ void SvxBorderTabPage::Reset( const SfxItemSet* rSet )

        if( !mbUseMarginItem )
        {
            if ( m_pLeftMF->IsVisible() )
            if (m_xLeftMF->get_visible())
            {
                SetMetricValue(*m_pLeftMF,    pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_pRightMF,   pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_pTopMF,     pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_pBottomMF,  pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_xLeftMF,    pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_xRightMF,   pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_xTopMF,     pBoxInfoItem->GetDefDist(), eCoreUnit);
                SetMetricValue(*m_xBottomMF,  pBoxInfoItem->GetDefDist(), eCoreUnit);

                nMinValue = static_cast<long>(m_pLeftMF->GetValue());
                nMinValue = m_xLeftMF->get_value(FUNIT_NONE);

                if ( pBoxInfoItem->IsMinDist() )
                {
                    m_pLeftMF->SetFirst( nMinValue );
                    m_pRightMF->SetFirst( nMinValue );
                    m_pTopMF->SetFirst( nMinValue );
                    m_pBottomMF->SetFirst( nMinValue );
                    m_xLeftMF->set_min(nMinValue, FUNIT_NONE);
                    m_xRightMF->set_min(nMinValue, FUNIT_NONE);
                    m_xTopMF->set_min(nMinValue, FUNIT_NONE);
                    m_xBottomMF->set_min(nMinValue, FUNIT_NONE);
                }

                if ( pBoxInfoItem->IsDist() )
                {
                    if( rSet->GetItemState( nWhichBox ) >= SfxItemState::DEFAULT )
                    {
                        bool bIsAnyBorderVisible = m_pFrameSel->IsAnyBorderVisible();
                        bool bIsAnyBorderVisible = m_aFrameSel.IsAnyBorderVisible();
                        if( !bIsAnyBorderVisible || !pBoxInfoItem->IsMinDist() )
                        {
                            m_pLeftMF->SetMin( 0 );
                            m_pLeftMF->SetFirst( 0 );
                            m_pRightMF->SetMin( 0 );
                            m_pRightMF->SetFirst( 0 );
                            m_pTopMF->SetMin( 0 );
                            m_pTopMF->SetFirst( 0 );
                            m_pBottomMF->SetMin( 0 );
                            m_pBottomMF->SetFirst( 0 );
                            m_xLeftMF->set_min(0, FUNIT_NONE);
                            m_xRightMF->set_min(0, FUNIT_NONE);
                            m_xTopMF->set_min(0, FUNIT_NONE);
                            m_xBottomMF->set_min(0, FUNIT_NONE);
                        }
                        long nLeftDist = pBoxItem->GetDistance( SvxBoxItemLine::LEFT);
                        SetMetricValue(*m_pLeftMF, nLeftDist, eCoreUnit);
                        SetMetricValue(*m_xLeftMF, nLeftDist, eCoreUnit);
                        long nRightDist = pBoxItem->GetDistance( SvxBoxItemLine::RIGHT);
                        SetMetricValue(*m_pRightMF, nRightDist, eCoreUnit);
                        SetMetricValue(*m_xRightMF, nRightDist, eCoreUnit);
                        long nTopDist = pBoxItem->GetDistance( SvxBoxItemLine::TOP);
                        SetMetricValue( *m_pTopMF, nTopDist, eCoreUnit );
                        SetMetricValue( *m_xTopMF, nTopDist, eCoreUnit );
                        long nBottomDist = pBoxItem->GetDistance( SvxBoxItemLine::BOTTOM);
                        SetMetricValue( *m_pBottomMF, nBottomDist, eCoreUnit );

                        // if the distance is set with no active border line
                        // or it is null with an active border line
                        // no automatic changes should be made
                        const long nDefDist = bIsAnyBorderVisible ? pBoxInfoItem->GetDefDist() : 0;
                        bool bDiffDist = (nDefDist != nLeftDist ||
                                    nDefDist != nRightDist ||
                                    nDefDist != nTopDist   ||
                                    nDefDist != nBottomDist);
                        if ((pBoxItem->GetSmallestDistance() ||
                                bIsAnyBorderVisible) && bDiffDist )
                        {
                            m_pLeftMF->SetModifyFlag();
                            m_pRightMF->SetModifyFlag();
                            m_pTopMF->SetModifyFlag();
                            m_pBottomMF->SetModifyFlag();
                        }
                        SetMetricValue( *m_xBottomMF, nBottomDist, eCoreUnit );
                    }
                    else
                    {
                        // #106224# different margins -> do not fill the edits
                        m_pLeftMF->SetText( OUString() );
                        m_pRightMF->SetText( OUString() );
                        m_pTopMF->SetText( OUString() );
                        m_pBottomMF->SetText( OUString() );
                        m_xLeftMF->set_text( OUString() );
                        m_xRightMF->set_text( OUString() );
                        m_xTopMF->set_text( OUString() );
                        m_xBottomMF->set_text( OUString() );
                    }
                }
                m_pLeftMF->SaveValue();
                m_pRightMF->SaveValue();
                m_pTopMF->SaveValue();
                m_pBottomMF->SaveValue();
                m_xLeftMF->save_value();
                m_xRightMF->save_value();
                m_xTopMF->save_value();
                m_xBottomMF->save_value();
            }
        }
    }
    else
    {
        // avoid ResetFrameLine-calls:
        m_pFrameSel->HideAllBorders();
        m_aFrameSel.HideAllBorders();
    }

    if( !m_pFrameSel->IsAnyBorderVisible() )
        m_pFrameSel->DeselectAllBorders();
    if( !m_aFrameSel.IsAnyBorderVisible() )
        m_aFrameSel.DeselectAllBorders();

    // depict line (color) in controllers if unambiguous:

@@ -571,54 +663,54 @@ void SvxBorderTabPage::Reset( const SfxItemSet* rSet )
        // Do all visible lines show the same line widths?
        long nWidth;
        SvxBorderLineStyle nStyle;
        bool bWidthEq = m_pFrameSel->GetVisibleWidth( nWidth, nStyle );
        bool bWidthEq = m_aFrameSel.GetVisibleWidth( nWidth, nStyle );
        if( bWidthEq )
        {
            // Determine the width first as some styles can be missing depending on it
            sal_Int64 nWidthPt =  static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                        sal_Int64( nWidth ), m_pLineWidthMF->GetDecimalDigits( ),
                        MapUnit::MapTwip, m_pLineWidthMF->GetUnit() ));
            m_pLineWidthMF->SetValue( nWidthPt );
            m_pLbLineStyle->SetWidth(5);
                        sal_Int64( nWidth ), m_xLineWidthMF->get_digits(),
                        MapUnit::MapTwip, FUNIT_POINT ));
            m_xLineWidthMF->set_value(nWidthPt, FUNIT_POINT);
            m_xLbLineStyle->SetWidth(nWidth);

            // then set the style
            m_pLbLineStyle->SelectEntry( nStyle );
            m_xLbLineStyle->SelectEntry( nStyle );
        }
        else
            m_pLbLineStyle->SelectEntryPos( 1 );
            m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);

        // Do all visible lines show the same line color?
        Color aColor;
        bool bColorEq = m_pFrameSel->GetVisibleColor( aColor );
        bool bColorEq = m_aFrameSel.GetVisibleColor( aColor );
        if( !bColorEq )
            aColor = COL_BLACK;

        m_pLbLineColor->SelectEntry(aColor);
        m_pLbLineStyle->SetColor(GetTextColor());
        m_xLbLineColor->SelectEntry(aColor);
        m_xLbLineStyle->SetColor(GetTextColor());

        // Select all visible lines, if they are all equal.
        if( bWidthEq && bColorEq )
            m_pFrameSel->SelectAllVisibleBorders();
            m_aFrameSel.SelectAllVisibleBorders();

        // set the current style and color (caches style in control even if nothing is selected)
        SelStyleHdl_Impl(*m_pLbLineStyle);
        SelColHdl_Impl(*m_pLbLineColor);
        SelStyleHdl_Impl(*m_xLbLineStyle);
        SelColHdl_Impl(*m_xLbLineColor);
    }

    bool bEnable = m_pWndShadows->GetSelectedItemId() > 1 ;
    m_pFtShadowSize->Enable(bEnable);
    m_pEdShadowSize->Enable(bEnable);
    m_pFtShadowColor->Enable(bEnable);
    m_pLbShadowColor->Enable(bEnable);
    bool bEnable = m_xWndShadows->GetSelectedItemId() > 1 ;
    m_xFtShadowSize->set_sensitive(bEnable);
    m_xEdShadowSize->set_sensitive(bEnable);
    m_xFtShadowColor->set_sensitive(bEnable);
    m_xLbShadowColor->set_sensitive(bEnable);

    m_pWndPresets->SetNoSelection();
    m_xWndPresets->SetNoSelection();

    // - no line - should not be selected

    if ( m_pLbLineStyle->GetSelectedEntryPos() == 0 )
    if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
    {
        m_pLbLineStyle->SelectEntryPos( 1 );
        SelStyleHdl_Impl(*m_pLbLineStyle);
        m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
        SelStyleHdl_Impl(*m_xLbLineStyle);
    }

    const SfxPoolItem* pItem;
@@ -631,39 +723,43 @@ void SvxBorderTabPage::Reset( const SfxItemSet* rSet )
        if(nHtmlMode & HTMLMODE_ON)
        {
            // there are no shadows in Html-mode and only complete borders
            m_pShadowFrame->Disable();
            m_xShadowFrame->set_sensitive(false);

            if( !(nSWMode & SwBorderModes::TABLE) )
            {
                m_pUserDefFT->Disable();
                m_pFrameSel->Disable();
                m_pWndPresets->RemoveItem(3);
                m_pWndPresets->RemoveItem(4);
                m_pWndPresets->RemoveItem(5);
                m_xUserDefFT->set_sensitive(false);
                m_xFrameSelWin->set_sensitive(false);
                m_xWndPresets->RemoveItem(3);
                m_xWndPresets->RemoveItem(4);
                m_xWndPresets->RemoveItem(5);
            }
        }
    }

    LinesChanged_Impl( nullptr );
    if(m_pLeftMF->GetValue() == m_pRightMF->GetValue() && m_pTopMF->GetValue() == m_pBottomMF->GetValue() && m_pTopMF->GetValue() == m_pLeftMF->GetValue())
    if (m_xLeftMF->get_value(FUNIT_NONE) == m_xRightMF->get_value(FUNIT_NONE) &&
        m_xTopMF->get_value(FUNIT_NONE) == m_xBottomMF->get_value(FUNIT_NONE) &&
        m_xTopMF->get_value(FUNIT_NONE) == m_xLeftMF->get_value(FUNIT_NONE))
    {
        mbSync = true;
    }
    else
        mbSync = false;
    m_pSynchronizeCB->Check(mbSync);
    m_xSynchronizeCB->set_active(mbSync);

    mbRemoveAdjacentCellBorders = false;
    m_pRemoveAdjcentCellBordersCB->Check( false );
    m_pRemoveAdjcentCellBordersCB->Enable( false );
    m_xRemoveAdjcentCellBordersCB->set_active(false);
    m_xRemoveAdjcentCellBordersCB->set_sensitive(false);
}

void SvxBorderTabPage::ChangesApplied()
{
    m_pLeftMF->SaveValue();
    m_pRightMF->SaveValue();
    m_pTopMF->SaveValue();
    m_pBottomMF->SaveValue();
    m_pMergeWithNextCB->SaveValue();
    m_pMergeAdjacentBordersCB->SaveValue();
    m_xLeftMF->save_value();
    m_xRightMF->save_value();
    m_xTopMF->save_value();
    m_xBottomMF->save_value();
    m_xMergeWithNextCB->save_state();
    m_xMergeAdjacentBordersCB->save_state();
}

DeactivateRC SvxBorderTabPage::DeactivatePage( SfxItemSet* _pSet )
@@ -676,13 +772,52 @@ DeactivateRC SvxBorderTabPage::DeactivatePage( SfxItemSet* _pSet )

bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
{
    bool bAttrsChanged = SfxTabPage::FillItemSet( rCoreAttrs );
    bool bAttrsChanged = false;

    SfxItemPool* pPool = rCoreAttrs->GetPool();
    if (m_pMergeAdjacentBordersCB->IsValueChangedFromSaved())

    if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR))
    {
        sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_TLBR);
        SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(rCoreAttrs->GetItem(nBorderDiagId)));
        aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::TLBR));
        rCoreAttrs->Put(aLineItem);
        bAttrsChanged = true;
    }

    if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR))
    {
        sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_BLTR);
        SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(rCoreAttrs->GetItem(nBorderDiagId)));
        aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::BLTR));
        rCoreAttrs->Put(aLineItem);
        bAttrsChanged = true;
    }

    if (m_xShadowControls)
    {
        sal_uInt16 nShadowId = pPool->GetWhich(mnShadowSlot);
        const SvxShadowItem& rOldShadowItem = *static_cast<const SvxShadowItem*>(rCoreAttrs->GetItem(nShadowId));
        SvxShadowItem aNewShadowItem = m_xShadowControls->GetControlValue(rOldShadowItem);
        if (aNewShadowItem != rOldShadowItem)
        {
            rCoreAttrs->Put(aNewShadowItem);
            bAttrsChanged = true;
        }
    }

    if (m_xMarginControls && m_xMarginControls->get_value_changed_from_saved())
    {
        sal_uInt16 nAlignMarginId = pPool->GetWhich(SID_ATTR_ALIGN_MARGIN);
        const SvxMarginItem& rOldMarginItem = *static_cast<const SvxMarginItem*>(rCoreAttrs->GetItem(nAlignMarginId));
        rCoreAttrs->Put(m_xMarginControls->GetControlValue(rOldMarginItem));
        bAttrsChanged = true;
    }

    if (m_xMergeAdjacentBordersCB->get_state_changed_from_saved())
    {
        sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
        auto nState = m_pMergeAdjacentBordersCB->GetState();
        auto nState = m_xMergeAdjacentBordersCB->get_state();
        if (nState == TRISTATE_INDET)
            rCoreAttrs->ClearItem(nMergeAdjacentBordersId);
        else
@@ -694,10 +829,10 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
        bAttrsChanged = true;
    }

    if (m_pMergeWithNextCB->IsValueChangedFromSaved())
    if (m_xMergeWithNextCB->get_state_changed_from_saved())
    {
        sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
        auto nState = m_pMergeWithNextCB->GetState();
        auto nState = m_xMergeWithNextCB->get_state();
        if (nState == TRISTATE_INDET)
            rCoreAttrs->ClearItem(nMergeWithNextId);
        else
@@ -730,7 +865,7 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
                            };

    for (std::pair<svx::FrameBorderType,SvxBoxItemLine> const & i : eTypes1)
        aBoxItem.SetLine( m_pFrameSel->GetFrameBorderStyle( i.first ), i.second );
        aBoxItem.SetLine( m_aFrameSel.GetFrameBorderStyle( i.first ), i.second );


    aBoxItem.SetRemoveAdjacentCellBorder( mbRemoveAdjacentCellBorders );
@@ -741,7 +876,7 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
                                { svx::FrameBorderType::Vertical,SvxBoxInfoItemLine::VERT }
                            };
    for (std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> const & j : eTypes2)
        aBoxInfoItem.SetLine( m_pFrameSel->GetFrameBorderStyle( j.first ), j.second );
        aBoxInfoItem.SetLine( m_aFrameSel.GetFrameBorderStyle( j.first ), j.second );

    aBoxInfoItem.EnableHor( mbHorEnabled );
    aBoxInfoItem.EnableVer( mbVerEnabled );
@@ -749,7 +884,7 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )

    // inner distance

    if( m_pLeftMF->IsVisible() )
    if (m_xLeftMF->get_visible())
    {
        // #i40405# enable distance controls for next dialog call
        aBoxInfoItem.SetDist( true );
@@ -757,36 +892,36 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
        if( !mbUseMarginItem )
        {
            // #106224# all edits empty: do nothing
            if( !m_pLeftMF->GetText().isEmpty() || !m_pRightMF->GetText().isEmpty() ||
                !m_pTopMF->GetText().isEmpty() || !m_pBottomMF->GetText().isEmpty() )
            if( !m_xLeftMF->get_text().isEmpty() || !m_xRightMF->get_text().isEmpty() ||
                !m_xTopMF->get_text().isEmpty() || !m_xBottomMF->get_text().isEmpty() )
            {
                if ( mbAllowPaddingWithoutBorders
                     || ((mbHorEnabled || mbVerEnabled || (nSWMode & SwBorderModes::TABLE)) &&
                         (m_pLeftMF->IsModified()||m_pRightMF->IsModified()||
                             m_pTopMF->IsModified()||m_pBottomMF->IsModified()) )
                     || m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Top ) != svx::FrameBorderState::Hide
                     || m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::Hide
                     || m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Left ) != svx::FrameBorderState::Hide
                     || m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Right ) != svx::FrameBorderState::Hide )
                         (m_xLeftMF->get_value_changed_from_saved()||m_xRightMF->get_value_changed_from_saved()||
                             m_xTopMF->get_value_changed_from_saved()||m_xBottomMF->get_value_changed_from_saved()) )
                     || m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top ) != svx::FrameBorderState::Hide
                     || m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::Hide
                     || m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left ) != svx::FrameBorderState::Hide
                     || m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right ) != svx::FrameBorderState::Hide )
                {
                    const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER );
                    if (
                        !pOldBoxItem ||
                        m_pLeftMF->IsValueChangedFromSaved() ||
                        m_pRightMF->IsValueChangedFromSaved() ||
                        m_pTopMF->IsValueChangedFromSaved() ||
                        m_pBottomMF->IsValueChangedFromSaved() ||
                        nMinValue == m_pLeftMF->GetValue() ||
                        nMinValue == m_pRightMF->GetValue() ||
                        nMinValue == m_pTopMF->GetValue() ||
                        nMinValue == m_pBottomMF->GetValue() ||
                        m_xLeftMF->get_value_changed_from_saved() ||
                        m_xRightMF->get_value_changed_from_saved() ||
                        m_xTopMF->get_value_changed_from_saved() ||
                        m_xBottomMF->get_value_changed_from_saved() ||
                        nMinValue == m_xLeftMF->get_value(FUNIT_NONE) ||
                        nMinValue == m_xRightMF->get_value(FUNIT_NONE) ||
                        nMinValue == m_xTopMF->get_value(FUNIT_NONE) ||
                        nMinValue == m_xBottomMF->get_value(FUNIT_NONE) ||
                        (pOldBoxInfoItem && !pOldBoxInfoItem->IsValid(SvxBoxInfoItemValidFlags::DISTANCE))
                       )
                    {
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_pLeftMF, eCoreUnit )), SvxBoxItemLine::LEFT  );
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_pRightMF, eCoreUnit )), SvxBoxItemLine::RIGHT );
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_pTopMF, eCoreUnit )), SvxBoxItemLine::TOP   );
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_pBottomMF, eCoreUnit )), SvxBoxItemLine::BOTTOM);
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xLeftMF, eCoreUnit )), SvxBoxItemLine::LEFT  );
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xRightMF, eCoreUnit )), SvxBoxItemLine::RIGHT );
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xTopMF, eCoreUnit )), SvxBoxItemLine::TOP   );
                        aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xBottomMF, eCoreUnit )), SvxBoxItemLine::BOTTOM);
                    }
                    else
                    {
@@ -806,12 +941,12 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )

    // note Don't Care Status in the Info-Item:

    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::TOP,    m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Top )    != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::LEFT,   m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Left )   != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::RIGHT,  m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Right )  != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::HORI,   m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Horizontal )    != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::VERT,   m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Vertical )    != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::TOP,    m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top )    != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::LEFT,   m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left )   != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::RIGHT,  m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right )  != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::HORI,   m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Horizontal )    != svx::FrameBorderState::DontCare );
    aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::VERT,   m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Vertical )    != svx::FrameBorderState::DontCare );


    // Put or Clear of the border?
@@ -858,7 +993,7 @@ bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )

void SvxBorderTabPage::HideShadowControls()
{
    m_pShadowFrame->Hide();
    m_xShadowFrame->hide();
}

#define IID_PRE_CELL_NONE       1
@@ -883,7 +1018,7 @@ void SvxBorderTabPage::HideShadowControls()
#define IID_PRE_TABLE_ALL       20
#define IID_PRE_TABLE_OUTER2    21

IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void)
IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, SvtValueSet*, void)
{
    const svx::FrameBorderState SHOW = svx::FrameBorderState::Show;
    const svx::FrameBorderState HIDE = svx::FrameBorderState::Hide;
@@ -916,11 +1051,11 @@ IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void)
    };

    // first hide and deselect all frame borders
    m_pFrameSel->HideAllBorders();
    m_pFrameSel->DeselectAllBorders();
    m_aFrameSel.HideAllBorders();
    m_aFrameSel.DeselectAllBorders();

    // Using image ID to find correct line in table above.
    sal_uInt16 nLine = GetPresetImageId( m_pWndPresets->GetSelectedItemId() ) - 1;
    sal_uInt16 nLine = GetPresetImageId( m_xWndPresets->GetSelectedItemId() ) - 1;

    // Apply all styles from the table
    for( int nBorder = 0; nBorder < svx::FRAMEBORDERTYPE_COUNT; ++nBorder )
@@ -928,73 +1063,70 @@ IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void)
        svx::FrameBorderType eBorder = svx::GetFrameBorderTypeFromIndex( nBorder );
        switch( ppeStates[ nLine ][ nBorder ] )
        {
            case SHOW:  m_pFrameSel->SelectBorder( eBorder );      break;
            case SHOW:  m_aFrameSel.SelectBorder( eBorder );      break;
            case HIDE:  /* nothing to do */                     break;
            case DONT:  m_pFrameSel->SetBorderDontCare( eBorder ); break;
            case DONT:  m_aFrameSel.SetBorderDontCare( eBorder ); break;
        }
    }

    // Show all lines that have been selected above
    if( m_pFrameSel->IsAnyBorderSelected() )
    if( m_aFrameSel.IsAnyBorderSelected() )
    {
        // any visible style, but "no-line" in line list box? -> use hair-line
        if( (m_pLbLineStyle->GetSelectedEntryPos() == 0) || (m_pLbLineStyle->GetSelectedEntryPos() == LISTBOX_ENTRY_NOTFOUND) )
            m_pLbLineStyle->SelectEntryPos( 1 );
        if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
            m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);

        // set current style to all previously selected lines
        SelStyleHdl_Impl(*m_pLbLineStyle);
        SelColHdl_Impl(*m_pLbLineColor);
        SelStyleHdl_Impl(*m_xLbLineStyle);
        SelColHdl_Impl(*m_xLbLineColor);
    }

    // Presets ValueSet does not show a selection (used as push buttons).
    m_pWndPresets->SetNoSelection();
    m_xWndPresets->SetNoSelection();

    LinesChanged_Impl( nullptr );
    UpdateRemoveAdjCellBorderCB( nLine + 1 );
}


IMPL_LINK_NOARG(SvxBorderTabPage, SelSdwHdl_Impl, ValueSet*, void)
IMPL_LINK_NOARG(SvxBorderTabPage, SelSdwHdl_Impl, SvtValueSet*, void)
{
    bool bEnable = m_pWndShadows->GetSelectedItemId() > 1;
    m_pFtShadowSize->Enable(bEnable);
    m_pEdShadowSize->Enable(bEnable);
    m_pFtShadowColor->Enable(bEnable);
    m_pLbShadowColor->Enable(bEnable);
    bool bEnable = m_xWndShadows->GetSelectedItemId() > 1;
    m_xFtShadowSize->set_sensitive(bEnable);
    m_xEdShadowSize->set_sensitive(bEnable);
    m_xFtShadowColor->set_sensitive(bEnable);
    m_xLbShadowColor->set_sensitive(bEnable);
}

IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, SvxColorListBox&, rColorBox, void)
IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, ColorListBox&, rColorBox, void)
{
    Color aColor = rColorBox.GetSelectEntryColor();
    m_pFrameSel->SetColorToSelection(aColor);
    m_aFrameSel.SetColorToSelection(aColor);
}

IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthHdl_Impl, Edit&, void)
IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthHdl_Impl, weld::MetricSpinButton&, void)
{
    sal_Int64 nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                m_pLineWidthMF->GetValue( ),
                m_pLineWidthMF->GetDecimalDigits( ),
                m_pLineWidthMF->GetUnit(), MapUnit::MapTwip ));
    sal_Int64 nVal = m_xLineWidthMF->get_value(FUNIT_NONE);
    nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                nVal,
                m_xLineWidthMF->get_digits(),
                FUNIT_POINT, MapUnit::MapTwip ));
    m_xLbLineStyle->SetWidth( nVal );

    m_pFrameSel->SetStyleToSelection( nVal,
        m_pLbLineStyle->GetSelectEntryStyle() );
    m_aFrameSel.SetStyleToSelection( nVal,
        m_xLbLineStyle->GetSelectEntryStyle() );
}


IMPL_LINK( SvxBorderTabPage, SelStyleHdl_Impl, ListBox&, rLb, void )
IMPL_LINK_NOARG(SvxBorderTabPage, SelStyleHdl_Impl, SvtLineListBox&, void)
{
    if (&rLb == m_pLbLineStyle)
    {
        sal_Int64 nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                    m_pLineWidthMF->GetValue( ),
                    m_pLineWidthMF->GetDecimalDigits( ),
                    m_pLineWidthMF->GetUnit(), MapUnit::MapTwip ));
        m_pFrameSel->SetStyleToSelection ( nVal,
            m_pLbLineStyle->GetSelectEntryStyle() );
    }
    sal_Int64 nVal = m_xLineWidthMF->get_value(FUNIT_NONE);
    nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                nVal,
                m_xLineWidthMF->get_digits(),
                FUNIT_POINT, MapUnit::MapTwip ));
    m_aFrameSel.SetStyleToSelection ( nVal,
        m_xLbLineStyle->GetSelectEntryStyle() );
}


// ValueSet handling
sal_uInt16 SvxBorderTabPage::GetPresetImageId( sal_uInt16 nValueSetIdx ) const
{
@@ -1065,27 +1197,28 @@ const char* SvxBorderTabPage::GetPresetStringId( sal_uInt16 nValueSetIdx ) const
void SvxBorderTabPage::FillPresetVS()
{
    // basic initialization of the ValueSet
    m_pWndPresets->SetStyle( m_pWndPresets->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
    m_pWndPresets->SetColCount( SVX_BORDER_PRESET_COUNT );
    m_xWndPresets->SetStyle( m_xWndPresets->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
    m_xWndPresets->SetColCount( SVX_BORDER_PRESET_COUNT );

    // insert images and help texts
    for( sal_uInt16 nVSIdx = 1; nVSIdx <= SVX_BORDER_PRESET_COUNT; ++nVSIdx )
    {
        m_pWndPresets->InsertItem( nVSIdx );
        m_pWndPresets->SetItemImage(nVSIdx, Image(m_aBorderImgVec[GetPresetImageId(nVSIdx) - 1]));
        m_pWndPresets->SetItemText( nVSIdx, CuiResId( GetPresetStringId( nVSIdx ) ) );
        m_xWndPresets->InsertItem( nVSIdx );
        m_xWndPresets->SetItemImage(nVSIdx, Image(m_aBorderImgVec[GetPresetImageId(nVSIdx) - 1]));
        m_xWndPresets->SetItemText( nVSIdx, CuiResId( GetPresetStringId( nVSIdx ) ) );
    }

    // show the control
    m_pWndPresets->SetNoSelection();
    m_pWndPresets->Show();
    m_xWndPresets->SetNoSelection();
    m_xWndPresets->SetOptimalSize();
    m_xWndPresets->Show();
}

void SvxBorderTabPage::FillShadowVS()
{
    // basic initialization of the ValueSet
    m_pWndShadows->SetStyle( m_pWndShadows->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
    m_pWndShadows->SetColCount( SVX_BORDER_SHADOW_COUNT );
    m_xWndShadows->SetStyle( m_xWndShadows->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
    m_xWndShadows->SetColCount( SVX_BORDER_SHADOW_COUNT );

    // string resource IDs for each image
    static const char* pnStrIds[ SVX_BORDER_SHADOW_COUNT ] =
@@ -1094,14 +1227,15 @@ void SvxBorderTabPage::FillShadowVS()
    // insert images and help texts
    for( sal_uInt16 nVSIdx = 1; nVSIdx <= SVX_BORDER_SHADOW_COUNT; ++nVSIdx )
    {
        m_pWndShadows->InsertItem( nVSIdx );
        m_pWndShadows->SetItemImage(nVSIdx, Image(m_aShadowImgVec[nVSIdx-1]));
        m_pWndShadows->SetItemText( nVSIdx, CuiResId( pnStrIds[ nVSIdx - 1 ] ) );
        m_xWndShadows->InsertItem( nVSIdx );
        m_xWndShadows->SetItemImage(nVSIdx, Image(m_aShadowImgVec[nVSIdx-1]));
        m_xWndShadows->SetItemText( nVSIdx, CuiResId( pnStrIds[ nVSIdx - 1 ] ) );
    }

    // show the control
    m_pWndShadows->SelectItem( 1 );
    m_pWndShadows->Show();
    m_xWndShadows->SelectItem( 1 );
    m_xWndShadows->SetOptimalSize();
    m_xWndShadows->Show();
}


@@ -1153,72 +1287,65 @@ void SvxBorderTabPage::FillLineListBox_Impl()
        { SvxBorderLineStyle::INSET,  10, &SvxBorderLine::darkColor, &SvxBorderLine::lightColor, &sameDistColor }
    };

    m_pLbLineStyle->SetSourceUnit( FUNIT_TWIP );

    m_pLbLineStyle->SetNone( SvxResId( RID_SVXSTR_NONE ) );
    m_xLbLineStyle->SetSourceUnit( FUNIT_TWIP );

    for (size_t i = 0; i < SAL_N_ELEMENTS(aLines); ++i)
    {
        if (!IsBorderLineStyleAllowed(aLines[i].mnStyle))
            continue;

        m_pLbLineStyle->InsertEntry(
        m_xLbLineStyle->InsertEntry(
            SvxBorderLine::getWidthImpl(aLines[i].mnStyle), aLines[i].mnStyle,
            aLines[i].mnMinWidth, aLines[i].mpColor1Fn, aLines[i].mpColor2Fn, aLines[i].mpColorDistFn);
    }

    sal_Int64 nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(
                m_pLineWidthMF->GetValue( ),
                m_pLineWidthMF->GetDecimalDigits( ),
                m_pLineWidthMF->GetUnit(), MapUnit::MapTwip ));
    m_pLbLineStyle->SetWidth( nVal );
    sal_Int64 nVal = m_xLineWidthMF->get_value(FUNIT_NONE);
    nVal = static_cast<sal_Int64>(MetricField::ConvertDoubleValue(nVal, m_xLineWidthMF->get_digits(),
                                                                  m_xLineWidthMF->get_unit(), MapUnit::MapTwip));
    m_xLbLineStyle->SetWidth( nVal );
}


IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl, LinkParamNone*, void)
{
    if(!mbUseMarginItem && m_pLeftMF->IsVisible())
    if (!mbUseMarginItem && m_xLeftMF->get_visible())
    {
        bool bLineSet = m_pFrameSel->IsAnyBorderVisible();
        bool bLineSet = m_aFrameSel.IsAnyBorderVisible();
        bool bMinAllowed = bool(nSWMode & (SwBorderModes::FRAME|SwBorderModes::TABLE));
        bool bSpaceModified =   m_pLeftMF->IsModified()||
                                m_pRightMF->IsModified()||
                                m_pTopMF->IsModified()||
                                m_pBottomMF->IsModified();
        bool bSpaceModified =   m_xLeftMF->get_value_changed_from_saved() ||
                                m_xRightMF->get_value_changed_from_saved() ||
                                m_xTopMF->get_value_changed_from_saved() ||
                                m_xBottomMF->get_value_changed_from_saved();

        if(bLineSet)
        {
            if(!bMinAllowed)
            {
                m_pLeftMF->SetFirst(nMinValue);
                m_pRightMF->SetFirst(nMinValue);
                m_pTopMF->SetFirst(nMinValue);
                m_pBottomMF->SetFirst(nMinValue);
                m_xLeftMF->set_min(nMinValue, FUNIT_NONE);
                m_xRightMF->set_min(nMinValue, FUNIT_NONE);
                m_xTopMF->set_min(nMinValue, FUNIT_NONE);
                m_xBottomMF->set_min(nMinValue, FUNIT_NONE);
            }
            if(!bSpaceModified)
            {
                m_pLeftMF->SetValue(nMinValue);
                m_pRightMF->SetValue(nMinValue);
                m_pTopMF->SetValue(nMinValue);
                m_pBottomMF->SetValue(nMinValue);
                m_xLeftMF->set_value(nMinValue, FUNIT_NONE);
                m_xRightMF->set_value(nMinValue, FUNIT_NONE);
                m_xTopMF->set_value(nMinValue, FUNIT_NONE);
                m_xBottomMF->set_value(nMinValue, FUNIT_NONE);
            }
        }
        else
        {
            m_pLeftMF->SetMin(0);
            m_pRightMF->SetMin(0);
            m_pTopMF->SetMin(0);
            m_pBottomMF->SetMin(0);
            m_pLeftMF->SetFirst(0);
            m_pRightMF->SetFirst(0);
            m_pTopMF->SetFirst(0);
            m_pBottomMF->SetFirst(0);
            m_xLeftMF->set_min(0, FUNIT_NONE);
            m_xRightMF->set_min(0, FUNIT_NONE);
            m_xTopMF->set_min(0, FUNIT_NONE);
            m_xBottomMF->set_min(0, FUNIT_NONE);
            if(!bSpaceModified && !mbAllowPaddingWithoutBorders)
            {
                m_pLeftMF->SetValue(0);
                m_pRightMF->SetValue(0);
                m_pTopMF->SetValue(0);
                m_pBottomMF->SetValue(0);
                m_xLeftMF->set_value(0, FUNIT_NONE);
                m_xRightMF->set_value(0, FUNIT_NONE);
                m_xTopMF->set_value(0, FUNIT_NONE);
                m_xBottomMF->set_value(0, FUNIT_NONE);
            }
        }
        // for tables everything is allowed
@@ -1229,53 +1356,53 @@ IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl, LinkParamNone*, void)
        {
            if(bLineSet)
            {
                nValid  = (m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Top)    == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::TOP : SvxBoxInfoItemValidFlags::NONE;
                nValid |= (m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Bottom) == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::BOTTOM : SvxBoxInfoItemValidFlags::NONE;
                nValid |= (m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Left)   == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::LEFT : SvxBoxInfoItemValidFlags::NONE;
                nValid |= (m_pFrameSel->GetFrameBorderState( svx::FrameBorderType::Right ) == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::RIGHT : SvxBoxInfoItemValidFlags::NONE;
                nValid  = (m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top)    == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::TOP : SvxBoxInfoItemValidFlags::NONE;
                nValid |= (m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom) == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::BOTTOM : SvxBoxInfoItemValidFlags::NONE;
                nValid |= (m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left)   == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::LEFT : SvxBoxInfoItemValidFlags::NONE;
                nValid |= (m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right ) == svx::FrameBorderState::Show) ? SvxBoxInfoItemValidFlags::RIGHT : SvxBoxInfoItemValidFlags::NONE;
            }
            else
                nValid = SvxBoxInfoItemValidFlags::NONE;
        }
        m_pLeftFT->Enable( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
        m_pRightFT->Enable( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
        m_pTopFT->Enable( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
        m_pBottomFT->Enable( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
        m_pLeftMF->Enable( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
        m_pRightMF->Enable( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
        m_pTopMF->Enable( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
        m_pBottomMF->Enable( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
        m_pSynchronizeCB->Enable( m_pRightMF->IsEnabled() || m_pTopMF->IsEnabled() ||
                               m_pBottomMF->IsEnabled() || m_pLeftMF->IsEnabled() );
        m_xLeftFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
        m_xRightFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
        m_xTopFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
        m_xBottomFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
        m_xLeftMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
        m_xRightMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
        m_xTopMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
        m_xBottomMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
        m_xSynchronizeCB->set_sensitive(m_xRightMF->get_sensitive() || m_xTopMF->get_sensitive() ||
                                        m_xBottomMF->get_sensitive() || m_xLeftMF->get_sensitive());
    }
    UpdateRemoveAdjCellBorderCB( SAL_MAX_UINT16 );
}


IMPL_LINK( SvxBorderTabPage, ModifyDistanceHdl_Impl, Edit&, rField, void)
IMPL_LINK( SvxBorderTabPage, ModifyDistanceHdl_Impl, weld::MetricSpinButton&, rField, void)
{
    if ( mbSync )
    if (mbSync)
    {
        sal_Int64 nVal = static_cast<MetricField&>(rField).GetValue();
        if(&rField != m_pLeftMF)
            m_pLeftMF->SetValue(nVal);
        if(&rField != m_pRightMF)
            m_pRightMF->SetValue(nVal);
        if(&rField != m_pTopMF)
            m_pTopMF->SetValue(nVal);
        if(&rField != m_pBottomMF)
            m_pBottomMF->SetValue(nVal);
        const auto nVal = rField.get_value(FUNIT_NONE);
        if (&rField != m_xLeftMF.get())
            m_xLeftMF->set_value(nVal, FUNIT_NONE);
        if (&rField != m_xRightMF.get())
            m_xRightMF->set_value(nVal, FUNIT_NONE);
        if (&rField != m_xTopMF.get())
            m_xTopMF->set_value(nVal, FUNIT_NONE);
        if (&rField != m_xBottomMF.get())
            m_xBottomMF->set_value(nVal, FUNIT_NONE);
    }
}

IMPL_LINK( SvxBorderTabPage, SyncHdl_Impl, Button*, pBox, void)
IMPL_LINK( SvxBorderTabPage, SyncHdl_Impl, weld::ToggleButton&, rBox, void)
{
    mbSync = static_cast<CheckBox*>(pBox)->IsChecked();
    mbSync = rBox.get_active();
}

IMPL_LINK( SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl, Button*, pBox, void)
IMPL_LINK( SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl, weld::ToggleButton&, rBox, void)
{
    mbRemoveAdjacentCellBorders = static_cast<CheckBox*>(pBox)->IsChecked();
    mbRemoveAdjacentCellBorders = rBox.get_active();
}

void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset )
@@ -1306,7 +1433,7 @@ void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset )
    {
        if( pOldBoxItem->GetLine( eTypes2[i] ) || !( pOldBoxInfoItem->IsValid( eTypes1[i].second ) ) )
        {
            if( m_pFrameSel->GetFrameBorderState( eTypes1[i].first ) == svx::FrameBorderState::Hide )
            if( m_aFrameSel.GetFrameBorderState( eTypes1[i].first ) == svx::FrameBorderState::Hide )
            {
                bBorderDeletionReq = true;
                break;
@@ -1317,12 +1444,12 @@ void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset )
    if( !bBorderDeletionReq && ( nPreset == IID_PRE_CELL_NONE || nPreset == IID_PRE_TABLE_NONE ) )
        bBorderDeletionReq = true;

    m_pRemoveAdjcentCellBordersCB->Enable( bBorderDeletionReq );
    m_xRemoveAdjcentCellBordersCB->set_sensitive(bBorderDeletionReq);

    if( !bBorderDeletionReq )
    {
        mbRemoveAdjacentCellBorders = false;
        m_pRemoveAdjcentCellBordersCB->Check( false );
        m_xRemoveAdjcentCellBordersCB->set_active(false);
    }
}

@@ -1342,17 +1469,17 @@ void SvxBorderTabPage::PageCreated(const SfxAllItemSet& aSet)
    {
        nSWMode = static_cast<SwBorderModes>(pSWModeItem->GetValue());
        // #i43593#
        // show checkbox <m_pMergeWithNextCB> for format.paragraph
        // show checkbox <m_xMergeWithNextCB> for format.paragraph
        if ( nSWMode == SwBorderModes::PARA )
        {
            m_pMergeWithNextCB->Show();
            m_pPropertiesFrame->Show();
            m_xMergeWithNextCB->show();
            m_xPropertiesFrame->show();
        }
        // show checkbox <m_pMergeAdjacentBordersCB> for format.paragraph
        // show checkbox <m_xMergeAdjacentBordersCB> for format.paragraph
        else if ( nSWMode == SwBorderModes::TABLE )
        {
            m_pMergeAdjacentBordersCB->Show();
            m_pPropertiesFrame->Show();
            m_xMergeAdjacentBordersCB->show();
            m_xPropertiesFrame->show();
        }
    }
    if (pFlagItem)
diff --git a/cui/source/tabpages/borderconn.cxx b/cui/source/tabpages/borderconn.cxx
deleted file mode 100644
index 78d2c3b..0000000
--- a/cui/source/tabpages/borderconn.cxx
+++ /dev/null
@@ -1,291 +0,0 @@
/* -*- 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 "borderconn.hxx"
#include <svx/frmsel.hxx>
#include <svx/svxids.hrc>
#include <editeng/lineitem.hxx>
#include <editeng/boxitem.hxx>
#include <svx/algitem.hxx>
#include <svx/colorbox.hxx>
#include <editeng/shaditem.hxx>

namespace svx {

/* ============================================================================
SvxLineItem connection
----------------------
Connects an SvxLineItem (that contains the style of one line of a cell border)
with one frame border from a svx::FrameSelector control. If this connection is
used, no additional code is needed in the Reset() and FillItemSet() functions
of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

class LineItemWrapper : public sfx::SingleItemWrapper< SvxLineItem, const editeng::SvxBorderLine* >
{
public:
    explicit     LineItemWrapper( sal_uInt16 nSlot ) : SingleItemWrapperType( nSlot ) {}

    virtual const editeng::SvxBorderLine* GetItemValue( const SvxLineItem& rItem ) const override
                            { return rItem.GetLine(); }
    virtual void        SetItemValue( SvxLineItem& rItem, const editeng::SvxBorderLine* pLine ) const override
                            { rItem.SetLine( pLine ); }
};

// 2nd: control wrappers ------------------------------------------------------

class FrameSelectorWrapper : public sfx::SingleControlWrapper< FrameSelector, const editeng::SvxBorderLine* >
{
public:
    explicit     FrameSelectorWrapper( FrameSelector& rFrameSel, FrameBorderType eBorder ) :
                            SingleControlWrapperType( rFrameSel ), meBorder( eBorder ) {}

    virtual bool        IsControlDontKnow() const override;
    virtual void        SetControlDontKnow( bool bSet ) override;

    virtual const editeng::SvxBorderLine* GetControlValue() const override;
    virtual void        SetControlValue( const editeng::SvxBorderLine* pLine ) override;

private:
    FrameBorderType       meBorder;         /// The line this wrapper works with.
};

bool FrameSelectorWrapper::IsControlDontKnow() const
{
    return GetControl().GetFrameBorderState( meBorder ) == FrameBorderState::DontCare;
}

void FrameSelectorWrapper::SetControlDontKnow( bool bSet )
{
    if( bSet )
        GetControl().SetBorderDontCare( meBorder );
}

const editeng::SvxBorderLine* FrameSelectorWrapper::GetControlValue() const
{
    return GetControl().GetFrameBorderStyle( meBorder );
}

void FrameSelectorWrapper::SetControlValue( const editeng::SvxBorderLine* pLine )
{
    GetControl().ShowBorder( meBorder, pLine );
}

// 3rd: connection ------------------------------------------------------------

/* ============================================================================
SvxMarginItem connection
------------------------
Connects an SvxMarginItem (that contains the inner margin of all cell borders)
with the numerical edit controls of the SvxBorderTabPage. If this connection is
used, no additional code is needed in the Reset() and FillItemSet() functions
of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

typedef sfx::IdentItemWrapper< SvxMarginItem > MarginItemWrapper;

// 2nd: control wrappers ------------------------------------------------------

class MarginControlsWrapper : public sfx::MultiControlWrapper< SvxMarginItem >
{
public:
    explicit            MarginControlsWrapper(
                            MetricField& rMfLeft, MetricField& rMfRight,
                            MetricField& rMfTop, MetricField& rMfBottom );

    virtual SvxMarginItem GetControlValue() const override;
    virtual void        SetControlValue( SvxMarginItem aItem ) override;

private:
    sfx::MetricFieldWrapper<sal_Int16> maLeftWrp;
    sfx::MetricFieldWrapper<sal_Int16> maRightWrp;
    sfx::MetricFieldWrapper<sal_Int16> maTopWrp;
    sfx::MetricFieldWrapper<sal_Int16> maBottomWrp;
};

MarginControlsWrapper::MarginControlsWrapper(
        MetricField& rMfLeft, MetricField& rMfRight, MetricField& rMfTop, MetricField& rMfBottom ) :
    maLeftWrp( rMfLeft, FUNIT_TWIP ),
    maRightWrp( rMfRight, FUNIT_TWIP ),
    maTopWrp( rMfTop, FUNIT_TWIP ),
    maBottomWrp( rMfBottom, FUNIT_TWIP )
{
    RegisterControlWrapper( maLeftWrp );
    RegisterControlWrapper( maRightWrp );
    RegisterControlWrapper( maTopWrp );
    RegisterControlWrapper( maBottomWrp );
}

SvxMarginItem MarginControlsWrapper::GetControlValue() const
{
    SvxMarginItem aItem( GetDefaultValue() );
    if( !maLeftWrp.IsControlDontKnow() )
        aItem.SetLeftMargin( maLeftWrp.GetControlValue() );
    if( !maRightWrp.IsControlDontKnow() )
        aItem.SetRightMargin( maRightWrp.GetControlValue() );
    if( !maTopWrp.IsControlDontKnow() )
        aItem.SetTopMargin( maTopWrp.GetControlValue() );
    if( !maBottomWrp.IsControlDontKnow() )
        aItem.SetBottomMargin( maBottomWrp.GetControlValue() );
    return aItem;
}

void MarginControlsWrapper::SetControlValue( SvxMarginItem aItem )
{
    maLeftWrp.SetControlValue( aItem.GetLeftMargin() );
    maRightWrp.SetControlValue( aItem.GetRightMargin() );
    maTopWrp.SetControlValue( aItem.GetTopMargin() );
    maBottomWrp.SetControlValue( aItem.GetBottomMargin() );
}

// 3rd: connection ------------------------------------------------------------

class MarginConnection : public sfx::ItemControlConnection< MarginItemWrapper, MarginControlsWrapper >
{
public:
    explicit            MarginConnection( const SfxItemSet& rItemSet,
                            MetricField& rMfLeft, MetricField& rMfRight,
                            MetricField& rMfTop, MetricField& rMfBottom );
};

MarginConnection::MarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight, MetricField& rMfTop, MetricField& rMfBottom ) :
    ItemControlConnectionType( SID_ATTR_ALIGN_MARGIN, new MarginControlsWrapper( rMfLeft, rMfRight, rMfTop, rMfBottom ), ItemConnFlags::NONE )
{
    mxCtrlWrp->SetDefaultValue( maItemWrp.GetDefaultItem( rItemSet ) );
}

/* ============================================================================
SvxShadowItem connection
------------------------
Connects an SvxShadowItem (that contains shadow position, size, and color) with
the controls of the SvxBorderTabPage. If this connection is used, no additional
code is needed in the Reset() and FillItemSet() functions of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

typedef sfx::IdentItemWrapper< SvxShadowItem > ShadowItemWrapper;

// 2nd: control wrappers ------------------------------------------------------

typedef sfx::ValueSetWrapper< SvxShadowLocation > ShadowPosWrapper;
static const ShadowPosWrapper::MapEntryType s_pShadowPosMap[] =
{
    { 1,                        SvxShadowLocation::NONE         },
    { 2,                        SvxShadowLocation::BottomRight  },
    { 3,                        SvxShadowLocation::TopRight     },
    { 4,                        SvxShadowLocation::BottomLeft   },
    { 5,                        SvxShadowLocation::TopLeft      },
    { WRAPPER_VALUESET_ITEM_NOTFOUND, SvxShadowLocation::NONE   }
};

class ShadowControlsWrapper : public sfx::MultiControlWrapper< SvxShadowItem >
{
public:
    explicit            ShadowControlsWrapper( ValueSet& rVsPos, MetricField& rMfSize, SvxColorListBox& rLbColor );

    virtual SvxShadowItem GetControlValue() const override;
    virtual void        SetControlValue( SvxShadowItem aItem ) override;

private:
    ShadowPosWrapper                    maPosWrp;
    sfx::MetricFieldWrapper<sal_uInt16> maSizeWrp;
    SvxColorListBoxWrapper              maColorWrp;
};

ShadowControlsWrapper::ShadowControlsWrapper(
        ValueSet& rVsPos, MetricField& rMfSize, SvxColorListBox& rLbColor ) :
    maPosWrp( rVsPos, s_pShadowPosMap ),
    maSizeWrp( rMfSize, FUNIT_TWIP ),
    maColorWrp( rLbColor )
{
    RegisterControlWrapper( maPosWrp );
    RegisterControlWrapper( maSizeWrp );
    RegisterControlWrapper( maColorWrp );
}

SvxShadowItem ShadowControlsWrapper::GetControlValue() const
{
    SvxShadowItem aItem( GetDefaultValue() );
    if( !maPosWrp.IsControlDontKnow() )
        aItem.SetLocation( maPosWrp.GetControlValue() );
    // Default value was saved; so don't change the aItem's width if the control
    // has not changed its value, to avoid round-trip errors (like twip->cm->twip)
    // E.g., initial 100 twip will become 0.18 cm, which will return as 102 twip
    if( !maSizeWrp.IsControlDontKnow() && maSizeWrp.IsControlValueChanged() )
        aItem.SetWidth( maSizeWrp.GetControlValue() );
    if( !maColorWrp.IsControlDontKnow() )
        aItem.SetColor( maColorWrp.GetControlValue() );
    return aItem;
}

void ShadowControlsWrapper::SetControlValue( SvxShadowItem aItem )
{
    SetDefaultValue(aItem);
    maPosWrp.SetControlValue( aItem.GetLocation() );
    maSizeWrp.SetControlValue( aItem.GetWidth() );
    maSizeWrp.GetControl().SaveValue();
    maColorWrp.SetControlValue( aItem.GetColor() );
}

// 3rd: connection ------------------------------------------------------------

class ShadowConnection : public sfx::ItemControlConnection< ShadowItemWrapper, ShadowControlsWrapper >
{
public:
    explicit ShadowConnection( sal_uInt16 nSlot, const SfxItemSet& rItemSet,
                                ValueSet& rVsPos, MetricField& rMfSize, SvxColorListBox& rLbColor );
};

ShadowConnection::ShadowConnection( sal_uInt16 nSlot, const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, SvxColorListBox& rLbColor ) :
    ItemControlConnectionType( nSlot, new ShadowControlsWrapper( rVsPos, rMfSize, rLbColor ), ItemConnFlags::NONE )
{
    mxCtrlWrp->SetDefaultValue( maItemWrp.GetDefaultItem( rItemSet ) );
}


sfx::ItemConnectionBase* CreateFrameLineConnection( sal_uInt16 nSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder )
{
    return new sfx::ItemControlConnection< LineItemWrapper, FrameSelectorWrapper >( nSlot, new FrameSelectorWrapper( rFrameSel, eBorder ), ItemConnFlags::NONE );
}

sfx::ItemConnectionBase* CreateMarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight,
        MetricField& rMfTop, MetricField& rMfBottom )
{
    return new MarginConnection( rItemSet, rMfLeft, rMfRight, rMfTop, rMfBottom );
}

sfx::ItemConnectionBase* CreateShadowConnection( sal_uInt16 nSlot, const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, SvxColorListBox& rLbColor )
{
    return new ShadowConnection( nSlot, rItemSet, rVsPos, rMfSize, rLbColor );
}


}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/borderconn.hxx b/cui/source/tabpages/borderconn.hxx
deleted file mode 100644
index 01b4046..0000000
--- a/cui/source/tabpages/borderconn.hxx
+++ /dev/null
@@ -1,57 +0,0 @@
/* -*- 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 .
 */

#ifndef INCLUDED_CUI_SOURCE_TABPAGES_BORDERCONN_HXX
#define INCLUDED_CUI_SOURCE_TABPAGES_BORDERCONN_HXX

#include <sfx2/itemconnect.hxx>
#include <svx/framebordertype.hxx>

class SfxItemSet;
class MetricField;
class ValueSet;
class SvxColorListBox;

namespace svx {

class FrameSelector;


/** Creates an item connection object that connects an SvxLineItem with an
    svx::FrameSelector control. */
sfx::ItemConnectionBase* CreateFrameLineConnection( sal_uInt16 nSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder );

/** Creates an item connection object that connects an SvxMarginItem with the
    controls of the SvxBorderTabPage. */
sfx::ItemConnectionBase* CreateMarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight,
        MetricField& rMfTop, MetricField& rMfBottom );

/** Creates an item connection object that connects an SvxShadowItem with the
    controls of the SvxBorderTabPage. */
sfx::ItemConnectionBase* CreateShadowConnection( sal_uInt16 nSlot, const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, SvxColorListBox& rLbColor );


}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx
index edd5f59..7e8682d 100644
--- a/cui/source/tabpages/tpbitmap.cxx
+++ b/cui/source/tabpages/tpbitmap.cxx
@@ -113,7 +113,6 @@ SvxBitmapTabPage::SvxBitmapTabPage(TabPageParent pParent, const SfxItemSet& rInA
    Link<weld::MetricSpinButton&, void> aLink( LINK( this, SvxBitmapTabPage, ModifyPositionOffsetHdl ) );
    m_xPositionOffX->connect_value_changed(aLink);
    m_xPositionOffY->connect_value_changed(aLink);
    m_xTileOffset->set_value(0, FUNIT_PERCENT);
    m_xTileOffset->connect_value_changed( LINK( this, SvxBitmapTabPage, ModifyTileOffsetHdl ) );
    m_xBtnImport->connect_clicked( LINK(this, SvxBitmapTabPage, ClickImportHdl) );

diff --git a/cui/uiconfig/ui/borderpage.ui b/cui/uiconfig/ui/borderpage.ui
index 1e66125..020318c 100644
--- a/cui/uiconfig/ui/borderpage.ui
+++ b/cui/uiconfig/ui/borderpage.ui
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="lower">0.050000000000000003</property>
    <property name="upper">9</property>
@@ -20,6 +19,21 @@
    <property name="step_increment">0.10000000000000001</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkAdjustment" id="adjustment4">
    <property name="upper">50</property>
    <property name="step_increment">0.10000000000000001</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkAdjustment" id="adjustment5">
    <property name="upper">50</property>
    <property name="step_increment">0.10000000000000001</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkAdjustment" id="adjustment6">
    <property name="upper">50</property>
    <property name="step_increment">0.10000000000000001</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkGrid" id="BorderPage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -54,9 +68,24 @@
                    <property name="hexpand">True</property>
                    <property name="row_spacing">6</property>
                    <child>
                      <object class="svxlo-SvxFrameSelector" id="framesel">
                      <object class="GtkScrolledWindow" id="frameselwin">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="hscrollbar_policy">never</property>
                        <property name="vscrollbar_policy">never</property>
                        <property name="shadow_type">in</property>
                        <child>
                          <object class="GtkViewport">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <child>
                              <object class="GtkDrawingArea" id="framesel">
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                              </object>
                            </child>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -67,10 +96,10 @@
                      <object class="GtkLabel" id="userdefft">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|userdefft">_User-defined:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">framesel</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -81,10 +110,10 @@
                      <object class="GtkLabel" id="label14">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|label14">Pr_esets:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">presets</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -92,10 +121,25 @@
                      </packing>
                    </child>
                    <child>
                      <object class="svtlo-ValueSet" id="presets">
                      <object class="GtkScrolledWindow" id="presetswin">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="halign">start</property>
                        <property name="hscrollbar_policy">never</property>
                        <property name="vscrollbar_policy">never</property>
                        <property name="shadow_type">in</property>
                        <child>
                          <object class="GtkViewport">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <child>
                              <object class="GtkDrawingArea" id="presets">
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                              </object>
                            </child>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -106,10 +150,10 @@
                      <object class="GtkLabel" id="rmadjcellbordersft">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|rmadjcellbordersft">_Adjacent Cells:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">rmadjcellborders</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -172,10 +216,10 @@
                      <object class="GtkLabel" id="label15">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|label15">St_yle:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">linestylelb</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -186,10 +230,10 @@
                      <object class="GtkLabel" id="label16">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|label16">_Width:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">linewidthmf:0.00pt</property>
                        <property name="mnemonic_widget">linewidthmf</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -200,10 +244,10 @@
                      <object class="GtkLabel" id="label17">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|label17">_Color:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">linecolorlb</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -211,9 +255,14 @@
                      </packing>
                    </child>
                    <child>
                      <object class="svtlo-LineListBox" id="linestylelb">
                      <object class="GtkMenuButton" id="linestylelb">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="receives_default">False</property>
                        <property name="xalign">0</property>
                        <child>
                          <placeholder/>
                        </child>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -221,9 +270,10 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkSpinButton" id="linewidthmf:0.00pt">
                      <object class="GtkSpinButton" id="linewidthmf">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="activates_default">True</property>
                        <property name="adjustment">adjustment1</property>
                        <property name="digits">2</property>
                      </object>
@@ -233,9 +283,14 @@
                      </packing>
                    </child>
                    <child>
                      <object class="svxcorelo-SvxColorListBox" id="linecolorlb">
                      <object class="GtkMenuButton" id="linecolorlb">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="receives_default">False</property>
                        <property name="xalign">0</property>
                        <child>
                          <placeholder/>
                        </child>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -281,9 +336,10 @@
                    <property name="row_spacing">6</property>
                    <property name="column_spacing">12</property>
                    <child>
                      <object class="GtkSpinButton" id="leftmf:0.00mm">
                      <object class="GtkSpinButton" id="leftmf">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="activates_default">True</property>
                        <property name="adjustment">adjustment2</property>
                        <property name="digits">2</property>
                      </object>
@@ -293,10 +349,11 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkSpinButton" id="topmf:0.00mm">
                      <object class="GtkSpinButton" id="topmf">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="adjustment">adjustment2</property>
                        <property name="activates_default">True</property>
                        <property name="adjustment">adjustment5</property>
                        <property name="digits">2</property>
                      </object>
                      <packing>
@@ -305,10 +362,11 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkSpinButton" id="rightmf:0.00mm">
                      <object class="GtkSpinButton" id="rightmf">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="adjustment">adjustment2</property>
                        <property name="activates_default">True</property>
                        <property name="adjustment">adjustment4</property>
                        <property name="digits">2</property>
                      </object>
                      <packing>
@@ -317,10 +375,11 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkSpinButton" id="bottommf:0.00mm">
                      <object class="GtkSpinButton" id="bottommf">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="adjustment">adjustment2</property>
                        <property name="activates_default">True</property>
                        <property name="adjustment">adjustment6</property>
                        <property name="digits">2</property>
                      </object>
                      <packing>
@@ -332,10 +391,10 @@
                      <object class="GtkLabel" id="leftft">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|leftft">_Left:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">leftmf:0.00mm</property>
                        <property name="mnemonic_widget">leftmf</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -346,10 +405,10 @@
                      <object class="GtkLabel" id="rightft">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|rightft">Right:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">rightmf:0.00mm</property>
                        <property name="mnemonic_widget">rightmf</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -360,10 +419,10 @@
                      <object class="GtkLabel" id="topft">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|topft">_Top:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">topmf:0.00mm</property>
                        <property name="mnemonic_widget">topmf</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -374,10 +433,10 @@
                      <object class="GtkLabel" id="bottomft">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="xalign">0</property>
                        <property name="label" translatable="yes" context="borderpage|bottomft">_Bottom:</property>
                        <property name="use_underline">True</property>
                        <property name="mnemonic_widget">bottommf:0.00mm</property>
                        <property name="mnemonic_widget">bottommf</property>
                        <property name="xalign">0</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
@@ -450,10 +509,10 @@
                  <object class="GtkLabel" id="label22">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="xalign">0</property>
                    <property name="label" translatable="yes" context="borderpage|label22">_Position:</property>
                    <property name="use_underline">True</property>
                    <property name="mnemonic_widget">shadows</property>
                    <property name="xalign">0</property>
                  </object>
                  <packing>
                    <property name="left_attach">0</property>
@@ -464,10 +523,10 @@
                  <object class="GtkLabel" id="distanceft">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="xalign">0</property>
                    <property name="label" translatable="yes" context="borderpage|distanceft">Distan_ce:</property>
                    <property name="use_underline">True</property>
                    <property name="mnemonic_widget">distancemf:0.00mm</property>
                    <property name="mnemonic_widget">distancemf</property>
                    <property name="xalign">0</property>
                  </object>
                  <packing>
                    <property name="left_attach">1</property>
@@ -478,10 +537,10 @@
                  <object class="GtkLabel" id="shadowcolorft">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="xalign">0</property>
                    <property name="label" translatable="yes" context="borderpage|shadowcolorft">C_olor:</property>
                    <property name="use_underline">True</property>
                    <property name="mnemonic_widget">shadowcolorlb</property>
                    <property name="xalign">0</property>
                  </object>
                  <packing>
                    <property name="left_attach">2</property>
@@ -489,10 +548,11 @@
                  </packing>
                </child>
                <child>
                  <object class="GtkSpinButton" id="distancemf:0.00mm">
                  <object class="GtkSpinButton" id="distancemf">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="halign">start</property>
                    <property name="activates_default">True</property>
                    <property name="adjustment">adjustment3</property>
                  </object>
                  <packing>
@@ -501,10 +561,14 @@
                  </packing>
                </child>
                <child>
                  <object class="svxcorelo-SvxColorListBox" id="shadowcolorlb">
                  <object class="GtkMenuButton" id="shadowcolorlb">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="halign">start</property>
                    <property name="receives_default">False</property>
                    <property name="xalign">0</property>
                    <child>
                      <placeholder/>
                    </child>
                  </object>
                  <packing>
                    <property name="left_attach">2</property>
@@ -512,10 +576,25 @@
                  </packing>
                </child>
                <child>
                  <object class="svtlo-ValueSet" id="shadows">
                  <object class="GtkScrolledWindow" id="shadowswin">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="halign">start</property>
                    <property name="hscrollbar_policy">never</property>
                    <property name="vscrollbar_policy">never</property>
                    <property name="shadow_type">in</property>
                    <child>
                      <object class="GtkViewport">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <child>
                          <object class="GtkDrawingArea" id="shadows">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                  <packing>
                    <property name="left_attach">0</property>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index 3e9db8c..fb2bbd3 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -290,9 +290,6 @@
    <glade-widget-class title="Svx 3D Preview Control" name="svxlo-Svx3DPreviewControl"
                        generic-name="3D Preview Control" parent="GtkDrawingArea"
                        icon-name="widget-gtk-drawingarea"/>
    <glade-widget-class title="Frame Selector" name="svxlo-SvxFrameSelector"
                        generic-name="Frame Border Preview Window" parent="GtkDrawingArea"
                        icon-name="widget-gtk-drawingarea"/>
    <glade-widget-class title="MultiLine Edit" name="svtlo-MultiLineEditSyntaxHighlight"
                        generic-name="MultiLineEdit" parent="GtkTextView"
                        icon-name="widget-gtk-textview"/>
diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index 97db99c..8df5dfd 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -22,12 +22,14 @@

#include <svtools/svtdllapi.h>

#include <vcl/customweld.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/combobox.hxx>
#include <vcl/image.hxx>
#include <vcl/virdev.hxx>
#include <vcl/metric.hxx>
#include <vcl/field.hxx>
#include <vcl/weld.hxx>

#include <com/sun/star/table/BorderLineStyle.hpp>
#include <o3tl/typed_flags_set.hxx>
@@ -280,6 +282,91 @@ inline void LineListBox::SetNone( const OUString& sNone )
    m_sNone = sNone;
}

class SvtValueSet;

class SVT_DLLPUBLIC SvtLineListBox
{
public:
    typedef Color (*ColorFunc)(Color);
    typedef Color (*ColorDistFunc)(Color, Color);

    SvtLineListBox(std::unique_ptr<weld::MenuButton> pControl);
    ~SvtLineListBox();

    /** Set the width in Twips */
    void SetWidth( long nWidth )
    {
        m_nWidth = nWidth;
        UpdateEntries();
        UpdatePreview();
    }

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

    void            SelectEntry( SvxBorderLineStyle nStyle );
    SvxBorderLineStyle GetSelectEntryStyle() const;

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

    void            SetColor( const Color& rColor )
    {
        aColor = rColor;
        UpdateEntries();
    }

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

    void            SetSelectHdl(const Link<SvtLineListBox&,void>& rLink) { maSelectHdl = rLink; }

private:

    SVT_DLLPRIVATE void         ImpGetLine( long nLine1, long nLine2, long nDistance,
                                    Color nColor1, Color nColor2, Color nColorDist,
                                    SvxBorderLineStyle nStyle, BitmapEx& rBmp );

    void            UpdatePaintLineColor();       // returns sal_True if maPaintCol has changed
    DECL_LINK(StyleUpdated, weld::Widget&, void);
    DECL_LINK(ValueSelectHdl, SvtValueSet*, void);
    DECL_LINK(FocusHdl, weld::Widget&, void);
    DECL_LINK(NoneHdl, weld::Button&, void);

    void            UpdateEntries();
    sal_Int32       GetStylePos(sal_Int32 nListPos);

    const Color&    GetPaintColor() const
    {
        return maPaintCol;
    }
    Color   GetColorLine1( sal_Int32  nPos );
    Color   GetColorLine2( sal_Int32  nPos );
    Color   GetColorDist( sal_Int32  nPos );

    void UpdatePreview();

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

    std::unique_ptr<weld::MenuButton> m_xControl;
    std::unique_ptr<weld::Builder> m_xBuilder;
    std::unique_ptr<weld::Widget> m_xTopLevel;
    std::unique_ptr<weld::Button> m_xNoneButton;
    std::unique_ptr<SvtValueSet> m_xLineSet;
    std::unique_ptr<weld::CustomWeld> m_xLineSetWin;

    std::vector<std::unique_ptr<ImpLineListData>> m_vLineList;
    long            m_nWidth;
    ScopedVclPtr<VirtualDevice>   aVirDev;
    Color           aColor;
    Color           maPaintCol;
    FieldUnit       eSourceUnit;
    Link<SvtLineListBox&,void> maSelectHdl;
};

class SVT_DLLPUBLIC FontNameBox : public ComboBox
{
private:
diff --git a/include/svtools/valueset.hxx b/include/svtools/valueset.hxx
index 9acfd77..fa4b399 100644
--- a/include/svtools/valueset.hxx
+++ b/include/svtools/valueset.hxx
@@ -427,6 +427,7 @@ private:
    long            mnUserItemWidth;
    long            mnUserItemHeight;
    sal_uInt16      mnSelItemId;
    sal_uInt16      mnHighItemId;
    sal_uInt16      mnCols;
    sal_uInt16      mnCurCol;
    sal_uInt16      mnUserCols;
@@ -441,7 +442,9 @@ private:
    Link<SvtValueSet*,void>  maSelectHdl;

    bool            mbFormat : 1;
    bool            mbHighlight : 1;
    bool            mbNoSelection : 1;
    bool            mbDrawSelection : 1;
    bool            mbBlackSel : 1;
    bool            mbDoubleSel : 1;
    bool            mbScroll : 1;
@@ -457,6 +460,7 @@ private:
    SVT_DLLPRIVATE void         ImplDrawItemText(vcl::RenderContext& rRenderContext, const OUString& rStr);
    SVT_DLLPRIVATE void         ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel);
    SVT_DLLPRIVATE void         ImplDrawSelect(vcl::RenderContext& rRenderContext);
    SVT_DLLPRIVATE void         ImplHighlightItem(sal_uInt16 nItemId, bool bIsSelection = true);
    SVT_DLLPRIVATE void         ImplDraw(vcl::RenderContext& rRenderContext);
    SVT_DLLPRIVATE size_t       ImplGetItem( const Point& rPoint ) const;
    SVT_DLLPRIVATE SvtValueSetItem*    ImplGetItem( size_t nPos );
@@ -466,8 +470,11 @@ private:
    SVT_DLLPRIVATE tools::Rectangle    ImplGetItemRect( size_t nPos ) const;
    SVT_DLLPRIVATE void         ImplFireAccessibleEvent( short nEventId, const css::uno::Any& rOldValue, const css::uno::Any& rNewValue );
    SVT_DLLPRIVATE bool         ImplHasAccessibleListeners();
    SVT_DLLPRIVATE void         ImplTracking(const Point& rPos);
    DECL_DLLPRIVATE_LINK(ImplScrollHdl, weld::ScrolledWindow&, void);

    Size           GetLargestItemSize();

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

@@ -481,6 +488,7 @@ public:
    virtual void    SetDrawingArea(weld::DrawingArea* pDrawingArea) override;

    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
    virtual void    MouseMove( const MouseEvent& rMEvt ) override;
    virtual bool    KeyInput( const KeyEvent& rKEvt ) override;
    virtual void    Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
    virtual void    GetFocus() override;
@@ -495,12 +503,16 @@ public:
    void            SetStyle(WinBits nStyle);
    WinBits         GetStyle() const { return mnStyle; }

    void SetOptimalSize();

    /// Insert @rImage item with @rStr as either a legend or tooltip depending on @bShowLegend.
    void            InsertItem(sal_uInt16 nItemId, const Image& rImage,
                               const OUString& rStr, size_t nPos = VALUESET_APPEND, bool bShowLegend = false);
    /// Insert an @rColor item with @rStr tooltip.
    void            InsertItem(sal_uInt16 nItemId, const Color& rColor,
                               const OUString& rStr);
    /// Insert an User Drawn item.
    void            InsertItem(sal_uInt16 nItemId, size_t nPos = VALUESET_APPEND);
    void            RemoveItem(sal_uInt16 nItemId);

    void            Clear();
@@ -535,6 +547,8 @@ public:
        return mbNoSelection;
    }

    void            SetItemImage( sal_uInt16 nItemId, const Image& rImage );
    Image           GetItemImage( sal_uInt16 nItemId ) const;
    Color           GetItemColor( sal_uInt16 nItemId ) const;
    void            SetItemText( sal_uInt16 nItemId, const OUString& rStr );
    OUString        GetItemText( sal_uInt16 nItemId ) const;
diff --git a/include/svx/colorbox.hxx b/include/svx/colorbox.hxx
index 6ce1d61..9f3648e 100644
--- a/include/svx/colorbox.hxx
+++ b/include/svx/colorbox.hxx
@@ -124,6 +124,7 @@ public:
    void SelectEntry(const Color& rColor);

    void SetNoSelection() { getColorWindow()->SetNoSelection(); }
    bool IsNoSelection() const { return getColorWindow()->IsNoSelection(); }

    void ShowPreview(const NamedColor &rColor);
    void EnsurePaletteManager();
diff --git a/include/svx/colorwindow.hxx b/include/svx/colorwindow.hxx
index ade14fb..4249389 100644
--- a/include/svx/colorwindow.hxx
+++ b/include/svx/colorwindow.hxx
@@ -153,6 +153,7 @@ public:
    weld::Container* GetWidget() { return mxTopLevel.get(); }
    virtual ~ColorWindow() override;
    void                SetNoSelection();
    bool                IsNoSelection() const;
    void                SelectEntry(const NamedColor& rColor);
    void                SelectEntry(const Color& rColor);
    NamedColor          GetSelectEntryColor() const;
diff --git a/include/svx/frmsel.hxx b/include/svx/frmsel.hxx
index db2699e..db7fe57 100644
--- a/include/svx/frmsel.hxx
+++ b/include/svx/frmsel.hxx
@@ -22,6 +22,7 @@

#include <memory>
#include <vcl/ctrl.hxx>
#include <vcl/customweld.hxx>
#include <vcl/bitmap.hxx>
#include <editeng/borderline.hxx>
#include <svx/framebordertype.hxx>
@@ -79,10 +80,16 @@ enum class FrameBorderState
};


class SAL_WARN_UNUSED SVX_DLLPUBLIC FrameSelector : public Control
namespace a11y
{
    class AccFrameSelector;
}

class SAL_WARN_UNUSED SVX_DLLPUBLIC FrameSelector : public weld::CustomWidgetController
{
public:
    FrameSelector(vcl::Window* pParent);
    FrameSelector();
    virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
    virtual ~FrameSelector() override;

    /** Initializes the control, enables/disables frame borders according to flags. */
@@ -156,8 +163,9 @@ public:

    // accessibility

    virtual css::uno::Reference< css::accessibility::XAccessible >
                        CreateAccessible() override;
    css::uno::Reference<css::accessibility::XAccessible> getAccessibleParent() { return GetDrawingArea()->get_accessible_parent(); }
    virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
    a11yrelationset get_accessible_relation_set() { return GetDrawingArea()->get_accessible_relation_set(); }

    /** Returns the accessibility child object of the specified frame border (if enabled). */
    css::uno::Reference< css::accessibility::XAccessible >
@@ -174,22 +182,20 @@ public:
    /** Returns the bounding rectangle of the specified frame border (if enabled). */
    tools::Rectangle           GetClickBoundRect( FrameBorderType eBorder ) const;


protected:
    virtual void        Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
    virtual void        MouseButtonDown( const MouseEvent& rMEvt ) override;
    virtual void        KeyInput( const KeyEvent& rKEvt ) override;
    virtual bool        KeyInput( const KeyEvent& rKEvt ) override;
    virtual void        GetFocus() override;
    virtual void        LoseFocus() override;
    virtual void        DataChanged( const DataChangedEvent& rDCEvt ) override;
    virtual void        StyleUpdated() override;
    virtual void        Resize() override;
    virtual Size        GetOptimalSize() const override;

private:
    rtl::Reference<a11y::AccFrameSelector> mxAccess;   /// Pointer to accessibility object of the control.
    std::unique_ptr< FrameSelectorImpl > mxImpl;
};


}

#endif
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 57bedf5..693a905 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -291,10 +291,11 @@ enum class InvertFlags
    NONE                    = 0x0000,
    Highlight               = 0x0001,
    N50                     = 0x0002,
    TrackFrame              = 0x0004
};
namespace o3tl
{
    template<> struct typed_flags<InvertFlags> : is_typed_flags<InvertFlags, 0x0003> {};
    template<> struct typed_flags<InvertFlags> : is_typed_flags<InvertFlags, 0x0007> {};
}

enum OutDevType { OUTDEV_DONTKNOW, OUTDEV_WINDOW, OUTDEV_PRINTER, OUTDEV_VIRDEV };
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 6092312..89a4bed 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -366,7 +366,8 @@ protected:

public:
    virtual void set_label(const OUString& rText) = 0;
    virtual void set_image(VirtualDevice& rDevice) = 0;
    // pDevice, the image for the button, or nullptr to unset
    virtual void set_image(VirtualDevice* pDevice) = 0;
    virtual OUString get_label() const = 0;
    void clicked() { signal_clicked(); }

diff --git a/svtools/UIConfig_svt.mk b/svtools/UIConfig_svt.mk
index bceaebe..5887d16 100644
--- a/svtools/UIConfig_svt.mk
+++ b/svtools/UIConfig_svt.mk
@@ -15,6 +15,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svt,\
	svtools/uiconfig/ui/graphicexport \
	svtools/uiconfig/ui/inputbox \
	svtools/uiconfig/ui/javadisableddialog \
	svtools/uiconfig/ui/linewindow \
	svtools/uiconfig/ui/placeedit \
	svtools/uiconfig/ui/printersetupdialog \
	svtools/uiconfig/ui/querydeletedialog \
diff --git a/svtools/inc/borderline.hrc b/svtools/inc/borderline.hrc
new file mode 100644
index 0000000..07e4f1c
--- /dev/null
+++ b/svtools/inc/borderline.hrc
@@ -0,0 +1,41 @@
/* -*- 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/.
 */
#ifndef INCLUDED_CUI_INC_BORDERLINE_HRC
#define INCLUDED_CUI_INC_BORDERLINE_HRC

#include <editeng/borderline.hxx>

#define NC_(Context, String) (Context "\004" u8##String)

const std::pair<const char*, SvxBorderLineStyle> RID_SVXSTR_BORDERLINE[] =
{
    { NC_("RID_SVXSTR_BORDERLINE", "None"), SvxBorderLineStyle::NONE },
    { NC_("RID_SVXSTR_BORDERLINE", "Solid"), SvxBorderLineStyle::SOLID },
    { NC_("RID_SVXSTR_BORDERLINE", "Dotted"), SvxBorderLineStyle::DOTTED },
    { NC_("RID_SVXSTR_BORDERLINE", "Dashed"), SvxBorderLineStyle::DASHED },
    { NC_("RID_SVXSTR_BORDERLINE", "Double"), SvxBorderLineStyle::DOUBLE },
    { NC_("RID_SVXSTR_BORDERLINE", "Thin Thick, Small Gap"), SvxBorderLineStyle::THINTHICK_SMALLGAP },
    { NC_("RID_SVXSTR_BORDERLINE", "Thin Thick, Medium Gap"), SvxBorderLineStyle::THINTHICK_MEDIUMGAP },
    { NC_("RID_SVXSTR_BORDERLINE", "Thin Thick, Large Gap"), SvxBorderLineStyle::THINTHICK_LARGEGAP },
    { NC_("RID_SVXSTR_BORDERLINE", "Thick Thin, Small Gap"), SvxBorderLineStyle::THICKTHIN_SMALLGAP },
    { NC_("RID_SVXSTR_BORDERLINE", "Thick Thin, Medium Gap"), SvxBorderLineStyle::THICKTHIN_MEDIUMGAP },
    { NC_("RID_SVXSTR_BORDERLINE", "Thick Thin, Large Gap"), SvxBorderLineStyle::THICKTHIN_LARGEGAP },
    { NC_("RID_SVXSTR_BORDERLINE", "Embossed"), SvxBorderLineStyle::EMBOSSED },
    { NC_("RID_SVXSTR_BORDERLINE", "Engraved"), SvxBorderLineStyle::ENGRAVED },
    { NC_("RID_SVXSTR_BORDERLINE", "Outset"), SvxBorderLineStyle::OUTSET },
    { NC_("RID_SVXSTR_BORDERLINE", "Inset"), SvxBorderLineStyle::INSET },
    { NC_("RID_SVXSTR_BORDERLINE", "Fine Dashed"), SvxBorderLineStyle::FINE_DASHED },
    { NC_("RID_SVXSTR_BORDERLINE", "Double Thin"), SvxBorderLineStyle::DOUBLE_THIN },
    { NC_("RID_SVXSTR_BORDERLINE", "Dash Dot"), SvxBorderLineStyle::DASH_DOT },
    { NC_("RID_SVXSTR_BORDERLINE", "Dash Dot Dot"), SvxBorderLineStyle::DASH_DOT_DOT }
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index 3865975..3e3f2d9 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -22,6 +22,7 @@
#include <i18nutil/unicode.hxx>
#include <tools/stream.hxx>
#include <vcl/builderfactory.hxx>
#include <vcl/customweld.hxx>
#include <vcl/svapp.hxx>
#include <vcl/field.hxx>
#include <vcl/settings.hxx>
@@ -38,6 +39,7 @@
#include <svtools/ctrlbox.hxx>
#include <svtools/ctrltool.hxx>
#include <svtools/borderhelper.hxx>
#include <svtools/valueset.hxx>

#include <vcl/i18nhelp.hxx>
#include <vcl/fontcapabilities.hxx>
@@ -49,6 +51,8 @@

#include <rtl/bootstrap.hxx>

#include <borderline.hrc>

#include <stdio.h>

#define IMGOUTERTEXTSPACE 5
@@ -1575,4 +1579,298 @@ sal_Int64 FontSizeBox::GetValueFromStringUnit(const OUString& rStr, FieldUnit eO
    return MetricBox::GetValueFromStringUnit( rStr, eOutUnit );
}

SvxBorderLineStyle SvtLineListBox::GetSelectEntryStyle() const
{
    if (m_xLineSet->IsNoSelection())
        return SvxBorderLineStyle::NONE;
    auto nId = m_xLineSet->GetSelectedItemId();
    return static_cast<SvxBorderLineStyle>(nId - 1);
}

void SvtLineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
                            Color aColor1, Color aColor2, Color aColorDist,
                            SvxBorderLineStyle nStyle, BitmapEx& rBmp )
{
    Size aSize(m_xControl->get_approximate_digit_width() * 15, m_xControl->get_text_height());

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

    // Paint the lines
    aSize = aVirDev->PixelToLogic( aSize );
    long nPix = aVirDev->PixelToLogic( Size( 0, 1 ) ).Height();
    sal_uInt32 n1 = nLine1;
    sal_uInt32 n2 = nLine2;
    long nDist  = nDistance;
    n1 += nPix-1;
    n1 -= n1%nPix;
    if ( n2 )
    {
        nDist += nPix-1;
        nDist -= nDist%nPix;
        n2    += nPix-1;
        n2    -= n2%nPix;
    }
    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.get(), 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.get(), basegfx::B2DPoint( 0, y2 ), basegfx::B2DPoint( aSize.Width(), y2 ), n2, SvxBorderLineStyle::SOLID );
    }
    rBmp = aVirDev->GetBitmapEx( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
}

namespace
{
    OUString GetLineStyleName(SvxBorderLineStyle eStyle)
    {
        OUString sRet;
        for (sal_uInt32 i = 0; i < SAL_N_ELEMENTS(RID_SVXSTR_BORDERLINE); ++i)
        {
            if (eStyle == RID_SVXSTR_BORDERLINE[i].second)
            {
                sRet = SvtResId(RID_SVXSTR_BORDERLINE[i].first);
                break;
            }
        }
        return sRet;
    }
}

SvtLineListBox::SvtLineListBox(std::unique_ptr<weld::MenuButton> pControl)
    : m_xControl(std::move(pControl))
    , m_xBuilder(Application::CreateBuilder(m_xControl.get(), "svt/ui/linewindow.ui"))
    , m_xTopLevel(m_xBuilder->weld_widget("line_popup_window"))
    , m_xNoneButton(m_xBuilder->weld_button("none_line_button"))
    , m_xLineSet(new SvtValueSet(nullptr))
    , m_xLineSetWin(new weld::CustomWeld(*m_xBuilder, "lineset", *m_xLineSet))
    , m_nWidth( 5 )
    , aVirDev(VclPtr<VirtualDevice>::Create())
    , aColor(COL_BLACK)
    , maPaintCol(COL_BLACK)
{
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    m_xLineSet->SetStyle(WinBits(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP));
    m_xLineSet->SetItemHeight(rStyleSettings.GetListBoxPreviewDefaultPixelSize().Height() + 1);
    m_xLineSet->SetColCount(1);
    m_xLineSet->SetSelectHdl(LINK(this, SvtLineListBox, ValueSelectHdl));

    m_xNoneButton->connect_clicked(LINK(this, SvtLineListBox, NoneHdl));

    m_xTopLevel->connect_focus_in(LINK(this, SvtLineListBox, FocusHdl));
    m_xControl->set_popover(m_xTopLevel.get());
    m_xControl->set_label(GetLineStyleName(SvxBorderLineStyle::NONE));
    // lock to this text height
    m_xControl->set_size_request(-1, m_xControl->get_preferred_size().Height());

    eSourceUnit = FUNIT_POINT;

    aVirDev->SetLineColor();
    aVirDev->SetMapMode(MapMode(MapUnit::MapTwip));

    UpdatePaintLineColor();
}

IMPL_LINK_NOARG(SvtLineListBox, FocusHdl, weld::Widget&, void)
{
    if (GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
        m_xNoneButton->grab_focus();
    else
        m_xLineSet->GrabFocus();
}

IMPL_LINK_NOARG(SvtLineListBox, NoneHdl, weld::Button&, void)
{
    SelectEntry(SvxBorderLineStyle::NONE);
    ValueSelectHdl(nullptr);
}

SvtLineListBox::~SvtLineListBox()
{
}

sal_Int32 SvtLineListBox::GetStylePos( sal_Int32 nListPos )
{
    sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND;
    --nListPos;

    sal_Int32 n = 0;
    size_t i = 0;
    size_t nCount = m_vLineList.size();
    while ( nPos == LISTBOX_ENTRY_NOTFOUND && i < nCount )
    {
        if ( nListPos == n )
            nPos = static_cast<sal_Int32>(i);
        n++;
        i++;
    }

    return nPos;
}

void SvtLineListBox::SelectEntry(SvxBorderLineStyle nStyle)
{
    if (nStyle == SvxBorderLineStyle::NONE)
    {
        m_xLineSet->SetNoSelection();
        m_xNoneButton->set_has_default(true);
    }
    else
    {
        m_xLineSet->SelectItem(static_cast<sal_Int16>(nStyle) + 1);
        m_xNoneButton->set_has_default(false);
    }
    UpdatePreview();
}

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

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

    bool bRet = aNewCol != maPaintCol;

    if( bRet )
        maPaintCol = aNewCol;
}

void SvtLineListBox::UpdateEntries()
{
    UpdatePaintLineColor( );

    SvxBorderLineStyle eSelected = GetSelectEntryStyle();

    // Remove the old entries
    m_xLineSet->Clear();

    // Add the new entries based on the defined width

    sal_uInt16 n = 0;
    sal_uInt16 nCount = m_vLineList.size( );
    while ( n < nCount )
    {
        auto& pData = m_vLineList[ n ];
        BitmapEx aBmp;
        ImpGetLine( pData->GetLine1ForWidth( m_nWidth ),
                pData->GetLine2ForWidth( m_nWidth ),
                pData->GetDistForWidth( m_nWidth ),
                GetColorLine1(m_xLineSet->GetItemCount()),
                GetColorLine2(m_xLineSet->GetItemCount()),
                GetColorDist(m_xLineSet->GetItemCount()),
                pData->GetStyle(), aBmp );
        sal_Int16 nItemId = static_cast<sal_Int16>(pData->GetStyle()) + 1;
        m_xLineSet->InsertItem(nItemId, Image(aBmp), GetLineStyleName(pData->GetStyle()));
        if (pData->GetStyle() == eSelected)
            m_xLineSet->SelectItem(nItemId);
        n++;
    }

    m_xLineSet->SetOptimalSize();
}

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

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

Color SvtLineListBox::GetColorDist( sal_Int32 nPos )
{
    const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
    Color rResult = rSettings.GetFieldColor();

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

IMPL_LINK_NOARG(SvtLineListBox, StyleUpdated, weld::Widget&, void)
{
    UpdateEntries();
}

IMPL_LINK_NOARG(SvtLineListBox, ValueSelectHdl, SvtValueSet*, void)
{
    maSelectHdl.Call(*this);
    UpdatePreview();
    if (m_xControl->get_active())
        m_xControl->set_active(false);
}

void SvtLineListBox::UpdatePreview()
{
    SvxBorderLineStyle eStyle = GetSelectEntryStyle();
    for (sal_uInt32 i = 0; i < SAL_N_ELEMENTS(RID_SVXSTR_BORDERLINE); ++i)
    {
        if (eStyle == RID_SVXSTR_BORDERLINE[i].second)
        {
            m_xControl->set_label(SvtResId(RID_SVXSTR_BORDERLINE[i].first));
            break;
        }
    }

    if (eStyle == SvxBorderLineStyle::NONE)
    {
        m_xControl->set_image(nullptr);
        m_xControl->set_label(GetLineStyleName(SvxBorderLineStyle::NONE));
    }
    else
    {
        Image aImage(m_xLineSet->GetItemImage(m_xLineSet->GetSelectedItemId()));
        m_xControl->set_label("");
        const auto nPos = (aVirDev->GetOutputSizePixel().Height() - aImage.GetSizePixel().Height()) / 2;
        aVirDev->Push(PushFlags::MAPMODE);
        aVirDev->SetMapMode(MapMode(MapUnit::MapPixel));
        aVirDev->Erase();
        aVirDev->DrawImage(Point(0, nPos), aImage);
        aVirDev->Pop();
        m_xControl->set_image(aVirDev.get());
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index e45cf99..e39650e 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -2279,9 +2279,11 @@ void ValueSet::SetEdgeBlending(bool bNew)
SvtValueSet::SvtValueSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow)
    : maVirDev( VclPtr<VirtualDevice>::Create())
    , mxScrolledWindow(std::move(pScrolledWindow))
    , mnHighItemId(0)
    , maColor(COL_TRANSPARENT)
    , mnStyle(0)
    , mbFormat(true)
    , mbHighlight(false)
{
    maVirDev->SetBackground(Application::GetSettings().GetStyleSettings().GetFaceColor());

@@ -2303,6 +2305,7 @@ SvtValueSet::SvtValueSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow)
    mnSpacing           = 0;
    mnFrameStyle        = DrawFrameStyle::NONE;
    mbNoSelection       = true;
    mbDrawSelection     = true;
    mbBlackSel          = false;
    mbDoubleSel         = false;
    mbScroll            = false;
@@ -2653,6 +2656,25 @@ bool SvtValueSet::KeyInput( const KeyEvent& rKeyEvent )
    return true;
}

void SvtValueSet::ImplTracking(const Point& rPos)
{
    SvtValueSetItem* pItem = ImplGetItem( ImplGetItem( rPos ) );
    if ( pItem )
    {
        if( GetStyle() & WB_MENUSTYLEVALUESET || GetStyle() & WB_FLATVALUESET )
            mbHighlight = true;

        ImplHighlightItem( pItem->mnId );
    }
    else
    {
        if( GetStyle() & WB_MENUSTYLEVALUESET || GetStyle() & WB_FLATVALUESET )
            mbHighlight = true;

        ImplHighlightItem( mnSelItemId, false );
    }
}

void SvtValueSet::MouseButtonDown( const MouseEvent& rMouseEvent )
{
    if ( rMouseEvent.IsLeft() )
@@ -2677,6 +2699,14 @@ void SvtValueSet::MouseButtonDown( const MouseEvent& rMouseEvent )
    CustomWidgetController::MouseButtonDown( rMouseEvent );
}

void SvtValueSet::MouseMove(const MouseEvent& rMouseEvent)
{
    // because of SelectionMode
    if ((GetStyle() & WB_MENUSTYLEVALUESET) || (GetStyle() & WB_FLATVALUESET))
        ImplTracking(rMouseEvent.GetPosPixel());
    CustomWidgetController::MouseMove(rMouseEvent);
}

void SvtValueSet::RemoveItem( sal_uInt16 nItemId )
{
    size_t nPos = GetItemPos( nItemId );
@@ -2780,6 +2810,23 @@ tools::Rectangle SvtValueSet::ImplGetItemRect( size_t nPos ) const
    return tools::Rectangle( Point(x, y), Size(mnItemWidth, mnItemHeight) );
}

void SvtValueSet::ImplHighlightItem( sal_uInt16 nItemId, bool bIsSelection )
{
    if ( mnHighItemId == nItemId )
        return;

    // remember the old item to delete the previous selection
    mnHighItemId = nItemId;

    // don't draw the selection if nothing is selected
    if ( !bIsSelection && mbNoSelection )
        mbDrawSelection = false;

    // remove the old selection and draw the new one
    Invalidate();
    mbDrawSelection = true;
}

void SvtValueSet::ImplDraw(vcl::RenderContext& rRenderContext)
{
    if (mbFormat)
@@ -2916,6 +2963,7 @@ void SvtValueSet::SelectItem( sal_uInt16 nItemId )
void SvtValueSet::SetNoSelection()
{
    mbNoSelection   = true;
    mbHighlight     = false;

    if (IsReallyVisible() && IsUpdateMode())
        Invalidate();
@@ -3260,13 +3308,19 @@ void SvtValueSet::ImplDrawSelect(vcl::RenderContext& rRenderContext)
        return;

    const bool bFocus = HasFocus();
    if (!bFocus && mbNoSelection)
    const bool bDrawSel = !((mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight));

    if (!bFocus && !bDrawSel)
    {
        ImplDrawItemText(rRenderContext, OUString());
        return;
    }

    ImplDrawSelect(rRenderContext, mnSelItemId, bFocus, !mbNoSelection);
    ImplDrawSelect(rRenderContext, mnSelItemId, bFocus, bDrawSel);
    if (mbHighlight)
    {
        ImplDrawSelect(rRenderContext, mnHighItemId, bFocus, bDrawSel);
    }
}

void SvtValueSet::ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel )
@@ -3568,6 +3622,26 @@ void SvtValueSet::SetColCount( sal_uInt16 nNewCols )
    }
}

void SvtValueSet::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
{
    size_t nPos = GetItemPos( nItemId );

    if ( nPos == VALUESET_ITEM_NOTFOUND )
        return;

    SvtValueSetItem* pItem = mItemList[nPos];
    pItem->meType  = VALUESETITEM_IMAGE;
    pItem->maImage = rImage;

    if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
    {
        const tools::Rectangle aRect = ImplGetItemRect(nPos);
        Invalidate(aRect);
    }
    else
        mbFormat = true;
}

Color SvtValueSet::GetItemColor( sal_uInt16 nItemId ) const
{
    size_t nPos = GetItemPos( nItemId );
@@ -3661,6 +3735,14 @@ void SvtValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage,
    ImplInsertItem( pItem, nPos );
}

void SvtValueSet::InsertItem( sal_uInt16 nItemId, size_t nPos )
{
    SvtValueSetItem* pItem = new SvtValueSetItem( *this );
    pItem->mnId     = nItemId;
    pItem->meType   = VALUESETITEM_USERDRAW;
    ImplInsertItem( pItem, nPos );
}

void SvtValueSet::InsertItem( sal_uInt16 nItemId, const Color& rColor,
                           const OUString& rText )
{
@@ -3830,6 +3912,9 @@ void SvtValueSet::SetItemText(sal_uInt16 nItemId, const OUString& rText)
    {
        sal_uInt16 nTempId = mnSelItemId;

        if (mbHighlight)
            nTempId = mnHighItemId;

        if (nTempId == nItemId)
            Invalidate();
    }
@@ -3842,4 +3927,55 @@ void SvtValueSet::SetItemText(sal_uInt16 nItemId, const OUString& rText)
    }
}

Size SvtValueSet::GetLargestItemSize()
{
    Size aLargestItem;

    for (SvtValueSetItem* pItem : mItemList)
    {
        if (!pItem->mbVisible)
            continue;

        if (pItem->meType != VALUESETITEM_IMAGE &&
            pItem->meType != VALUESETITEM_IMAGE_AND_TEXT)
        {
            // handle determining an optimal size for this case
            continue;
        }

        Size aSize = pItem->maImage.GetSizePixel();
        if (pItem->meType == VALUESETITEM_IMAGE_AND_TEXT)
        {
            aSize.AdjustHeight(3 * NAME_LINE_HEIGHT +
                maVirDev->GetTextHeight() );
            aSize.setWidth( std::max(aSize.Width(),
                                     maVirDev->GetTextWidth(pItem->maText) + NAME_OFFSET) );
        }

        aLargestItem.setWidth( std::max(aLargestItem.Width(), aSize.Width()) );
        aLargestItem.setHeight( std::max(aLargestItem.Height(), aSize.Height()) );
    }

    return aLargestItem;
}

void SvtValueSet::SetOptimalSize()
{
    Size aLargestSize(GetLargestItemSize());
    aLargestSize.setWidth(std::max(aLargestSize.Width(), mnUserItemWidth));
    aLargestSize.setHeight(std::max(aLargestSize.Height(), mnUserItemHeight));
    Size aPrefSize(CalcWindowSizePixel(aLargestSize));
    GetDrawingArea()->set_size_request(aPrefSize.Width(), aPrefSize.Height());
}

Image SvtValueSet::GetItemImage(sal_uInt16 nItemId) const
{
    size_t nPos = GetItemPos( nItemId );

    if ( nPos != VALUESET_ITEM_NOTFOUND )
        return mItemList[nPos]->maImage;
    else
        return Image();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/uiconfig/ui/linewindow.ui b/svtools/uiconfig/ui/linewindow.ui
new file mode 100644
index 0000000..e438cf8
--- /dev/null
+++ b/svtools/uiconfig/ui/linewindow.ui
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="svx">
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkPopover" id="line_popup_window">
    <property name="can_focus">False</property>
    <property name="border_width">4</property>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <property name="spacing">6</property>
        <child>
          <object class="GtkButton" id="none_line_button">
            <property name="label" translatable="yes" context="colorwindow|none_color_button">None</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="can_default">True</property>
            <property name="receives_default">True</property>
            <property name="no_show_all">True</property>
            <property name="image">none_icon</property>
            <property name="xalign">0</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkDrawingArea" id="lineset">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkImage" id="none_icon">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="icon_name">cmd/sc_square_unfilled.png</property>
  </object>
</interface>
diff --git a/svx/source/accessibility/AccessibleFrameSelector.cxx b/svx/source/accessibility/AccessibleFrameSelector.cxx
index 4f31f76..e180bec 100644
--- a/svx/source/accessibility/AccessibleFrameSelector.cxx
+++ b/svx/source/accessibility/AccessibleFrameSelector.cxx
@@ -54,55 +54,35 @@ using ::com::sun::star::awt::XFocusListener;
using namespace ::com::sun::star::accessibility;


AccFrameSelector::AccFrameSelector( FrameSelector& rFrameSel, FrameBorderType eBorder ) :
    mpFrameSel( &rFrameSel ),
    meBorder( eBorder ),
    maFocusListeners( maFocusMutex ),
    maPropertyListeners( maPropertyMutex ),
    mnClientId( 0 )
AccFrameSelector::AccFrameSelector(FrameSelector& rFrameSel)
    : mpFrameSel(&rFrameSel)
{
    if ( mpFrameSel )
    {
        mpFrameSel->AddEventListener( LINK( this, AccFrameSelector, WindowEventListener ) );
    }
}


AccFrameSelector::~AccFrameSelector()
{
    RemoveFrameSelEventListener();
}


void AccFrameSelector::RemoveFrameSelEventListener()
{
    if ( mpFrameSel )
    {
        mpFrameSel->RemoveEventListener( LINK( this, AccFrameSelector, WindowEventListener ) );
    }
}

IMPLEMENT_FORWARD_XINTERFACE2( AccFrameSelector, OAccessibleComponentHelper, OAccessibleHelper_Base )
IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccFrameSelector, OAccessibleComponentHelper, OAccessibleHelper_Base )

Reference< XAccessibleContext > AccFrameSelector::getAccessibleContext(  )
{
    return this;
}


sal_Int32 AccFrameSelector::getAccessibleChildCount(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return (meBorder == FrameBorderType::NONE) ? mpFrameSel->GetEnabledBorderCount() : 0;
    return mpFrameSel->GetEnabledBorderCount();
}

Reference< XAccessible > AccFrameSelector::getAccessibleChild( sal_Int32 i )
{
    SolarMutexGuard aGuard;
    IsValid();
    Reference< XAccessible > xRet;
    if( meBorder == FrameBorderType::NONE )
        xRet = mpFrameSel->GetChildAccessible( i );
    Reference< XAccessible > xRet = mpFrameSel->GetChildAccessible( i );
    if( !xRet.is() )
        throw RuntimeException();
    return xRet;
@@ -112,86 +92,34 @@ Reference< XAccessible > AccFrameSelector::getAccessibleParent(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    Reference< XAccessible > xRet;
    if(meBorder == FrameBorderType::NONE)
        xRet = mpFrameSel->GetParent()->GetAccessible();
    else
        xRet = mpFrameSel->CreateAccessible();
    Reference< XAccessible > xRet = mpFrameSel->getAccessibleParent();
    return xRet;
}

sal_Int32 AccFrameSelector::getAccessibleIndexInParent(  )
{
    SolarMutexGuard aGuard;
    IsValid();

    sal_Int32 nIdx = 0;
    if( meBorder == FrameBorderType::NONE )
    {
        vcl::Window* pTabPage = mpFrameSel->GetParent();
        if (!pTabPage)
            return nIdx;
        sal_Int32 nChildren = pTabPage->GetChildCount();
        for( nIdx = 0; nIdx < nChildren; ++nIdx )
            if( pTabPage->GetChild( static_cast< sal_uInt16 >( nIdx ) ) == mpFrameSel )
                break;
    }
    else
        nIdx = mpFrameSel->GetEnabledBorderIndex( meBorder );

    if( nIdx < 0 )
        throw RuntimeException();
    return nIdx;
}

sal_Int16 AccFrameSelector::getAccessibleRole(  )
{
    return meBorder == FrameBorderType::NONE ? AccessibleRole::OPTION_PANE : AccessibleRole::CHECK_BOX;
    return AccessibleRole::OPTION_PANE;
}

OUString AccFrameSelector::getAccessibleDescription(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return SvxResId(RID_SVXSTR_FRMSEL_DESCRIPTIONS[static_cast<sal_uInt32>(meBorder)].first);
    return SvxResId(RID_SVXSTR_FRMSEL_DESCRIPTIONS[0].first);
}

OUString AccFrameSelector::getAccessibleName(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return SvxResId(RID_SVXSTR_FRMSEL_TEXTS[static_cast<sal_uInt32>(meBorder)].first);
    return SvxResId(RID_SVXSTR_FRMSEL_TEXTS[0].first);
}

Reference< XAccessibleRelationSet > AccFrameSelector::getAccessibleRelationSet(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    utl::AccessibleRelationSetHelper* pHelper;
    Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper;
    if(meBorder == FrameBorderType::NONE)
    {
        //add the label relation
        vcl::Window *pLabeledBy = mpFrameSel->GetAccessibleRelationLabeledBy();
        if ( pLabeledBy && pLabeledBy != mpFrameSel )
        {
            AccessibleRelation aLabelRelation;
            aLabelRelation.RelationType = AccessibleRelationType::LABELED_BY;
            aLabelRelation.TargetSet.realloc(1);
            aLabelRelation.TargetSet.getArray()[0]  = pLabeledBy->GetAccessible();
            pHelper->AddRelation(aLabelRelation);
        }
        vcl::Window* pMemberOf = mpFrameSel->GetAccessibleRelationMemberOf();
        if ( pMemberOf && pMemberOf != mpFrameSel )
        {
            AccessibleRelation aMemberOfRelation;
            aMemberOfRelation.RelationType = AccessibleRelationType::MEMBER_OF;
            aMemberOfRelation.TargetSet.realloc(1);
            aMemberOfRelation.TargetSet.getArray()[0]  = pMemberOf->GetAccessible();
            pHelper->AddRelation(aMemberOfRelation);
        }
    }
    return xRet;
    return mpFrameSel->get_accessible_relation_set();
}

Reference< XAccessibleStateSet > AccFrameSelector::getAccessibleStateSet(  )
@@ -225,9 +153,7 @@ Reference< XAccessibleStateSet > AccFrameSelector::getAccessibleStateSet(  )
            pStateSetHelper->AddState(AccessibleStateType::SENSITIVE);
        }

        bool bIsParent = meBorder == FrameBorderType::NONE;
        if(mpFrameSel->HasFocus() &&
            (bIsParent || mpFrameSel->IsBorderSelected(meBorder)))
        if (mpFrameSel->HasFocus())
        {
            pStateSetHelper->AddState(AccessibleStateType::ACTIVE);
            pStateSetHelper->AddState(AccessibleStateType::FOCUSED);
@@ -237,19 +163,6 @@ Reference< XAccessibleStateSet > AccFrameSelector::getAccessibleStateSet(  )
    return xRet;
}

Locale AccFrameSelector::getLocale(  )
{
    return Application::GetSettings().GetUILanguageTag().getLocale();
}

sal_Bool AccFrameSelector::containsPoint( const css::awt::Point& aPt )
{
    SolarMutexGuard aGuard;
    IsValid();
    //aPt is relative to the frame selector
    return mpFrameSel->ContainsClickPoint( Point( aPt.X, aPt.Y ) );
}

Reference< XAccessible > AccFrameSelector::getAccessibleAtPoint(
    const css::awt::Point& aPt )
{
@@ -259,89 +172,6 @@ Reference< XAccessible > AccFrameSelector::getAccessibleAtPoint(
    return mpFrameSel->GetChildAccessible( Point( aPt.X, aPt.Y ) );
}

css::awt::Rectangle AccFrameSelector::getBounds(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    Size aSz;
    Point aPos;
    switch(meBorder)
    {
        case FrameBorderType::NONE:
            aSz = mpFrameSel->GetSizePixel();
            aPos = mpFrameSel->GetPosPixel();
        break;
        default:
            const tools::Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
            aPos = aSpot.TopLeft();
            aSz = aSpot.GetSize();
    }
    css::awt::Rectangle aRet;
    aRet.X = aPos.X();
    aRet.Y = aPos.Y();
    aRet.Width = aSz.Width();
    aRet.Height = aSz.Height();
    return aRet;
}


css::awt::Point AccFrameSelector::getLocation(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    Point aPos;
    switch(meBorder)
    {
        case FrameBorderType::NONE:
            aPos = mpFrameSel->GetPosPixel();
        break;
        default:
            const tools::Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
            aPos = aSpot.TopLeft();
    }
    css::awt::Point aRet(aPos.X(), aPos.Y());
    return aRet;
}


css::awt::Point AccFrameSelector::getLocationOnScreen(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    Point aPos;
    switch(meBorder)
    {
        case FrameBorderType::NONE:
            aPos = mpFrameSel->GetPosPixel();
        break;
        default:
            const tools::Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
            aPos = aSpot.TopLeft();
    }
    aPos = mpFrameSel->OutputToAbsoluteScreenPixel( aPos );
    css::awt::Point aRet(aPos.X(), aPos.Y());
    return aRet;
}


css::awt::Size AccFrameSelector::getSize(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    Size aSz;
    switch(meBorder)
    {
        case FrameBorderType::NONE:
            aSz = mpFrameSel->GetSizePixel();
        break;
        default:
            const tools::Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
            aSz = aSpot.GetSize();
    }
    css::awt::Size aRet(aSz.Width(), aSz.Height());
    return aRet;
}

void AccFrameSelector::grabFocus(  )
{
    SolarMutexGuard aGuard;
@@ -352,65 +182,36 @@ void AccFrameSelector::grabFocus(  )
sal_Int32 AccFrameSelector::getForeground(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return sal_Int32(mpFrameSel->GetControlForeground());

    //see FrameSelector::Paint
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
    return sal_Int32(rStyles.GetLabelTextColor());
}

sal_Int32 AccFrameSelector::getBackground(  )
{
    SolarMutexGuard aGuard;

    //see FrameSelector::Paint
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
    return sal_Int32(rStyles.GetDialogColor());
}

css::awt::Rectangle AccFrameSelector::implGetBounds()
{
    SolarMutexGuard aGuard;
    IsValid();
    return sal_Int32(mpFrameSel->GetControlBackground());
}

void AccFrameSelector::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
{
    SolarMutexGuard aGuard;
    css::awt::Rectangle aRet;

    if ( xListener.is() )
    {
        if ( !mnClientId )
        {
            mnClientId = ::comphelper::AccessibleEventNotifier::registerClient();
        }
        ::comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
    }
}
    const Point   aOutPos;
    Size          aOutSize(mpFrameSel->GetOutputSizePixel());

void AccFrameSelector::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
{
    SolarMutexGuard aGuard;
    aRet.X = aOutPos.X();
    aRet.Y = aOutPos.Y();
    aRet.Width = aOutSize.Width();
    aRet.Height = aOutSize.Height();

    if ( xListener.is() && mnClientId != 0 &&
         ::comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ) == 0 )
    {
        // no listeners anymore
        // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
        // and at least to us not firing any events anymore, in case somebody calls
        // NotifyAccessibleEvent, again
        ::comphelper::AccessibleEventNotifier::TClientId nId( mnClientId );
        mnClientId = 0;
        ::comphelper::AccessibleEventNotifier::revokeClient( nId );
    }
}

OUString AccFrameSelector::getImplementationName(  )
{
    return OUString("AccFrameSelector");
}

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

Sequence< OUString > AccFrameSelector::getSupportedServiceNames(  )
{
    Sequence< OUString > aRet(3);
    OUString* pArray = aRet.getArray();
    pArray[0] = "Accessible";
    pArray[1] = "AccessibleContext";
    pArray[2] = "AccessibleComponent";
    return aRet;
}

@@ -420,106 +221,177 @@ void AccFrameSelector::IsValid()
        throw RuntimeException();
}

void AccFrameSelector::NotifyFocusListeners(bool bGetFocus)
{
    SolarMutexGuard aGuard;
    css::awt::FocusEvent aEvent;
    aEvent.FocusFlags = 0;
    if(bGetFocus)
    {
        GetFocusFlags nFocusFlags = mpFrameSel->GetGetFocusFlags();
        if(nFocusFlags & GetFocusFlags::Tab)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::TAB;
        if(nFocusFlags & GetFocusFlags::CURSOR)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::CURSOR;
        if(nFocusFlags & GetFocusFlags::Mnemonic)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::MNEMONIC;
        if(nFocusFlags & GetFocusFlags::Forward)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::FORWARD;
        if(nFocusFlags & GetFocusFlags::Backward)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::BACKWARD;
        if(nFocusFlags & GetFocusFlags::Around)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::AROUND;
        if(nFocusFlags & GetFocusFlags::UniqueMnemonic)
            aEvent.FocusFlags |= css::awt::FocusChangeReason::UNIQUEMNEMONIC;
    }
    aEvent.Temporary = false;

    Reference < XAccessibleContext > xThis( this );
    aEvent.Source = xThis;

    ::comphelper::OInterfaceIteratorHelper2 aIter( maFocusListeners );
    while( aIter.hasMoreElements() )
    {
        Reference < XFocusListener > xListener( aIter.next(), UNO_QUERY );
        if(bGetFocus)
            xListener->focusGained( aEvent );
        else
            xListener->focusLost( aEvent );
    }
}


IMPL_LINK( AccFrameSelector, WindowEventListener, VclWindowEvent&, rEvent, void )
{
    vcl::Window* pWindow = rEvent.GetWindow();
    DBG_ASSERT( pWindow, "AccFrameSelector::WindowEventListener: no window!" );
    if ( pWindow->IsAccessibilityEventsSuppressed() && ( rEvent.GetId() != VclEventId::ObjectDying ) )
        return;

    switch ( rEvent.GetId() )
    {
        case VclEventId::WindowGetFocus:
        {
            if ( meBorder == FrameBorderType::NONE )
            {
                Any aOldValue, aNewValue;
                aNewValue <<= AccessibleStateType::FOCUSED;
                NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
            }
        }
        break;
        case VclEventId::WindowLoseFocus:
        {
            if ( meBorder == FrameBorderType::NONE )
            {
                Any aOldValue, aNewValue;
                aOldValue <<= AccessibleStateType::FOCUSED;
                NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
            }
        }
        break;
        default:
        {
        }
        break;
    }
}


void AccFrameSelector::NotifyAccessibleEvent( const sal_Int16 _nEventId,
    const Any& _rOldValue, const Any& _rNewValue )
{
    if ( mnClientId )
    {
        Reference< XInterface > xSource( *this );
        AccessibleEventObject aEvent( xSource, _nEventId, _rNewValue, _rOldValue );
        ::comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
    }
}


void AccFrameSelector::Invalidate()
{
    RemoveFrameSelEventListener();
    mpFrameSel = nullptr;
    EventObject aEvent;
    Reference < XAccessibleContext > xThis( this );
    aEvent.Source = xThis;
    maFocusListeners.disposeAndClear( aEvent );
    maPropertyListeners.disposeAndClear( aEvent );
}

AccFrameSelectorChild::AccFrameSelectorChild(FrameSelector& rFrameSel, FrameBorderType eBorder)
    : mpFrameSel(&rFrameSel)
    , meBorder(eBorder)
{
}

AccFrameSelectorChild::~AccFrameSelectorChild()
{
}

IMPLEMENT_FORWARD_XINTERFACE2( AccFrameSelectorChild, OAccessibleComponentHelper, OAccessibleHelper_Base )
IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccFrameSelectorChild, OAccessibleComponentHelper, OAccessibleHelper_Base )

Reference< XAccessibleContext > AccFrameSelectorChild::getAccessibleContext(  )
{
    return this;
}

sal_Int32 AccFrameSelectorChild::getAccessibleChildCount(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return 0;
}

Reference< XAccessible > AccFrameSelectorChild::getAccessibleChild( sal_Int32 )
{
    throw RuntimeException();
}

Reference< XAccessible > AccFrameSelectorChild::getAccessibleParent(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    Reference< XAccessible > xRet = mpFrameSel->CreateAccessible();
    return xRet;
}

sal_Int16 AccFrameSelectorChild::getAccessibleRole(  )
{
    return AccessibleRole::CHECK_BOX;
}

OUString AccFrameSelectorChild::getAccessibleDescription(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return SvxResId(RID_SVXSTR_FRMSEL_DESCRIPTIONS[static_cast<sal_uInt32>(meBorder)].first);
}

OUString AccFrameSelectorChild::getAccessibleName(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    return SvxResId(RID_SVXSTR_FRMSEL_TEXTS[static_cast<sal_uInt32>(meBorder)].first);
}

Reference< XAccessibleRelationSet > AccFrameSelectorChild::getAccessibleRelationSet(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    utl::AccessibleRelationSetHelper* pHelper;
    Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper;
    return xRet;
}

Reference< XAccessibleStateSet > AccFrameSelectorChild::getAccessibleStateSet(  )
{
    SolarMutexGuard aGuard;
    utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
    Reference< XAccessibleStateSet > xRet = pStateSetHelper;

    if(!mpFrameSel)
        pStateSetHelper->AddState(AccessibleStateType::DEFUNC);
    else
    {
        const sal_Int16 aStandardStates[] =
        {
            AccessibleStateType::EDITABLE,
            AccessibleStateType::FOCUSABLE,
            AccessibleStateType::MULTI_SELECTABLE,
            AccessibleStateType::SELECTABLE,
            AccessibleStateType::SHOWING,
            AccessibleStateType::VISIBLE,
            AccessibleStateType::OPAQUE,
            0};
        sal_Int16 nState = 0;
        while(aStandardStates[nState])
        {
            pStateSetHelper->AddState(aStandardStates[nState++]);
        }
        if(mpFrameSel->IsEnabled())
        {
            pStateSetHelper->AddState(AccessibleStateType::ENABLED);
            pStateSetHelper->AddState(AccessibleStateType::SENSITIVE);
        }

        if (mpFrameSel->HasFocus() && mpFrameSel->IsBorderSelected(meBorder))
        {
            pStateSetHelper->AddState(AccessibleStateType::ACTIVE);
            pStateSetHelper->AddState(AccessibleStateType::FOCUSED);
            pStateSetHelper->AddState(AccessibleStateType::SELECTED);
        }
    }
    return xRet;
}

Reference< XAccessible > AccFrameSelectorChild::getAccessibleAtPoint(
    const css::awt::Point& aPt )
{
    SolarMutexGuard aGuard;
    IsValid();
    //aPt is relative to the frame selector
    return mpFrameSel->GetChildAccessible( Point( aPt.X, aPt.Y ) );
}

css::awt::Rectangle AccFrameSelectorChild::implGetBounds(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    const tools::Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
    Point aPos = aSpot.TopLeft();
    Size aSz = aSpot.GetSize();
    css::awt::Rectangle aRet;
    aRet.X = aPos.X();
    aRet.Y = aPos.Y();
    aRet.Width = aSz.Width();
    aRet.Height = aSz.Height();
    return aRet;
}

void AccFrameSelectorChild::grabFocus(  )
{
    SolarMutexGuard aGuard;
    IsValid();
    mpFrameSel->GrabFocus();
}

sal_Int32 AccFrameSelectorChild::getForeground(  )
{
    SolarMutexGuard aGuard;

    //see FrameSelector::Paint
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
    return sal_Int32(rStyles.GetLabelTextColor());
}

sal_Int32 AccFrameSelectorChild::getBackground(  )
{
    SolarMutexGuard aGuard;

    //see FrameSelector::Paint
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
    return sal_Int32(rStyles.GetDialogColor());
}

void AccFrameSelectorChild::IsValid()
{
    if(!mpFrameSel)
        throw RuntimeException();
}

void AccFrameSelectorChild::Invalidate()
{
    mpFrameSel = nullptr;
}

}
}
diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx
index fd1e7dd..c8340e8 100644
--- a/svx/source/dialog/frmsel.cxx
+++ b/svx/source/dialog/frmsel.cxx
@@ -28,6 +28,7 @@
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <drawinglayer/processor2d/processor2dtools.hxx>

#include <bitmaps.hlst>
@@ -261,8 +262,6 @@ FrameSelectorImpl::FrameSelectorImpl( FrameSelector& rFrameSel ) :
FrameSelectorImpl::~FrameSelectorImpl()

{
    if( mxAccess.is() )
        mxAccess->Invalidate();
    for( auto aIt = maChildVec.begin(), aEnd = maChildVec.end(); aIt != aEnd; ++aIt )
        if( aIt->is() )
            (*aIt)->Invalidate();
@@ -290,7 +289,7 @@ void FrameSelectorImpl::Initialize( FrameSelFlags nFlags )

void FrameSelectorImpl::InitColors()
{
    const StyleSettings& rSettings = mrFrameSel.GetSettings().GetStyleSettings();
    const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
    maBackCol = rSettings.GetFieldColor();
    mbHCMode = rSettings.GetHighContrastMode();
    maArrowCol = rSettings.GetFieldTextColor();
@@ -346,7 +345,7 @@ void FrameSelectorImpl::InitArrowImageList()

void FrameSelectorImpl::InitGlobalGeometry()
{
    Size aCtrlSize( mrFrameSel.CalcOutputSize( mrFrameSel.GetSizePixel() ) );
    Size aCtrlSize(mrFrameSel.GetOutputSizePixel());
    /*  nMinSize is the lower of width and height (control will always be squarish).
        FRAMESEL_GEOM_OUTER is the minimal distance between inner control border
        and any element. */
@@ -513,8 +512,6 @@ void FrameSelectorImpl::sizeChanged()
    InitGlobalGeometry();
    InitBorderGeometry();

    // correct background around the used area
    mrFrameSel.SetBackground( Wallpaper( maBackCol ) );
    DoInvalidate( true );
}

@@ -709,7 +706,7 @@ void FrameSelectorImpl::CopyVirDevToControl(vcl::RenderContext& rRenderContext)
    rRenderContext.DrawBitmapEx(maVirDevPos, mpVirDev->GetBitmapEx(Point(0, 0), mpVirDev->GetOutputSizePixel()));
}

void FrameSelectorImpl::DrawAllTrackingRects()
void FrameSelectorImpl::DrawAllTrackingRects(vcl::RenderContext& rRenderContext)
{
    tools::PolyPolygon aPPoly;
    if (mrFrameSel.IsAnyBorderSelected())
@@ -723,8 +720,9 @@ void FrameSelectorImpl::DrawAllTrackingRects()
        aPPoly.Insert( tools::Polygon(tools::Rectangle(maVirDevPos, mpVirDev->GetOutputSizePixel())));

    aPPoly.Optimize(PolyOptimizeFlags::CLOSE);

    for(sal_uInt16 nIdx = 0, nCount = aPPoly.Count(); nIdx < nCount; ++nIdx)
        mrFrameSel.InvertTracking(aPPoly.GetObject(nIdx), ShowTrackFlags::Small | ShowTrackFlags::TrackWindow);
        rRenderContext.Invert(aPPoly.GetObject(nIdx), InvertFlags::TrackFrame);
}

Point FrameSelectorImpl::GetDevPosFromMousePos( const Point& rMousePos ) const
@@ -735,7 +733,7 @@ Point FrameSelectorImpl::GetDevPosFromMousePos( const Point& rMousePos ) const
void FrameSelectorImpl::DoInvalidate( bool bFullRepaint )
{
    mbFullRepaint |= bFullRepaint;
    mrFrameSel.Invalidate( InvalidateFlags::NoErase );
    mrFrameSel.Invalidate();
}

// frame border state and style
@@ -757,7 +755,7 @@ void FrameSelectorImpl::SetBorderState( FrameBorder& rBorder, FrameBorderState e
    else
        rBorder.SetState( eState );
    if (pFrameSelector)
            pFrameSelector->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOld, aNew );
        pFrameSelector->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOld, aNew );
    DoInvalidate( true );
}

@@ -816,22 +814,23 @@ bool FrameSelectorImpl::SelectedBordersEqual() const
    return bEqual;
}

FrameSelector::FrameSelector(vcl::Window* pParent)
    : Control(pParent, WB_BORDER|WB_TABSTOP)
FrameSelector::FrameSelector()
{
    // not in c'tor init list (avoid warning about usage of *this)
}

void FrameSelector::SetDrawingArea(weld::DrawingArea* pDrawingArea)
{
    Size aPrefSize = pDrawingArea->get_ref_device().LogicToPixel(Size(61, 65), MapMode(MapUnit::MapAppFont));
    pDrawingArea->set_size_request(aPrefSize.Width(), aPrefSize.Height());
    CustomWidgetController::SetDrawingArea(pDrawingArea);
    mxImpl.reset( new FrameSelectorImpl( *this ) );
    EnableRTL( false ); // #107808# don't mirror the mouse handling
}

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

extern "C" SAL_DLLPUBLIC_EXPORT void makeSvxFrameSelector(VclPtr<vcl::Window> & rRet, VclPtr<vcl::Window> & pParent, VclBuilder::stringmap &)
{
    rRet = VclPtr<FrameSelector>::Create(pParent);
    if( mxAccess.is() )
        mxAccess->Invalidate();
}

void FrameSelector::Initialize( FrameSelFlags nFlags )
@@ -1023,9 +1022,9 @@ void FrameSelector::SetColorToSelection( const Color& rColor )
// accessibility
Reference< XAccessible > FrameSelector::CreateAccessible()
{
    if( !mxImpl->mxAccess.is() )
        mxImpl->mxAccess = new a11y::AccFrameSelector( *this, FrameBorderType::NONE );
    return mxImpl->mxAccess.get();
    if( !mxAccess.is() )
        mxAccess = new a11y::AccFrameSelector(*this);
    return mxAccess.get();
}

Reference< XAccessible > FrameSelector::GetChildAccessible( FrameBorderType eBorder )
@@ -1036,7 +1035,7 @@ Reference< XAccessible > FrameSelector::GetChildAccessible( FrameBorderType eBor
    {
        --nVecIdx;
        if( !mxImpl->maChildVec[ nVecIdx ].is() )
            mxImpl->maChildVec[ nVecIdx ] = new a11y::AccFrameSelector( *this, eBorder );
            mxImpl->maChildVec[ nVecIdx ] = new a11y::AccFrameSelectorChild( *this, eBorder );
        xRet = mxImpl->maChildVec[ nVecIdx ].get();
    }
    return xRet;
@@ -1078,7 +1077,7 @@ void FrameSelector::Paint(vcl::RenderContext& rRenderContext, const tools::Recta
{
    mxImpl->CopyVirDevToControl(rRenderContext);
    if (HasFocus())
        mxImpl->DrawAllTrackingRects();
        mxImpl->DrawAllTrackingRects(rRenderContext);
}

void FrameSelector::MouseButtonDown( const MouseEvent& rMEvt )
@@ -1167,7 +1166,7 @@ void FrameSelector::MouseButtonDown( const MouseEvent& rMEvt )
    }
}

void FrameSelector::KeyInput( const KeyEvent& rKEvt )
bool FrameSelector::KeyInput( const KeyEvent& rKEvt )
{
    bool bHandled = false;
    vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
@@ -1214,8 +1213,9 @@ void FrameSelector::KeyInput( const KeyEvent& rKEvt )
            break;
        }
    }
    if( !bHandled )
        Window::KeyInput(rKEvt);
    if (bHandled)
        return true;
    return CustomWidgetController::KeyInput(rKEvt);
}

void FrameSelector::GetFocus()
@@ -1225,8 +1225,6 @@ void FrameSelector::GetFocus()
        mxImpl->SelectBorder( *mxImpl->maEnabBorders.front(), true );

    mxImpl->DoInvalidate( false );
    if( mxImpl->mxAccess.is() )
        mxImpl->mxAccess->NotifyFocusListeners( true );
    if (IsAnyBorderSelected())
    {
        FrameBorderType borderType = FrameBorderType::NONE;
@@ -1250,36 +1248,27 @@ void FrameSelector::GetFocus()
    }
    for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
            mxImpl->SetBorderState( **aIt, FrameBorderState::Show );
    Control::GetFocus();
    CustomWidgetController::GetFocus();
}

void FrameSelector::LoseFocus()
{
    mxImpl->DoInvalidate( false );
    if( mxImpl->mxAccess.is() )
        mxImpl->mxAccess->NotifyFocusListeners( false );
    Control::LoseFocus();
    CustomWidgetController::LoseFocus();
}

void FrameSelector::DataChanged( const DataChangedEvent& rDCEvt )
void FrameSelector::StyleUpdated()
{
    Control::DataChanged( rDCEvt );
    if( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
        mxImpl->InitVirtualDevice();
    mxImpl->InitVirtualDevice();
    CustomWidgetController::StyleUpdated();
}

void FrameSelector::Resize()
{
    Control::Resize();
    CustomWidgetController::Resize();
    mxImpl->sizeChanged();
}

Size FrameSelector::GetOptimalSize() const
{
    return LogicToPixel(Size(61, 65), MapMode(MapUnit::MapAppFont));
}


template< typename Cont, typename Iter, typename Pred >
FrameBorderIterBase< Cont, Iter, Pred >::FrameBorderIterBase( container_type& rCont ) :
    maIt( rCont.begin() ),
@@ -1295,7 +1284,6 @@ FrameBorderIterBase< Cont, Iter, Pred >& FrameBorderIterBase< Cont, Iter, Pred >
    return *this;
}


}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/inc/AccessibleFrameSelector.hxx b/svx/source/inc/AccessibleFrameSelector.hxx
index e7482b9..177780f 100644
--- a/svx/source/inc/AccessibleFrameSelector.hxx
+++ b/svx/source/inc/AccessibleFrameSelector.hxx
@@ -29,91 +29,110 @@
#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
#include <tools/link.hxx>
#include <cppuhelper/implbase.hxx>
#include <comphelper/interfacecontainer2.hxx>
#include <comphelper/accessibleeventnotifier.hxx>
#include <comphelper/accessibleselectionhelper.hxx>
#include <svx/framebordertype.hxx>
#include <vcl/vclptr.hxx>

class VclSimpleEvent;
class VclWindowEvent;

namespace svx {

class FrameSelector;

namespace a11y {

typedef ::cppu::ImplHelper1<css::accessibility::XAccessible> OAccessibleHelper_Base;

class AccFrameSelector final :
    public ::cppu::WeakImplHelper<
                css::accessibility::XAccessible,
                css::accessibility::XAccessibleContext,
                css::accessibility::XAccessibleComponent,
                css::accessibility::XAccessibleEventBroadcaster,
                css::lang::XServiceInfo
                >
class AccFrameSelector final : public ::comphelper::OAccessibleComponentHelper,
                               public OAccessibleHelper_Base
{
public:
    explicit            AccFrameSelector( FrameSelector& rFrameSel, FrameBorderType eBorder );

    explicit            AccFrameSelector(FrameSelector& rFrameSel);
    virtual             ~AccFrameSelector() override;

    //XAccessible
    virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) override;
    DECLARE_XINTERFACE( )
    DECLARE_XTYPEPROVIDER( )

    //XAccessibleComponent
    virtual void SAL_CALL grabFocus(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;

    //XAccessibleContext
    virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) override;
    virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) override;
    virtual sal_Int16 SAL_CALL getAccessibleRole(  ) override;
    virtual OUString SAL_CALL getAccessibleDescription(  ) override;
    virtual OUString SAL_CALL getAccessibleName(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) override;
    virtual css::lang::Locale SAL_CALL getLocale(  ) override;

    //XAccessibleComponent
    virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
    virtual css::awt::Rectangle SAL_CALL getBounds(  ) override;
    virtual css::awt::Point SAL_CALL getLocation(  ) override;
    virtual css::awt::Point SAL_CALL getLocationOnScreen(  ) override;
    virtual css::awt::Size SAL_CALL getSize(  ) override;
    virtual void SAL_CALL grabFocus(  ) override;
    //XAccessible
    virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) override;

    virtual sal_Int32 SAL_CALL getForeground(  ) override;
    virtual sal_Int32 SAL_CALL getBackground(  ) override;

    // XAccessibleEventBroadcaster
    virtual void SAL_CALL addAccessibleEventListener ( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener) override;
    virtual void SAL_CALL removeAccessibleEventListener ( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener) override;

    //XServiceInfo
    virtual OUString SAL_CALL getImplementationName(  ) override;
    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) override;
    void NotifyAccessibleEvent(const sal_Int16 _nEventId, const css::uno::Any& _rOldValue, const css::uno::Any& _rNewValue)
    {
        ::comphelper::OAccessibleComponentHelper::NotifyAccessibleEvent(_nEventId, _rOldValue, _rNewValue);
    }

    void    Invalidate();
    void    NotifyFocusListeners(bool bGetFocus);
    void    NotifyAccessibleEvent( const sal_Int16 _nEventId, const css::uno::Any& _rOldValue, const css::uno::Any& _rNewValue );

private:
    DECL_LINK( WindowEventListener, VclWindowEvent&, void );
    // OCommonAccessibleComponent
    /// implements the calculation of the bounding rectangle
    virtual css::awt::Rectangle implGetBounds(  ) override;

    /// @throws css::uno::RuntimeException
    void                IsValid();
    void                RemoveFrameSelEventListener();

    VclPtr<FrameSelector>  mpFrameSel;
    ::osl::Mutex        maFocusMutex;
    ::osl::Mutex        maPropertyMutex;
    FrameSelector*      mpFrameSel;
};

class AccFrameSelectorChild final : public ::comphelper::OAccessibleComponentHelper,
                                    public OAccessibleHelper_Base
{
public:
    explicit            AccFrameSelectorChild( FrameSelector& rFrameSel, FrameBorderType eBorder );

    virtual             ~AccFrameSelectorChild() override;

    DECLARE_XINTERFACE( )
    DECLARE_XTYPEPROVIDER( )

    //XAccessibleComponent
    virtual void SAL_CALL grabFocus(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;

    //XAccessibleContext
    virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override;
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) override;
    virtual sal_Int16 SAL_CALL getAccessibleRole(  ) override;
    virtual OUString SAL_CALL getAccessibleDescription(  ) override;
    virtual OUString SAL_CALL getAccessibleName(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) override;
    virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) override;

    //XAccessible
    virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) override;

    virtual sal_Int32 SAL_CALL getForeground(  ) override;
    virtual sal_Int32 SAL_CALL getBackground(  ) override;

    void    Invalidate();

private:
    // OCommonAccessibleComponent
    /// implements the calculation of the bounding rectangle
    virtual css::awt::Rectangle implGetBounds(  ) override;

    /// @throws css::uno::RuntimeException
    void                IsValid();

    FrameSelector*      mpFrameSel;

    FrameBorderType     meBorder;

    ::comphelper::OInterfaceContainerHelper2 maFocusListeners;
    ::comphelper::OInterfaceContainerHelper2 maPropertyListeners;

    ::comphelper::AccessibleEventNotifier::TClientId    mnClientId;
};


diff --git a/svx/source/inc/frmselimpl.hxx b/svx/source/inc/frmselimpl.hxx
index 21c35dd..29791d7 100644
--- a/svx/source/inc/frmselimpl.hxx
+++ b/svx/source/inc/frmselimpl.hxx
@@ -30,6 +30,7 @@ namespace svx {

namespace a11y {
    class AccFrameSelector;
    class AccFrameSelectorChild;
}

class FrameBorder
@@ -138,8 +139,7 @@ struct FrameSelectorImpl
    bool                mbAutoSelect;   /// true = Auto select a frame border, if focus reaches control.
    bool                mbHCMode;       /// true = High contrast mode.

    rtl::Reference<a11y::AccFrameSelector> mxAccess;   /// Pointer to accessibility object of the control.
    std::vector<rtl::Reference<a11y::AccFrameSelector>>
    std::vector<rtl::Reference<a11y::AccFrameSelectorChild>>
                        maChildVec;     /// Pointers to accessibility objects for frame borders.
    explicit            FrameSelectorImpl( FrameSelector& rFrameSel );
                        ~FrameSelectorImpl();
@@ -185,7 +185,7 @@ struct FrameSelectorImpl
    void                CopyVirDevToControl(vcl::RenderContext& rRenderContext);

    /** Draws tracking rectangles for all selected frame borders. */
    void                DrawAllTrackingRects();
    void                DrawAllTrackingRects(vcl::RenderContext& rRenderContext);

    /** Converts a mouse position to the virtual device position. */
    Point               GetDevPosFromMousePos( const Point& rMousePos ) const;
diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index a0bcc10..62a0015 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -1743,6 +1743,15 @@ bool SvxColorWindow::IsNoSelection() const
    return !mpButtonAutoColor->IsVisible() && !mpButtonNoneColor->IsVisible();
}

bool ColorWindow::IsNoSelection() const
{
    if (!mxColorSet->IsNoSelection())
        return false;
    if (!mxRecentColorSet->IsNoSelection())
        return false;
    return !mxButtonAutoColor->get_visible() && !mxButtonNoneColor->get_visible();
}

void SvxColorWindow::statusChanged( const css::frame::FeatureStateEvent& rEvent )
{
    if (rEvent.FeatureURL.Complete == ".uno:ColorTableState")
@@ -3840,7 +3849,7 @@ void ColorListBox::ShowPreview(const NamedColor &rColor)
    xDevice->SetLineColor(rStyleSettings.GetDisableColor());
    xDevice->DrawRect(aRect);

    m_xButton->set_image(*xDevice);
    m_xButton->set_image(xDevice.get());
    m_xButton->set_label(rColor.second);
}

diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 43eb8d5..a65a973 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -982,11 +982,16 @@ public:
        m_xButton->SetText(rText);
    }

    virtual void set_image(VirtualDevice& rDevice) override
    virtual void set_image(VirtualDevice* pDevice) override
    {
        BitmapEx aBitmap(rDevice.GetBitmap(Point(0, 0), rDevice.GetOutputSize()));
        m_xButton->SetImageAlign(ImageAlign::Left);
        m_xButton->SetModeImage(Image(aBitmap));
        if (pDevice)
        {
            BitmapEx aBitmap(pDevice->GetBitmap(Point(0, 0), pDevice->GetOutputSize()));
            m_xButton->SetModeImage(Image(aBitmap));
        }
        else
            m_xButton->SetModeImage(Image());
    }

    virtual OUString get_label() const override
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 39acdd3..d81565a 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -823,7 +823,6 @@ void PushButton::ImplDrawPushButtonContent(OutputDevice* pDev, DrawFlags nDrawFl
    const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
    tools::Rectangle               aInRect = rRect;
    Color                   aColor;
    OUString                aText = PushButton::GetText(); // PushButton:: because of MoreButton
    DrawTextFlags           nTextStyle = ImplGetTextStyle( nDrawFlags );
    DrawSymbolFlags         nStyle;

@@ -872,7 +871,7 @@ void PushButton::ImplDrawPushButtonContent(OutputDevice* pDev, DrawFlags nDrawFl
    {
        long nSeparatorX = 0;
        tools::Rectangle aSymbolRect = aInRect;
        if ( !aText.isEmpty() && ! (ImplGetButtonState() & DrawButtonFlags::NoText) )
        if (!(ImplGetButtonState() & DrawButtonFlags::NoText))
        {
            // calculate symbol size
            long nSymbolSize    = pDev->GetTextHeight() / 2 + 1;
diff --git a/vcl/source/outdev/rect.cxx b/vcl/source/outdev/rect.cxx
index c9f0e7c..049612c 100644
--- a/vcl/source/outdev/rect.cxx
+++ b/vcl/source/outdev/rect.cxx
@@ -159,8 +159,8 @@ void OutputDevice::Invert( const tools::Rectangle& rRect, InvertFlags nFlags )
        nSalFlags |= SalInvert::Highlight;
    if ( nFlags & InvertFlags::N50 )
        nSalFlags |= SalInvert::N50;
    if ( nFlags == InvertFlags(0xffff) ) // vcldemo trackframe test
        nSalFlags = SalInvert::TrackFrame;
    if ( nFlags & InvertFlags::TrackFrame )
        nSalFlags |= SalInvert::TrackFrame;
    mpGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), nSalFlags, this );
}

@@ -195,6 +195,8 @@ void OutputDevice::Invert( const tools::Polygon& rPoly, InvertFlags nFlags )
        nSalFlags |= SalInvert::Highlight;
    if ( nFlags & InvertFlags::N50 )
        nSalFlags |= SalInvert::N50;
    if ( nFlags & InvertFlags::TrackFrame )
        nSalFlags |= SalInvert::TrackFrame;
    const SalPoint* pPtAry = reinterpret_cast<const SalPoint*>(aPoly.GetConstPointAry());
    mpGraphics->Invert( nPoints, pPtAry, nSalFlags, this );
}
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 458b836..6fd7795 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -1804,7 +1804,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
    else if (name == "GtkDrawingArea")
    {
        OUString sBorder = BuilderUtils::extractCustomProperty(rMap);
        xWindow = VclPtr<VclDrawingArea>::Create(pParent, sBorder.isEmpty() ? 0 : WB_BORDER);
        xWindow = VclPtr<VclDrawingArea>::Create(pParent, sBorder.isEmpty() ? WB_TABSTOP : WB_BORDER | WB_TABSTOP);
    }
    else if (name == "GtkTextView")
    {
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 039f4a7..eaf7388 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2749,11 +2749,14 @@ public:
        ::set_label(m_pButton, rText);
    }

    virtual void set_image(VirtualDevice& rDevice) override
    virtual void set_image(VirtualDevice* pDevice) override
    {
        gtk_button_set_always_show_image(m_pButton, true);
        gtk_button_set_image_position(m_pButton, GTK_POS_LEFT);
        gtk_button_set_image(m_pButton, gtk_image_new_from_surface(get_underlying_cairo_surface(rDevice)));
        if (pDevice)
            gtk_button_set_image(m_pButton, gtk_image_new_from_surface(get_underlying_cairo_surface(*pDevice)));
        else
            gtk_button_set_image(m_pButton, nullptr);
    }

    virtual OUString get_label() const override
@@ -3097,11 +3100,11 @@ public:
        ::set_label(m_pLabel, rText);
    }

    virtual void set_image(VirtualDevice& rDevice) override
    virtual void set_image(VirtualDevice* pDevice) override
    {
        if (!m_pImage)
        {
            m_pImage = GTK_IMAGE(gtk_image_new_from_surface(get_underlying_cairo_surface(rDevice)));
            m_pImage = GTK_IMAGE(gtk_image_new());
            GtkStyleContext *pContext = gtk_widget_get_style_context(GTK_WIDGET(m_pMenuButton));
            gint nImageSpacing(0);
            gtk_style_context_get_style(pContext, "image-spacing", &nImageSpacing, nullptr);
@@ -3109,8 +3112,10 @@ public:
            gtk_box_reorder_child(m_pBox, GTK_WIDGET(m_pImage), 0);
            gtk_widget_show(GTK_WIDGET(m_pImage));
        }
        if (pDevice)
            gtk_image_set_from_surface(m_pImage, get_underlying_cairo_surface(*pDevice));
        else
            gtk_image_set_from_surface(m_pImage, get_underlying_cairo_surface(rDevice));
            gtk_image_set_from_surface(m_pImage, nullptr);
    }

    virtual void set_item_active(const OString& rIdent, bool bActive) override
diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index f36009e..4a812d3 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -768,7 +768,7 @@ public:
                doInvert(rDev, aRegions[0], InvertFlags::NONE);
                doInvert(rDev, aRegions[1], InvertFlags::N50);
                doInvert(rDev, aRegions[2], InvertFlags::Highlight);
                doInvert(rDev, aRegions[3], InvertFlags(0xffff));
                doInvert(rDev, aRegions[3], InvertFlags::TrackFrame);
            }
        }
    };