weld ScSortDlg, ScTabPageSortOptions and ScTabPageSortFields

Change-Id: I103e5e3670f8c95c1f480ce0c36e08c3de74e900
Reviewed-on: https://gerrit.libreoffice.org/54541
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/sfx2/tabdlg.hxx b/include/sfx2/tabdlg.hxx
index 51e30e4..9da02d5 100644
--- a/include/sfx2/tabdlg.hxx
+++ b/include/sfx2/tabdlg.hxx
@@ -244,6 +244,7 @@ private:
    std::unique_ptr<SfxItemSet>           m_pOutSet;
    std::unique_ptr< TabDlg_Impl >        m_pImpl;
    sal_uInt16*         m_pRanges;
    OString             m_sAppPageId;

    DECL_DLLPRIVATE_LINK(ActivatePageHdl, const OString&, void);
    DECL_DLLPRIVATE_LINK(DeactivatePageHdl, const OString&, bool);
diff --git a/include/svx/langbox.hxx b/include/svx/langbox.hxx
index 3b91701..848d93a 100644
--- a/include/svx/langbox.hxx
+++ b/include/svx/langbox.hxx
@@ -157,7 +157,6 @@ private:
    bool m_bLangNoneIsLangAll;

    SVX_DLLPRIVATE int ImplTypeToPos(LanguageType eType) const;
    SVX_DLLPRIVATE void InsertLanguage(const LanguageType nLangType);
    SVX_DLLPRIVATE void ImplClear();
    DECL_LINK(ChangeHdl, weld::ComboBoxText&, void);
public:
@@ -165,6 +164,7 @@ public:
    void            SetLanguageList( SvxLanguageListFlags nLangList,
                            bool bHasLangNone, bool bLangNoneIsLangAll = false );
    void            AddLanguages( const std::vector< LanguageType >& rLanguageTypes, SvxLanguageListFlags nLangList );
    void            InsertLanguage(const LanguageType nLangType);
    void            SelectLanguage( const LanguageType eLangType );
    LanguageType    GetSelectedLanguage() const;
    void            SelectEntryPos(int nPos) { m_xControl->set_active(nPos); }
diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index 31ff24e..6423d12 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -507,10 +507,13 @@ class VCL_DLLPUBLIC VclViewport : public VclBin
public:
    VclViewport(vcl::Window *pParent)
        : VclBin(pParent, WB_HIDE | WB_CLIPCHILDREN)
        , m_bInitialAllocation(true)
    {
    }
protected:
    virtual void setAllocation(const Size &rAllocation) override;
private:
    bool m_bInitialAllocation;
};

//Enforces that its children are always the same size as itself.
diff --git a/include/vcl/scrbar.hxx b/include/vcl/scrbar.hxx
index db4d2ee..5fadfb5 100644
--- a/include/vcl/scrbar.hxx
+++ b/include/vcl/scrbar.hxx
@@ -133,6 +133,7 @@ public:
    ScrollType      GetType() const { return meScrollType; }

    void            SetScrollHdl( const Link<ScrollBar*,void>& rLink ) { maScrollHdl = rLink; }
    const Link<ScrollBar*,void>&   GetScrollHdl() const { return maScrollHdl; }
    void            SetEndScrollHdl( const Link<ScrollBar*,void>& rLink ) { maEndScrollHdl = rLink; }
    const Link<ScrollBar*,void>&   GetEndScrollHdl() const { return maEndScrollHdl; }

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 423a6592..ace7173 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -120,6 +120,8 @@ public:
        = 0;
    virtual int vadjustment_get_value() const = 0;
    virtual void vadjustment_set_value(int value) = 0;
    virtual int vadjustment_get_upper() const = 0;
    virtual void vadjustment_set_upper(int upper) = 0;
    void connect_vadjustment_changed(const Link<ScrolledWindow&, void>& rLink)
    {
        m_aVChangeHdl = rLink;
diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx
index b1b33b94..7d76402 100644
--- a/sc/inc/scabstdlg.hxx
+++ b/sc/inc/scabstdlg.hxx
@@ -540,7 +540,7 @@ public:
    virtual VclPtr<SfxAbstractTabDialog> CreateScParagraphDlg(vcl::Window* pParent,
        const SfxItemSet* pAttr) = 0;

    virtual VclPtr<SfxAbstractTabDialog> CreateScSortDlg(vcl::Window* pParent, const SfxItemSet* pArgSet) = 0;
    virtual VclPtr<SfxAbstractTabDialog> CreateScSortDlg(weld::Window* pParent, const SfxItemSet* pArgSet) = 0;

    // for tabpage
    virtual CreateTabPage                GetTabPageCreatorFunc( sal_uInt16 nId ) = 0;
diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx
index 2d00bc0..b4ca85c 100644
--- a/sc/source/ui/attrdlg/scdlgfact.cxx
+++ b/sc/source/ui/attrdlg/scdlgfact.cxx
@@ -683,6 +683,37 @@ bool AbstractScTextImportOptionsDlg_Impl::IsDateConversionSet() const
    return pDlg->isDateConversionSet();
}

short ScAbstractTabController_Impl::Execute()
{
    return m_xDlg->execute();
}

void ScAbstractTabController_Impl::SetCurPageId( const OString &rName )
{
    m_xDlg->SetCurPageId( rName );
}

const SfxItemSet* ScAbstractTabController_Impl::GetOutputItemSet() const
{
    return m_xDlg->GetOutputItemSet();
}

const sal_uInt16* ScAbstractTabController_Impl::GetInputRanges(const SfxItemPool& pItem )
{
    return m_xDlg->GetInputRanges( pItem );
}

void ScAbstractTabController_Impl::SetInputSet( const SfxItemSet* pInSet )
{
     m_xDlg->SetInputSet( pInSet );
}

//From class Window.
void ScAbstractTabController_Impl::SetText( const OUString& rStr )
{
    m_xDlg->set_title(rStr);
}

// =========================Factories  for createdialog ===================
VclPtr<AbstractScImportAsciiDlg> ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg ( const OUString& aDatName,
                                                    SvStream* pInStream, ScImportAsciiCall eCall )
@@ -1015,10 +1046,9 @@ VclPtr<SfxAbstractTabDialog> ScAbstractDialogFactory_Impl::CreateScParagraphDlg(
    return VclPtr<ScAbstractTabDialog_Impl>::Create(pDlg);
}

VclPtr<SfxAbstractTabDialog> ScAbstractDialogFactory_Impl::CreateScSortDlg(vcl::Window* pParent, const SfxItemSet* pArgSet)
VclPtr<SfxAbstractTabDialog> ScAbstractDialogFactory_Impl::CreateScSortDlg(weld::Window* pParent, const SfxItemSet* pArgSet)
{
    VclPtr<SfxTabDialog> pDlg = VclPtr<ScSortDlg>::Create( pParent, pArgSet );
    return VclPtr<ScAbstractTabDialog_Impl>::Create( pDlg );
    return VclPtr<ScAbstractTabController_Impl>::Create(new ScSortDlg(pParent, pArgSet));
}

//------------------ Factories for TabPages--------------------
diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx
index 50f206c..d419758 100644
--- a/sc/source/ui/attrdlg/scdlgfact.hxx
+++ b/sc/source/ui/attrdlg/scdlgfact.hxx
@@ -507,6 +507,24 @@ class ScAbstractTabDialog_Impl : public SfxAbstractTabDialog
    virtual void        SetText( const OUString& rStr ) override;
};

class ScAbstractTabController_Impl : public SfxAbstractTabDialog
{
protected:
    std::unique_ptr<SfxTabDialogController> m_xDlg;
public:
    explicit ScAbstractTabController_Impl(SfxTabDialogController* p)
        : m_xDlg(p)
    {
    }
    virtual short Execute() override;
    virtual void                SetCurPageId( const OString &rName ) override;
    virtual const SfxItemSet*   GetOutputItemSet() const override;
    virtual const sal_uInt16*   GetInputRanges( const SfxItemPool& pItem ) override;
    virtual void                SetInputSet( const SfxItemSet* pInSet ) override;
        //From class Window.
    virtual void        SetText( const OUString& rStr ) override;
};

//AbstractDialogFactory_Impl implementations
class ScAbstractDialogFactory_Impl : public ScAbstractDialogFactory
{
@@ -656,7 +674,7 @@ public:
    virtual VclPtr<SfxAbstractTabDialog> CreateScParagraphDlg(vcl::Window* pParent,
        const SfxItemSet* pAttr) override;

    virtual VclPtr<SfxAbstractTabDialog> CreateScSortDlg(vcl::Window* pParent, const SfxItemSet* pArgSet) override;
    virtual VclPtr<SfxAbstractTabDialog> CreateScSortDlg(weld::Window* pParent, const SfxItemSet* pArgSet) override;

    // For TabPage
    virtual CreateTabPage                GetTabPageCreatorFunc( sal_uInt16 nId ) override;
diff --git a/sc/source/ui/dbgui/sortdlg.cxx b/sc/source/ui/dbgui/sortdlg.cxx
index 53feb2d..92a996e 100644
--- a/sc/source/ui/dbgui/sortdlg.cxx
+++ b/sc/source/ui/dbgui/sortdlg.cxx
@@ -22,8 +22,8 @@
#include <tpsort.hxx>
#include <sortdlg.hxx>

ScSortDlg::ScSortDlg(vcl::Window* pParent, const SfxItemSet* pArgSet)
    : SfxTabDialog(pParent, "SortDialog", "modules/scalc/ui/sortdialog.ui", pArgSet)
ScSortDlg::ScSortDlg(weld::Window* pParent, const SfxItemSet* pArgSet)
    : SfxTabDialogController(pParent, "modules/scalc/ui/sortdialog.ui", "SortDialog", pArgSet)
    , bIsHeaders(false)
    , bIsByRows(false)
{
diff --git a/sc/source/ui/dbgui/sortkeydlg.cxx b/sc/source/ui/dbgui/sortkeydlg.cxx
index 5bfc125..04b953c 100644
--- a/sc/source/ui/dbgui/sortkeydlg.cxx
+++ b/sc/source/ui/dbgui/sortkeydlg.cxx
@@ -12,54 +12,39 @@
#include <sortdlg.hxx>
#include <vcl/layout.hxx>

ScSortKeyItem::ScSortKeyItem(vcl::Window* pParent)
ScSortKeyItem::ScSortKeyItem(weld::Container* pParent)
    : m_xBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/sortkey.ui"))
    , m_xFrame(m_xBuilder->weld_frame("SortKeyFrame", true))
    , m_xLbSort(m_xBuilder->weld_combo_box_text("sortlb"))
    , m_xBtnUp(m_xBuilder->weld_radio_button("up"))
    , m_xBtnDown(m_xBuilder->weld_radio_button("down"))
{
    m_pUIBuilder.reset(new VclBuilder(pParent, getUIRootDir(), "modules/scalc/ui/sortkey.ui"));

    get(m_pFrame, "SortKeyFrame");
    get(m_pFlSort, "sortft");
    get(m_pLbSort, "sortlb");
    get(m_pBtnUp, "up");
    get(m_pBtnDown, "down");
}

long ScSortKeyItem::getItemHeight() const
{
    return VclContainer::getLayoutRequisition(*m_pFrame).Height();
    return m_xFrame->get_preferred_size().Height();
}

void ScSortKeyItem::DisableField()
{
    m_pFrame->Disable();
    m_xFrame->set_sensitive(false);
}

void ScSortKeyItem::EnableField()
{
    m_pFrame->Enable();
    m_xFrame->set_sensitive(true);
}

ScSortKeyWindow::ScSortKeyWindow(SfxTabPage* pParent, ScSortKeyItems& rSortKeyItems)
    : mrSortKeyItems(rSortKeyItems)
ScSortKeyWindow::ScSortKeyWindow(weld::Container* pBox)
    : m_pBox(pBox)
{
    pParent->get(m_pBox, "SortKeyWindow");
    if (!mrSortKeyItems.empty())
        nItemHeight = mrSortKeyItems.front()->getItemHeight();
    else
    {
        ScSortKeyItem aTemp(m_pBox);
        nItemHeight = aTemp.getItemHeight();
    }
    ScSortKeyItem aTemp(m_pBox);
    m_nItemHeight = aTemp.getItemHeight();
}

ScSortKeyWindow::~ScSortKeyWindow()
{
    dispose();
}

void ScSortKeyWindow::dispose()
{
    m_pBox.disposeAndClear();
    mrSortKeyItems.clear();
}

void ScSortKeyWindow::AddSortKey( sal_uInt16 nItemNumber )
@@ -67,76 +52,11 @@ void ScSortKeyWindow::AddSortKey( sal_uInt16 nItemNumber )
    ScSortKeyItem* pSortKeyItem = new ScSortKeyItem(m_pBox);

    // Set Sort key number
    OUString aLine = pSortKeyItem->m_pFlSort->GetText() +
    OUString aLine = pSortKeyItem->m_xFrame->get_label() +
                     OUString::number( nItemNumber );
    pSortKeyItem->m_pFlSort->SetText( aLine );
    pSortKeyItem->m_xFrame->set_label(aLine);

    mrSortKeyItems.push_back(std::unique_ptr<ScSortKeyItem>(pSortKeyItem));
}

void ScSortKeyWindow::DoScroll(sal_Int32 nNewPos)
{
    m_pBox->SetPosPixel(Point(0, nNewPos));
}

ScSortKeyCtrl::ScSortKeyCtrl(SfxTabPage* pParent, ScSortKeyItems& rItems)
    : m_aSortWin(pParent, rItems)
    , m_rScrolledWindow(*pParent->get<VclScrolledWindow>("SortCriteriaPage"))
    , m_rVertScroll(m_rScrolledWindow.getVertScrollBar())
{
    m_rScrolledWindow.setUserManagedScrolling(true);

    m_rVertScroll.EnableDrag();
    m_rVertScroll.Show(m_rScrolledWindow.GetStyle() & WB_VSCROLL);

    m_rVertScroll.SetRangeMin( 0 );
    m_rVertScroll.SetVisibleSize( 0xFFFF );

    Link<ScrollBar*,void> aScrollLink = LINK( this, ScSortKeyCtrl, ScrollHdl );
    m_rVertScroll.SetScrollHdl( aScrollLink );
}

void ScSortKeyCtrl::dispose()
{
    m_aSortWin.dispose();
}

void ScSortKeyCtrl::checkAutoVScroll()
{
    WinBits nBits = m_rScrolledWindow.GetStyle();
    if (nBits & WB_VSCROLL)
        return;
    if (nBits & WB_AUTOVSCROLL)
    {
        bool bShow = m_rVertScroll.GetRangeMax() > m_rVertScroll.GetVisibleSize();
        if (bShow != m_rVertScroll.IsVisible())
            m_rVertScroll.Show(bShow);
    }
}

void ScSortKeyCtrl::setScrollRange()
{
    sal_Int32 nScrollOffset = m_aSortWin.GetItemHeight();
    sal_Int32 nVisibleItems = m_rScrolledWindow.getVisibleChildSize().Height() / nScrollOffset;
    m_rVertScroll.SetPageSize( nVisibleItems - 1 );
    m_rVertScroll.SetVisibleSize( nVisibleItems );
    m_rVertScroll.Scroll();
    checkAutoVScroll();
}

IMPL_LINK( ScSortKeyCtrl, ScrollHdl, ScrollBar*, pScrollBar, void )
{
    sal_Int32 nOffset = m_aSortWin.GetItemHeight();
    nOffset *= pScrollBar->GetThumbPos();
    m_aSortWin.DoScroll( -nOffset );
}

void ScSortKeyCtrl::AddSortKey( sal_uInt16 nItem )
{
    m_rVertScroll.SetRangeMax( nItem );
    m_rVertScroll.DoScroll( nItem );
    m_aSortWin.AddSortKey( nItem );
    checkAutoVScroll();
    m_aSortKeyItems.push_back(std::unique_ptr<ScSortKeyItem>(pSortKeyItem));
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index 9f83cb5..6009f8b 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -68,10 +68,8 @@ using namespace com::sun::star;

// Sort Criteria Tab page

ScTabPageSortFields::ScTabPageSortFields(vcl::Window* pParent,
                                          const SfxItemSet& rArgSet)
    : SfxTabPage(pParent, "SortCriteriaPage",
        "modules/scalc/ui/sortcriteriapage.ui", &rArgSet)
ScTabPageSortFields::ScTabPageSortFields(TabPageParent pParent, const SfxItemSet& rArgSet)
    : SfxTabPage(pParent, "modules/scalc/ui/sortcriteriapage.ui", "SortCriteriaPage", &rArgSet)
    ,

        aStrUndefined   ( ScResId( SCSTR_UNDEFINED ) ),
@@ -79,7 +77,6 @@ ScTabPageSortFields::ScTabPageSortFields(vcl::Window* pParent,
        aStrRow         ( ScResId( SCSTR_ROW ) ),

        nWhichSort      ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
        pDlg            ( static_cast<ScSortDlg*>(GetParentDialog()) ),
        pViewData       ( nullptr ),
        aSortData       ( static_cast<const ScSortItem&>(
                           rArgSet.Get( nWhichSort )).
@@ -87,10 +84,17 @@ ScTabPageSortFields::ScTabPageSortFields(vcl::Window* pParent,
        nFieldCount     ( 0 ),
        nSortKeyCount   ( DEFSORT ),
        bHasHeader      ( false ),
        bSortByRows     ( false ),
        maSortKeyCtrl   ( this, maSortKeyItems )
        bSortByRows     ( false )

    , m_xScrolledWindow(m_xBuilder->weld_scrolled_window("SortCriteriaPage"))
    , m_xBox(m_xBuilder->weld_container("SortKeyWindow"))
    , m_aSortWin(m_xBox.get())
{
    Init();

    m_aIdle.SetInvokeHandler(LINK(this, ScTabPageSortFields, ScrollToEndHdl));
    m_aIdle.SetDebugName("ScTabPageSortFields Scroll To End Idle");

    SetExchangeSupport();
}

@@ -101,30 +105,12 @@ ScTabPageSortFields::~ScTabPageSortFields()

void ScTabPageSortFields::dispose()
{
    pDlg.clear();
    maSortKeyItems.clear();
    maSortKeyCtrl.dispose();
    m_aSortWin.m_aSortKeyItems.clear();
    m_xBox.reset();
    m_xScrolledWindow.reset();
    SfxTabPage::dispose();
}

void ScTabPageSortFields::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
{
    SfxTabPage::SetPosSizePixel(rAllocPos, rAllocation);
    maSortKeyCtrl.setScrollRange();
}

void ScTabPageSortFields::SetSizePixel(const Size& rAllocation)
{
    SfxTabPage::SetSizePixel(rAllocation);
    maSortKeyCtrl.setScrollRange();
}

void ScTabPageSortFields::SetPosPixel(const Point& rAllocPos)
{
    SfxTabPage::SetPosPixel(rAllocPos);
    maSortKeyCtrl.setScrollRange();
}

void ScTabPageSortFields::Init()
{
    const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
@@ -138,15 +124,14 @@ void ScTabPageSortFields::Init()
    // Create three sort key dialogs by default
    for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
    {
        maSortKeyCtrl.AddSortKey(i+1);
        maSortKeyItems[i]->m_pLbSort->SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
        AddSortKey(i+1);
        m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed(LINK(this, ScTabPageSortFields, SelectHdl));
    }
}

VclPtr<SfxTabPage> ScTabPageSortFields::Create( TabPageParent pParent,
                                                const SfxItemSet*  rArgSet )
VclPtr<SfxTabPage> ScTabPageSortFields::Create(TabPageParent pParent, const SfxItemSet* pArgSet)
{
    return VclPtr<ScTabPageSortFields>::Create( pParent.pParent, *rArgSet );
    return VclPtr<ScTabPageSortFields>::Create(pParent, *pArgSet);
}

void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
@@ -154,7 +139,7 @@ void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
    bSortByRows = aSortData.bByRow;
    bHasHeader  = aSortData.bHasHeader;

    if ( maSortKeyItems[0]->m_pLbSort->GetEntryCount() == 0 )
    if (m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->get_count() == 0)
        FillFieldLists(0);

    // ListBox selection:
@@ -163,8 +148,8 @@ void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
        // Make sure that the all sort keys are reset
        for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
        {
            maSortKeyCtrl.AddSortKey(i+1);
            maSortKeyItems[i]->m_pLbSort->SetSelectHdl( LINK( this,
            AddSortKey(i+1);
            m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed( LINK( this,
                                 ScTabPageSortFields, SelectHdl ) );
        }
        nSortKeyCount = aSortData.GetSortKeyCount();
@@ -174,26 +159,26 @@ void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
        {
            if (aSortData.maKeyState[i].bDoSort )
            {
                maSortKeyItems[i]->m_pLbSort->SelectEntryPos( GetFieldSelPos(
                m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active( GetFieldSelPos(
                                    aSortData.maKeyState[i].nField ) );
                (aSortData.maKeyState[i].bAscending)
                    ? maSortKeyItems[i]->m_pBtnUp->Check()
                    : maSortKeyItems[i]->m_pBtnDown->Check();
                    ? m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true)
                    : m_aSortWin.m_aSortKeyItems[i]->m_xBtnDown->set_active(true);
            }
            else
            {
                maSortKeyItems[i]->m_pLbSort->SelectEntryPos( 0 ); // Select none
                maSortKeyItems[i]->m_pBtnUp->Check();
                m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0); // Select none
                m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
            }
        }

        // Enable or disable field depending on preceding Listbox selection
        maSortKeyItems[0]->EnableField();
        m_aSortWin.m_aSortKeyItems[0]->EnableField();
        for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
            if ( maSortKeyItems[i - 1]->m_pLbSort->GetSelectedEntryPos() == 0 )
                maSortKeyItems[i]->DisableField();
            if ( m_aSortWin.m_aSortKeyItems[i - 1]->m_xLbSort->get_active() == 0 )
                m_aSortWin.m_aSortKeyItems[i]->DisableField();
            else
                maSortKeyItems[i]->EnableField();
                m_aSortWin.m_aSortKeyItems[i]->EnableField();
    }
    else
    {
@@ -206,27 +191,27 @@ void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )

        sal_uInt16  nSort1Pos = nCol - aSortData.nCol1+1;

        maSortKeyItems[0]->m_pLbSort->SelectEntryPos( nSort1Pos );
        m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->set_active(nSort1Pos);
        for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
            maSortKeyItems[i]->m_pLbSort->SelectEntryPos( 0 );
            m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0);

        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
            maSortKeyItems[i]->m_pBtnUp->Check();
            m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);

        maSortKeyItems[0]->EnableField();
        maSortKeyItems[1]->EnableField();
        m_aSortWin.m_aSortKeyItems[0]->EnableField();
        m_aSortWin.m_aSortKeyItems[1]->EnableField();
        for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
            maSortKeyItems[i]->DisableField();
            m_aSortWin.m_aSortKeyItems[i]->DisableField();
    }

    if ( pDlg )
    if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
    {
        pDlg->SetByRows ( bSortByRows );
        pDlg->SetHeaders( bHasHeader );
    }

    // Make sure that there is always a last undefined sort key
    if ( maSortKeyItems[nSortKeyCount - 1]->m_pLbSort->GetSelectedEntryPos() > 0 )
    if (m_aSortWin.m_aSortKeyItems[nSortKeyCount - 1]->m_xLbSort->get_active() > 0)
        SetLastSortKey( nSortKeyCount );
}

@@ -234,6 +219,7 @@ bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )
{
    ScSortParam aNewSortData = aSortData;

    ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
    if (pDlg)
    {
        const SfxItemSet* pExample = pDlg->GetExampleSet();
@@ -249,9 +235,8 @@ bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )

    for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
    {
        nSortPos.push_back( maSortKeyItems[i]->m_pLbSort->GetSelectedEntryPos() );

        if ( nSortPos[i] == LISTBOX_ENTRY_NOTFOUND ) nSortPos[i] = 0;
        nSortPos.push_back(m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active());
        if (nSortPos[i] == -1) nSortPos[i] = 0;
    }

    if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
@@ -277,7 +262,7 @@ bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )
        }

        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
            aNewSortData.maKeyState[i].bAscending = maSortKeyItems[i]->m_pBtnUp->IsChecked();
            aNewSortData.maKeyState[i].bAscending = m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->get_active();

        // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
    }
@@ -297,28 +282,28 @@ void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
{
    // Refresh local copy with shared data
    aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
    if ( pDlg )
    if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
    {
        if ( bHasHeader  != pDlg->GetHeaders()
             || bSortByRows != pDlg->GetByRows() )
        {
            std::vector<sal_uInt16> nCurSel;
            for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
                nCurSel.push_back( maSortKeyItems[i]->m_pLbSort->GetSelectedEntryPos() );
                nCurSel.push_back( m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active() );

            bHasHeader  = pDlg->GetHeaders();
            bSortByRows = pDlg->GetByRows();
            FillFieldLists(0);

            for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
                maSortKeyItems[i]->m_pLbSort->SelectEntryPos( nCurSel[i] );
                m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(nCurSel[i]);
        }
    }
}

DeactivateRC ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
{
    if ( pDlg )
    if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
    {
        if ( bHasHeader != pDlg->GetHeaders() )
            pDlg->SetHeaders( bHasHeader );
@@ -343,8 +328,8 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
        {
            for ( sal_uInt16 i=nStartField; i<nSortKeyCount; i++ )
            {
                maSortKeyItems[i]->m_pLbSort->Clear();
                maSortKeyItems[i]->m_pLbSort->InsertEntry( aStrUndefined, 0 );
                m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->clear();
                m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->append_text(aStrUndefined);
            }

            SCCOL   nFirstSortCol   = aSortData.nCol1;
@@ -370,7 +355,7 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
                    nFieldArr.push_back( col );

                    for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
                        maSortKeyItems[j]->m_pLbSort->InsertEntry( aFieldName, i );
                        m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);

                    i++;
                }
@@ -391,7 +376,7 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
                    nFieldArr.push_back( row );

                    for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
                        maSortKeyItems[j]->m_pLbSort->InsertEntry( aFieldName, i );
                        m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);

                    i++;
                }
@@ -426,69 +411,78 @@ void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )

    // Add Sort Key Item
    ++nSortKeyCount;
    maSortKeyCtrl.AddSortKey( nSortKeyCount );
    maSortKeyItems[nItem]->m_pLbSort->SetSelectHdl(
    AddSortKey( nSortKeyCount );
    m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->connect_changed(
                     LINK( this, ScTabPageSortFields, SelectHdl ) );

    FillFieldLists( nItem );

    // Set Status
    maSortKeyItems[nItem]->m_pBtnUp->Check();
    maSortKeyItems[nItem]->m_pLbSort->SelectEntryPos( 0 );
    m_aSortWin.m_aSortKeyItems[nItem]->m_xBtnUp->set_active(true);
    m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->set_active(0);
}

// Handler:

IMPL_LINK( ScTabPageSortFields, SelectHdl, ListBox&, rLb, void )
IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBoxText&, rLb, void )
{
    OUString aSelEntry = rLb.GetSelectedEntry();
    OUString aSelEntry = rLb.get_active_text();
    ScSortKeyItems::iterator pIter;

    // If last listbox is enabled add one item
    if ( maSortKeyItems.back()->m_pLbSort == &rLb )
    if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb)
    {
        if ( aSelEntry != aStrUndefined )
        {
            SetLastSortKey( nSortKeyCount );
            return;
        }

    // Find selected listbox
    for ( pIter = maSortKeyItems.begin(); pIter != maSortKeyItems.end(); ++pIter )
    {
        if ( (*pIter)->m_pLbSort == &rLb ) break;
    }

    if (pIter == maSortKeyItems.end())
    // Find selected listbox
    for ( pIter = m_aSortWin.m_aSortKeyItems.begin(); pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
    {
        if ( (*pIter)->m_xLbSort.get() == &rLb ) break;
    }

    if (pIter == m_aSortWin.m_aSortKeyItems.end())
        return;

    // If not selecting the last Listbox, modify the succeeding ones
    ++pIter;
    if ( std::distance(maSortKeyItems.begin(), pIter) < nSortKeyCount )
    if ( std::distance(m_aSortWin.m_aSortKeyItems.begin(), pIter) < nSortKeyCount )
    {
        if ( aSelEntry == aStrUndefined )
        {
            for ( ; pIter != maSortKeyItems.end(); ++pIter )
            for ( ; pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
            {
                (*pIter)->m_pLbSort->SelectEntryPos( 0 );
                (*pIter)->m_xLbSort->set_active(0);

                if ( (*pIter)->m_pFlSort->IsEnabled() )
                    (*pIter)->DisableField();
                (*pIter)->DisableField();
            }
        }
        else
        {
            if ( !(*pIter)->m_pFlSort->IsEnabled() )
                    (*pIter)->EnableField();
            (*pIter)->EnableField();
        }
     }
}

IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer*, void)
{
    m_xScrolledWindow->vadjustment_set_value(m_xScrolledWindow->vadjustment_get_upper());
}

void ScTabPageSortFields::AddSortKey( sal_uInt16 nItem )
{
    m_aSortWin.AddSortKey(nItem);
    m_aIdle.Start();
}

// Sort option Tab Page:

ScTabPageSortOptions::ScTabPageSortOptions( vcl::Window*             pParent,
                                            const SfxItemSet&   rArgSet )
    : SfxTabPage(pParent, "SortOptionsPage",
        "modules/scalc/ui/sortoptionspage.ui", &rArgSet)
ScTabPageSortOptions::ScTabPageSortOptions(TabPageParent pParent, const SfxItemSet& rArgSet)
    : SfxTabPage(pParent, "modules/scalc/ui/sortoptionspage.ui", "SortOptionsPage", &rArgSet)
    , aStrRowLabel(ScResId(SCSTR_ROW_LABEL))
    , aStrColLabel(ScResId(SCSTR_COL_LABEL))
    , aStrUndefined(ScResId(SCSTR_UNDEFINED))
@@ -496,81 +490,45 @@ ScTabPageSortOptions::ScTabPageSortOptions( vcl::Window*             pParent,
    , aSortData(static_cast<const ScSortItem&>(rArgSet.Get(nWhichSort)).GetSortData())
    , pViewData(nullptr)
    , pDoc(nullptr)
    , pDlg(static_cast<ScSortDlg*>(GetParentDialog()))
    , pColRes( nullptr )
    , pColWrap( nullptr )
    , m_xBtnCase(m_xBuilder->weld_check_button("case"))
    , m_xBtnHeader(m_xBuilder->weld_check_button("header"))
    , m_xBtnFormats(m_xBuilder->weld_check_button("formats"))
    , m_xBtnNaturalSort(m_xBuilder->weld_check_button("naturalsort"))
    , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult"))
    , m_xLbOutPos(m_xBuilder->weld_combo_box_text("outarealb"))
    , m_xEdOutPos(m_xBuilder->weld_entry("outareaed"))
    , m_xBtnSortUser(m_xBuilder->weld_check_button("sortuser"))
    , m_xLbSortUser(m_xBuilder->weld_combo_box_text("sortuserlb"))
    , m_xLbLanguage(new LanguageBox(m_xBuilder->weld_combo_box_text("language")))
    , m_xFtAlgorithm(m_xBuilder->weld_label("algorithmft"))
    , m_xLbAlgorithm(m_xBuilder->weld_combo_box_text("algorithmlb"))
    , m_xBtnTopDown(m_xBuilder->weld_radio_button("topdown"))
    , m_xBtnLeftRight(m_xBuilder->weld_radio_button("leftright"))
    , m_xBtnIncComments(m_xBuilder->weld_check_button("includenotes"))
    , m_xBtnIncImages(m_xBuilder->weld_check_button("includeimages"))
{
    get(m_pBtnCase, "case");
    get(m_pBtnHeader, "header");
    get(m_pBtnFormats, "formats");
    get(m_pBtnNaturalSort, "naturalsort");
    get(m_pBtnIncComments, "includenotes");
    get(m_pBtnIncImages, "includeimages");
    get(m_pBtnCopyResult, "copyresult");
    get(m_pLbOutPos, "outarealb");
    get(m_pEdOutPos, "outareaed");
    get(m_pBtnSortUser, "sortuser");
    get(m_pLbSortUser, "sortuserlb");
    get(m_pFtAlgorithm, "algorithmft");
    get(m_pLbAlgorithm, "algorithmlb");
    get(m_pBtnTopDown, "topdown");
    get(m_pBtnLeftRight, "leftright");
    get(m_pLbLanguage, "language");
    m_xLbSortUser->set_size_request(m_xLbSortUser->get_approximate_digit_width() * 50, -1);
    Init();
    SetExchangeSupport();
}

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

void ScTabPageSortOptions::dispose()
{
    const sal_Int32 nEntries = m_pLbOutPos->GetEntryCount();

    for ( sal_Int32 i=1; i<nEntries; ++i )
        delete static_cast<OUString*>(m_pLbOutPos->GetEntryData( i ));

    delete pColRes;
    delete pColWrap;        //! not if from document
    m_pBtnCase.clear();
    m_pBtnHeader.clear();
    m_pBtnFormats.clear();
    m_pBtnNaturalSort.clear();
    m_pBtnIncComments.clear();
    m_pBtnIncImages.clear();
    m_pBtnCopyResult.clear();
    m_pLbOutPos.clear();
    m_pEdOutPos.clear();
    m_pBtnSortUser.clear();
    m_pLbSortUser.clear();
    m_pLbLanguage.clear();
    m_pFtAlgorithm.clear();
    m_pLbAlgorithm.clear();
    m_pBtnTopDown.clear();
    m_pBtnLeftRight.clear();
    pDlg.clear();
    SfxTabPage::dispose();
}

void ScTabPageSortOptions::Init()
{
    //  CollatorResource has user-visible names for sort algorithms
    pColRes = new CollatorResource();
    m_xColRes.reset(new CollatorResource);

    //! use CollatorWrapper from document?
    pColWrap = new CollatorWrapper( comphelper::getProcessComponentContext() );
    m_xColWrap.reset(new CollatorWrapper(comphelper::getProcessComponentContext()));

    const ScSortItem&   rSortItem = static_cast<const ScSortItem&>(
                                    GetItemSet().Get( nWhichSort ));

    m_pLbOutPos->SetSelectHdl    ( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
    m_pBtnCopyResult->SetClickHdl( LINK( this, ScTabPageSortOptions, EnableHdl ) );
    m_pBtnSortUser->SetClickHdl  ( LINK( this, ScTabPageSortOptions, EnableHdl ) );
    m_pBtnTopDown->SetClickHdl   ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
    m_pBtnLeftRight->SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
    m_pLbLanguage->SetSelectHdl  ( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
    m_xLbOutPos->connect_changed( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
    m_xBtnCopyResult->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
    m_xBtnSortUser->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
    m_xBtnTopDown->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
    m_xBtnLeftRight->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
    m_xLbLanguage->connect_changed( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );

    pViewData = rSortItem.GetViewData();
    pDoc      = pViewData ? pViewData->GetDocument() : nullptr;
@@ -583,23 +541,21 @@ void ScTabPageSortOptions::Init()
        const SCTAB     nCurTab     = pViewData->GetTabNo();
        const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

        m_pLbOutPos->Clear();
        m_pLbOutPos->InsertEntry( aStrUndefined, 0 );
        m_pLbOutPos->Disable();
        m_xLbOutPos->clear();
        m_xLbOutPos->append_text(aStrUndefined);
        m_xLbOutPos->set_sensitive(false);

        ScAreaNameIterator aIter( pDoc );
        OUString aName;
        ScRange aRange;
        while ( aIter.Next( aName, aRange ) )
        {
            const sal_Int32 nInsert = m_pLbOutPos->InsertEntry( aName );

            OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
            m_pLbOutPos->SetEntryData( nInsert, new OUString( aRefStr ) );
            m_xLbOutPos->append(aRefStr, aName);
        }

        m_pLbOutPos->SelectEntryPos( 0 );
        m_pEdOutPos->SetText( EMPTY_OUSTRING );
        m_xLbOutPos->set_active(0);
        m_xEdOutPos->set_text(EMPTY_OUSTRING);

        // Check whether the field that is passed on is a database field:

@@ -611,67 +567,66 @@ void ScTabPageSortOptions::Init()
                                            aSortData.nCol2, aSortData.nRow2 );
            if ( pDBData )
            {
                m_pBtnHeader->Check( pDBData->HasHeader() );
                m_xBtnHeader->set_active(pDBData->HasHeader());
            }
        }

        m_pBtnHeader->SetText( aStrColLabel );
        m_xBtnHeader->set_label(aStrColLabel);
    }

    FillUserSortListBox();

    //  get available languages

    m_pLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
    m_pLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
    m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
    m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
}

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

void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
{
    if ( aSortData.bUserDef )
    {
        m_pBtnSortUser->Check();
        m_pLbSortUser->Enable();
        m_pLbSortUser->SelectEntryPos( aSortData.nUserIndex );
        m_xBtnSortUser->set_active(true);
        m_xLbSortUser->set_sensitive(true);
        m_xLbSortUser->set_active(aSortData.nUserIndex);
    }
    else
    {
        m_pBtnSortUser->Check( false );
        m_pLbSortUser->Disable();
        m_pLbSortUser->SelectEntryPos( 0 );
        m_xBtnSortUser->set_active(false);
        m_xLbSortUser->set_sensitive(false);
        m_xLbSortUser->set_active(0);
    }

    m_pBtnCase->Check          ( aSortData.bCaseSens );
    m_pBtnFormats->Check       ( aSortData.bIncludePattern );
    m_pBtnHeader->Check        ( aSortData.bHasHeader );
    m_pBtnNaturalSort->Check   ( aSortData.bNaturalSort );
    m_pBtnIncComments->Check   ( aSortData.bIncludeComments );
    m_pBtnIncImages->Check     ( aSortData.bIncludeGraphicObjects );
    m_xBtnCase->set_active( aSortData.bCaseSens );
    m_xBtnFormats->set_active( aSortData.bIncludePattern );
    m_xBtnHeader->set_active( aSortData.bHasHeader );
    m_xBtnNaturalSort->set_active( aSortData.bNaturalSort );
    m_xBtnIncComments->set_active( aSortData.bIncludeComments );
    m_xBtnIncImages->set_active( aSortData.bIncludeGraphicObjects );

    if ( aSortData.bByRow )
    {
        m_pBtnTopDown->Check();
        m_pBtnHeader->SetText( aStrColLabel );
        m_xBtnTopDown->set_active(true);
        m_xBtnHeader->set_label( aStrColLabel );
    }
    else
    {
        m_pBtnLeftRight->Check();
        m_pBtnHeader->SetText( aStrRowLabel );
        m_xBtnLeftRight->set_active(true);
        m_xBtnHeader->set_label( aStrRowLabel );
    }

    LanguageType eLang = LanguageTag::convertToLanguageType( aSortData.aCollatorLocale, false);
    if ( eLang == LANGUAGE_DONTKNOW )
        eLang = LANGUAGE_SYSTEM;
    m_pLbLanguage->SelectLanguage( eLang );
    FillAlgorHdl(*m_pLbLanguage.get());               // get algorithms, select default
    m_xLbLanguage->SelectLanguage( eLang );
    FillAlgor();               // get algorithms, select default
    if ( !aSortData.aCollatorAlgorithm.isEmpty() )
        m_pLbAlgorithm->SelectEntry( pColRes->GetTranslation( aSortData.aCollatorAlgorithm ) );
        m_xLbAlgorithm->set_active_text(m_xColRes->GetTranslation(aSortData.aCollatorAlgorithm));

    if ( pDoc && !aSortData.bInplace )
    {
@@ -684,20 +639,20 @@ void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
                       aSortData.nDestTab );

        OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
        m_pBtnCopyResult->Check();
        m_pLbOutPos->Enable();
        m_pEdOutPos->Enable();
        m_pEdOutPos->SetText( aStr );
        EdOutPosModHdl(m_pEdOutPos);
        m_pEdOutPos->GrabFocus();
        m_pEdOutPos->SetSelection( Selection( 0, SELECTION_MAX ) );
        m_xBtnCopyResult->set_active(true);
        m_xLbOutPos->set_sensitive(true);
        m_xEdOutPos->set_sensitive(true);
        m_xEdOutPos->set_text( aStr );
        EdOutPosModHdl();
        m_xEdOutPos->grab_focus();
        m_xEdOutPos->select_region(0, -1);
    }
    else
    {
        m_pBtnCopyResult->Check( false );
        m_pLbOutPos->Disable();
        m_pEdOutPos->Disable();
        m_pEdOutPos->SetText( EMPTY_OUSTRING );
        m_xBtnCopyResult->set_active( false );
        m_xLbOutPos->set_sensitive(false);
        m_xEdOutPos->set_sensitive(false);
        m_xEdOutPos->set_text( EMPTY_OUSTRING );
    }
}

@@ -706,40 +661,40 @@ bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
    // Create local copy of ScParam
    ScSortParam aNewSortData = aSortData;

    if (pDlg)
    if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
    {
        const SfxItemSet* pExample = pDlg->GetExampleSet();
        const SfxPoolItem* pItem;
        if ( pExample && pExample->GetItemState( nWhichSort, true, &pItem ) == SfxItemState::SET )
            aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
    }
    aNewSortData.bByRow          = m_pBtnTopDown->IsChecked();
    aNewSortData.bHasHeader      = m_pBtnHeader->IsChecked();
    aNewSortData.bCaseSens       = m_pBtnCase->IsChecked();
    aNewSortData.bNaturalSort    = m_pBtnNaturalSort->IsChecked();
    aNewSortData.bIncludeComments= m_pBtnIncComments->IsChecked();
    aNewSortData.bIncludeGraphicObjects = m_pBtnIncImages->IsChecked();
    aNewSortData.bIncludePattern = m_pBtnFormats->IsChecked();
    aNewSortData.bInplace        = !m_pBtnCopyResult->IsChecked();
    aNewSortData.bByRow          = m_xBtnTopDown->get_active();
    aNewSortData.bHasHeader      = m_xBtnHeader->get_active();
    aNewSortData.bCaseSens       = m_xBtnCase->get_active();
    aNewSortData.bNaturalSort    = m_xBtnNaturalSort->get_active();
    aNewSortData.bIncludeComments= m_xBtnIncComments->get_active();
    aNewSortData.bIncludeGraphicObjects = m_xBtnIncImages->get_active();
    aNewSortData.bIncludePattern = m_xBtnFormats->get_active();
    aNewSortData.bInplace        = !m_xBtnCopyResult->get_active();
    aNewSortData.nDestCol        = theOutPos.Col();
    aNewSortData.nDestRow        = theOutPos.Row();
    aNewSortData.nDestTab        = theOutPos.Tab();
    aNewSortData.bUserDef        = m_pBtnSortUser->IsChecked();
    aNewSortData.nUserIndex      = (m_pBtnSortUser->IsChecked())
                                   ? m_pLbSortUser->GetSelectedEntryPos()
    aNewSortData.bUserDef        = m_xBtnSortUser->get_active();
    aNewSortData.nUserIndex      = (m_xBtnSortUser->get_active())
                                   ? m_xLbSortUser->get_active()
                                   : 0;

    // get locale
    LanguageType eLang = m_pLbLanguage->GetSelectedLanguage();
    LanguageType eLang = m_xLbLanguage->GetSelectedLanguage();
    aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);

    // get algorithm
    OUString sAlg;
    if ( eLang != LANGUAGE_SYSTEM )
    {
        uno::Sequence<OUString> aAlgos = pColWrap->listCollatorAlgorithms(
        uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms(
                aNewSortData.aCollatorLocale );
        const sal_Int32 nSel = m_pLbAlgorithm->GetSelectedEntryPos();
        const int nSel = m_xLbAlgorithm->get_active();
        if ( nSel < aAlgos.getLength() )
            sAlg = aAlgos[nSel];
    }
@@ -755,20 +710,20 @@ void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
{
    // Refresh local copy with shared data
    aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
    if ( pDlg )
    if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
    {
        if ( m_pBtnHeader->IsChecked() != pDlg->GetHeaders() )
        if ( m_xBtnHeader->get_active() != pDlg->GetHeaders() )
        {
            m_pBtnHeader->Check( pDlg->GetHeaders() );
            m_xBtnHeader->set_active( pDlg->GetHeaders() );
        }

        if ( m_pBtnTopDown->IsChecked() != pDlg->GetByRows() )
        if ( m_xBtnTopDown->get_active() != pDlg->GetByRows() )
        {
            m_pBtnTopDown->Check( pDlg->GetByRows() );
            m_pBtnLeftRight->Check( !pDlg->GetByRows() );
            m_xBtnTopDown->set_active( pDlg->GetByRows() );
            m_xBtnLeftRight->set_active( !pDlg->GetByRows() );
        }

        m_pBtnHeader->SetText( (pDlg->GetByRows())
        m_xBtnHeader->set_label( (pDlg->GetByRows())
                            ? aStrColLabel
                            : aStrRowLabel );
    }
@@ -778,9 +733,9 @@ DeactivateRC ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
{
    bool bPosInputOk = true;

    if ( m_pBtnCopyResult->IsChecked() )
    if ( m_xBtnCopyResult->get_active() )
    {
        OUString    thePosStr = m_pEdOutPos->GetText();
        OUString    thePosStr = m_xEdOutPos->get_text();
        ScAddress   thePos;
        sal_Int32   nColonPos = thePosStr.indexOf( ':' );

@@ -800,25 +755,26 @@ DeactivateRC ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )

        if ( !bPosInputOk )
        {
            std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
            std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetTabDialog()->GetFrameWeld(),
                                                      VclMessageType::Warning, VclButtonsType::Ok,
                                                      ScResId(STR_INVALID_TABREF)));
            xBox->run();
            m_pEdOutPos->GrabFocus();
            m_pEdOutPos->SetSelection( Selection( 0, SELECTION_MAX ) );
            m_xEdOutPos->grab_focus();
            m_xEdOutPos->select_region(0, -1);
            theOutPos.Set(0,0,0);
        }
        else
        {
            m_pEdOutPos->SetText( thePosStr );
            m_xEdOutPos->set_text(thePosStr);
            theOutPos = thePos;
        }
    }

    if ( pDlg && bPosInputOk )
    ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
    if (pDlg && bPosInputOk)
    {
        pDlg->SetHeaders( m_pBtnHeader->IsChecked() );
        pDlg->SetByRows ( m_pBtnTopDown->IsChecked() );
        pDlg->SetHeaders( m_xBtnHeader->get_active() );
        pDlg->SetByRows ( m_xBtnTopDown->get_active() );
    }

    if ( pSetP && bPosInputOk )
@@ -831,133 +787,129 @@ void ScTabPageSortOptions::FillUserSortListBox()
{
    ScUserList* pUserLists = ScGlobal::GetUserList();

    m_pLbSortUser->Clear();
    m_xLbSortUser->clear();
    if ( pUserLists )
    {
        size_t nCount = pUserLists->size();
        if ( nCount > 0 )
            for ( size_t i=0; i<nCount; ++i )
                m_pLbSortUser->InsertEntry( (*pUserLists)[i].GetString() );
        for (size_t i=0; i<nCount; ++i)
            m_xLbSortUser->append_text((*pUserLists)[i].GetString());
    }
}

// Handler:

IMPL_LINK( ScTabPageSortOptions, EnableHdl, Button*, pButton, void )
IMPL_LINK( ScTabPageSortOptions, EnableHdl, weld::ToggleButton&, rButton, void )
{
    CheckBox* pBox = static_cast<CheckBox*>(pButton);
    if (pBox == m_pBtnCopyResult)
    if (&rButton == m_xBtnCopyResult.get())
    {
        if ( pBox->IsChecked() )
        if (rButton.get_active())
        {
            m_pLbOutPos->Enable();
            m_pEdOutPos->Enable();
            m_pEdOutPos->GrabFocus();
            m_xLbOutPos->set_sensitive(true);
            m_xEdOutPos->set_sensitive(true);
            m_xEdOutPos->grab_focus();
        }
        else
        {
            m_pLbOutPos->Disable();
            m_pEdOutPos->Disable();
            m_xLbOutPos->set_sensitive(false);
            m_xEdOutPos->set_sensitive(false);
        }
    }
    else if (pBox == m_pBtnSortUser)
    else if (&rButton == m_xBtnSortUser.get())
    {
        if ( pBox->IsChecked() )
        if (rButton.get_active())
        {
            m_pLbSortUser->Enable();
            m_pLbSortUser->GrabFocus();
            m_xLbSortUser->set_sensitive(true);
            m_xLbSortUser->grab_focus();
        }
        else
            m_pLbSortUser->Disable();
            m_xLbSortUser->set_sensitive(false);
    }
}

IMPL_LINK( ScTabPageSortOptions, SelOutPosHdl, ListBox&, rLb, void )
IMPL_LINK(ScTabPageSortOptions, SelOutPosHdl, weld::ComboBoxText&, rLb, void)
{
    if (&rLb == m_pLbOutPos)
    if (&rLb == m_xLbOutPos.get())
    {
        OUString  aString;
        const sal_Int32 nSelPos = m_pLbOutPos->GetSelectedEntryPos();
        const int nSelPos = m_xLbOutPos->get_active();

        if ( nSelPos > 0 )
            aString = *static_cast<OUString*>(m_pLbOutPos->GetEntryData( nSelPos ));
        if (nSelPos > 0)
            aString = m_xLbOutPos->get_id(nSelPos);

        m_pEdOutPos->SetText( aString );
        m_xEdOutPos->set_text(aString);
    }
}

IMPL_LINK( ScTabPageSortOptions, SortDirHdl, Button *, pBtn, void )
IMPL_LINK_NOARG(ScTabPageSortOptions, SortDirHdl, weld::ToggleButton&, void)
{
    if (pBtn == m_pBtnTopDown)
    {
        m_pBtnHeader->SetText( aStrColLabel );
    }
    else if (pBtn == m_pBtnLeftRight)
    {
        m_pBtnHeader->SetText( aStrRowLabel );
    }
    if (m_xBtnTopDown->get_active())
        m_xBtnHeader->set_label(aStrColLabel);
    else
        m_xBtnHeader->set_label(aStrRowLabel);
}

void ScTabPageSortOptions::EdOutPosModHdl( Edit* pEd )
void ScTabPageSortOptions::EdOutPosModHdl()
{
    if (pEd == m_pEdOutPos)
    {
        OUString  theCurPosStr = m_pEdOutPos->GetText();
        ScRefFlags  nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
    OUString  theCurPosStr = m_xEdOutPos->get_text();
    ScRefFlags  nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );

        if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
    if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
    {
        bool    bFound  = false;
        sal_Int32 i = 0;
        const int nCount = m_xLbOutPos->get_count();

        for ( i=2; i<nCount && !bFound; i++ )
        {
            bool    bFound  = false;
            sal_Int32 i = 0;
            const sal_Int32 nCount = m_pLbOutPos->GetEntryCount();

            for ( i=2; i<nCount && !bFound; i++ )
            {
                OUString* pStr = static_cast<OUString*>(m_pLbOutPos->GetEntryData( i ));
                bFound = (theCurPosStr == *pStr);
            }

            if ( bFound )
                m_pLbOutPos->SelectEntryPos( --i );
            else
                m_pLbOutPos->SelectEntryPos( 0 );
            OUString aStr = m_xLbOutPos->get_id(i);
            bFound = (theCurPosStr == aStr);
        }

        if ( bFound )
            m_xLbOutPos->set_active(--i);
        else
            m_xLbOutPos->set_active(0);
    }
}

IMPL_LINK_NOARG(ScTabPageSortOptions, FillAlgorHdl, ListBox&, void)
void ScTabPageSortOptions::FillAlgor()
{
    m_pLbAlgorithm->SetUpdateMode( false );
    m_pLbAlgorithm->Clear();
    m_xLbAlgorithm->freeze();
    m_xLbAlgorithm->clear();

    LanguageType eLang = m_pLbLanguage->GetSelectedLanguage();
    LanguageType eLang = m_xLbLanguage->GetSelectedLanguage();
    if ( eLang == LANGUAGE_SYSTEM )
    {
        //  for LANGUAGE_SYSTEM no algorithm can be selected because
        //  it wouldn't necessarily exist for other languages
        //  -> leave list box empty if LANGUAGE_SYSTEM is selected
        m_pFtAlgorithm->Enable( false );           // nothing to select
        m_pLbAlgorithm->Enable( false );           // nothing to select
        m_xFtAlgorithm->set_sensitive( false );           // nothing to select
        m_xLbAlgorithm->set_sensitive( false );           // nothing to select
    }
    else
    {
        lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
        uno::Sequence<OUString> aAlgos = pColWrap->listCollatorAlgorithms( aLocale );
        uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms( aLocale );

        long nCount = aAlgos.getLength();
        const OUString* pArray = aAlgos.getConstArray();
        for (long i=0; i<nCount; i++)
        {
            OUString sAlg = pArray[i];
            OUString sUser = pColRes->GetTranslation( sAlg );
            m_pLbAlgorithm->InsertEntry( sUser );
            OUString sUser = m_xColRes->GetTranslation( sAlg );
            m_xLbAlgorithm->append_text(sUser);
        }
        m_pLbAlgorithm->SelectEntryPos( 0 );       // first entry is default
        m_pFtAlgorithm->Enable( nCount > 1 );      // enable only if there is a choice
        m_pLbAlgorithm->Enable( nCount > 1 );      // enable only if there is a choice
        m_xLbAlgorithm->set_active(0);       // first entry is default
        m_xFtAlgorithm->set_sensitive(nCount > 1);      // enable only if there is a choice
        m_xLbAlgorithm->set_sensitive(nCount > 1);      // enable only if there is a choice
    }

    m_pLbAlgorithm->SetUpdateMode( true );
    m_xLbAlgorithm->thaw();
}

IMPL_LINK_NOARG(ScTabPageSortOptions, FillAlgorHdl, weld::ComboBoxText&, void)
{
    FillAlgor();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/sortdlg.hxx b/sc/source/ui/inc/sortdlg.hxx
index 6b790aa..91a27e4 100644
--- a/sc/source/ui/inc/sortdlg.hxx
+++ b/sc/source/ui/inc/sortdlg.hxx
@@ -24,10 +24,10 @@
#include <vcl/weld.hxx>
#include "scui_def.hxx"

class ScSortDlg : public SfxTabDialog
class ScSortDlg : public SfxTabDialogController
{
public:
    ScSortDlg(vcl::Window* pParent, const SfxItemSet* pArgSet);
    ScSortDlg(weld::Window* pParent, const SfxItemSet* pArgSet);

    void SetHeaders( bool bHeaders )  { bIsHeaders = bHeaders; }
    void SetByRows ( bool bByRows  )  { bIsByRows = bByRows; }
diff --git a/sc/source/ui/inc/sortkeydlg.hxx b/sc/source/ui/inc/sortkeydlg.hxx
index c8d83ce..3950605 100644
--- a/sc/source/ui/inc/sortkeydlg.hxx
+++ b/sc/source/ui/inc/sortkeydlg.hxx
@@ -15,23 +15,19 @@

#include "anyrefdg.hxx"

#include <vcl/edit.hxx>
#include <vcl/fixed.hxx>
#include <vcl/layout.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/ctrl.hxx>
#include <vcl/weld.hxx>
#include <svx/langbox.hxx>

struct ScSortKeyItem : public VclBuilderContainer
struct ScSortKeyItem
{
    VclPtr<VclFrame>       m_pFrame;
    VclPtr<FixedText>      m_pFlSort;
    VclPtr<ListBox>        m_pLbSort;
    VclPtr<RadioButton>    m_pBtnUp;
    VclPtr<RadioButton>    m_pBtnDown;
    std::unique_ptr<weld::Builder> m_xBuilder;

    ScSortKeyItem(vcl::Window* pParent);
    std::unique_ptr<weld::Frame> m_xFrame;
    std::unique_ptr<weld::ComboBoxText> m_xLbSort;
    std::unique_ptr<weld::RadioButton> m_xBtnUp;
    std::unique_ptr<weld::RadioButton> m_xBtnDown;

    ScSortKeyItem(weld::Container* pParent);

    void DisableField();
    void EnableField();
@@ -43,38 +39,19 @@ typedef std::vector<std::unique_ptr<ScSortKeyItem> > ScSortKeyItems;

class ScSortKeyWindow
{
public:
    ScSortKeyItems m_aSortKeyItems;
private:
    VclPtr<VclBox>  m_pBox;
    sal_Int32       nItemHeight;

    ScSortKeyItems& mrSortKeyItems;
    weld::Container* m_pBox;
    sal_Int32 m_nItemHeight;

public:
    ScSortKeyWindow(SfxTabPage* pParent, ScSortKeyItems& mrSortKeyItems);
    ScSortKeyWindow(weld::Container* pBox);
    ~ScSortKeyWindow();
    void dispose();

    void AddSortKey( sal_uInt16 nItem );
    void DoScroll( sal_Int32 nNewPos );
    sal_Int32 GetItemHeight() const { return nItemHeight; }
};

class ScSortKeyCtrl
{
private:
    ScSortKeyWindow  m_aSortWin;
    VclScrolledWindow& m_rScrolledWindow;
    ScrollBar&       m_rVertScroll;

    DECL_LINK(ScrollHdl, ScrollBar*, void);

    void checkAutoVScroll();

public:
    ScSortKeyCtrl(SfxTabPage* pParent, ScSortKeyItems& mrSortKeyItems);
    void dispose();
    void setScrollRange();
    void AddSortKey( sal_uInt16 nItem );
    sal_Int32 GetItemHeight() const { return m_nItemHeight; }
};

#endif // INCLUDED_SC_SOURCE_UI_INC_SORTKEYDLG_HXX
diff --git a/sc/source/ui/inc/tpsort.hxx b/sc/source/ui/inc/tpsort.hxx
index 660d9eb..4690873 100644
--- a/sc/source/ui/inc/tpsort.hxx
+++ b/sc/source/ui/inc/tpsort.hxx
@@ -46,19 +46,14 @@ struct ScSortParam;
class ScTabPageSortFields : public SfxTabPage
{
public:
    ScTabPageSortFields( vcl::Window*             pParent,
            const SfxItemSet&   rArgSet );
    ScTabPageSortFields(TabPageParent pParent, const SfxItemSet& rArgSet);
    virtual void dispose() override;
    virtual ~ScTabPageSortFields() override;
    virtual void        dispose() override;
    static  VclPtr<SfxTabPage> Create      ( TabPageParent               pParent,
                                      const SfxItemSet*     rArgSet );
    virtual bool        FillItemSet ( SfxItemSet* rArgSet ) override;
    virtual void        Reset       ( const SfxItemSet* rArgSet ) override;

    virtual void SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation) override;
    virtual void SetSizePixel(const Size& rAllocation) override;
    virtual void SetPosPixel(const Point& rAllocPos) override;

protected:
    virtual void        ActivatePage    ( const SfxItemSet& rSet ) override;
    using SfxTabPage::ActivatePage;
@@ -66,12 +61,13 @@ protected:
    virtual DeactivateRC   DeactivatePage  ( SfxItemSet* pSet ) override;

private:
    Idle m_aIdle;

    OUString            aStrUndefined;
    OUString            aStrColumn;
    OUString            aStrRow;

    const sal_uInt16    nWhichSort;
    VclPtr<ScSortDlg>   pDlg;
    ScViewData*         pViewData;
    ScSortParam         aSortData;
    std::vector<SCCOLROW>  nFieldArr;
@@ -81,8 +77,11 @@ private:
    bool                bHasHeader;
    bool                bSortByRows;

    ScSortKeyItems      maSortKeyItems;
    ScSortKeyCtrl       maSortKeyCtrl;
    std::unique_ptr<weld::ScrolledWindow> m_xScrolledWindow;
    std::unique_ptr<weld::Container> m_xBox;
    ScSortKeyWindow m_aSortWin;

    void AddSortKey( sal_uInt16 nItem );

private:
    void    Init            ();
@@ -91,7 +90,8 @@ private:
    void    SetLastSortKey( sal_uInt16 nItem );

    // Handler ------------------------
    DECL_LINK( SelectHdl, ListBox&, void );
    DECL_LINK(SelectHdl, weld::ComboBoxText&, void);
    DECL_LINK(ScrollToEndHdl, Timer*, void);
};

// Sort Options
@@ -103,15 +103,9 @@ class CollatorWrapper;
class ScTabPageSortOptions : public SfxTabPage
{
public:
    ScTabPageSortOptions( vcl::Window*            pParent,
            const SfxItemSet&  rArgSet );
    virtual ~ScTabPageSortOptions() override;
    virtual void dispose() override;
    ScTabPageSortOptions(TabPageParent pParent, const SfxItemSet& rArgSet);

#undef SfxTabPage
#define SfxTabPage ::SfxTabPage
    static  VclPtr<SfxTabPage> Create      ( TabPageParent               pParent,
                                      const SfxItemSet*     rArgSet );
    static  VclPtr<SfxTabPage> Create(TabPageParent pParent, const SfxItemSet* pArgSet);
    virtual bool        FillItemSet ( SfxItemSet* rArgSet ) override;
    virtual void        Reset       ( const SfxItemSet* rArgSet ) override;

@@ -122,29 +116,6 @@ protected:
    virtual DeactivateRC   DeactivatePage  ( SfxItemSet* pSet ) override;

private:

    VclPtr<CheckBox>           m_pBtnCase;
    VclPtr<CheckBox>           m_pBtnHeader;
    VclPtr<CheckBox>           m_pBtnFormats;
    VclPtr<CheckBox>           m_pBtnNaturalSort;

    VclPtr<CheckBox>           m_pBtnCopyResult;
    VclPtr<ListBox>            m_pLbOutPos;
    VclPtr<Edit>               m_pEdOutPos;

    VclPtr<CheckBox>           m_pBtnSortUser;
    VclPtr<ListBox>            m_pLbSortUser;

    VclPtr<SvxLanguageBox>     m_pLbLanguage;
    VclPtr<FixedText>          m_pFtAlgorithm;
    VclPtr<ListBox>            m_pLbAlgorithm;

    VclPtr<RadioButton>        m_pBtnTopDown;
    VclPtr<RadioButton>        m_pBtnLeftRight;

    VclPtr<CheckBox>           m_pBtnIncComments;
    VclPtr<CheckBox>           m_pBtnIncImages;

    OUString            aStrRowLabel;
    OUString            aStrColLabel;
    OUString            aStrUndefined;
@@ -153,22 +124,39 @@ private:
    ScSortParam         aSortData;
    ScViewData*         pViewData;
    ScDocument*         pDoc;
    VclPtr<ScSortDlg>          pDlg;
    ScAddress           theOutPos;

    CollatorResource*  pColRes;
    CollatorWrapper*    pColWrap;
    std::unique_ptr<CollatorResource>  m_xColRes;
    std::unique_ptr<CollatorWrapper>   m_xColWrap;

    std::unique_ptr<weld::CheckButton> m_xBtnCase;
    std::unique_ptr<weld::CheckButton> m_xBtnHeader;
    std::unique_ptr<weld::CheckButton> m_xBtnFormats;
    std::unique_ptr<weld::CheckButton> m_xBtnNaturalSort;
    std::unique_ptr<weld::CheckButton> m_xBtnCopyResult;
    std::unique_ptr<weld::ComboBoxText> m_xLbOutPos;
    std::unique_ptr<weld::Entry> m_xEdOutPos;
    std::unique_ptr<weld::CheckButton> m_xBtnSortUser;
    std::unique_ptr<weld::ComboBoxText> m_xLbSortUser;
    std::unique_ptr<LanguageBox> m_xLbLanguage;
    std::unique_ptr<weld::Label> m_xFtAlgorithm;
    std::unique_ptr<weld::ComboBoxText> m_xLbAlgorithm;
    std::unique_ptr<weld::RadioButton> m_xBtnTopDown;
    std::unique_ptr<weld::RadioButton> m_xBtnLeftRight;
    std::unique_ptr<weld::CheckButton> m_xBtnIncComments;
    std::unique_ptr<weld::CheckButton> m_xBtnIncImages;

private:
    void Init                   ();
    void FillUserSortListBox    ();

    // Handler ------------------------
    DECL_LINK( EnableHdl, Button*, void );
    DECL_LINK( SelOutPosHdl, ListBox&, void );
    void EdOutPosModHdl ( Edit* pEd );
    DECL_LINK( SortDirHdl, Button *, void );
    DECL_LINK( FillAlgorHdl, ListBox&, void );
    DECL_LINK( EnableHdl, weld::ToggleButton&, void );
    DECL_LINK( SelOutPosHdl, weld::ComboBoxText&, void );
    void EdOutPosModHdl();
    DECL_LINK( SortDirHdl, weld::ToggleButton&, void );
    void FillAlgor();
    DECL_LINK( FillAlgorHdl, weld::ComboBoxText&, void );
};

#endif // INCLUDED_SC_SOURCE_UI_INC_TPSORT_HXX
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index f97c52c..24e0c76 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -495,7 +495,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
                        assert(pFact); //ScAbstractFactory create fail!

                        ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScSortDlg(pTabViewShell->GetDialogParent(),  &aArgSet));
                        ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScSortDlg(pTabViewShell->GetFrameWeld(),  &aArgSet));
                        assert(pDlg); //Dialog create fail!
                        pDlg->SetCurPageId("criteria");  // 1=sort field tab  2=sort options tab

diff --git a/sc/uiconfig/scalc/ui/sortcriteriapage.ui b/sc/uiconfig/scalc/ui/sortcriteriapage.ui
index 6b2a782..8918b99 100644
--- a/sc/uiconfig/scalc/ui/sortcriteriapage.ui
+++ b/sc/uiconfig/scalc/ui/sortcriteriapage.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkScrolledWindow" id="SortCriteriaPage">
@@ -8,7 +8,6 @@
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="hscrollbar_policy">never</property>
    <property name="shadow_type">in</property>
    <child>
      <object class="GtkViewport" id="viewport2">
        <property name="visible">True</property>
diff --git a/sc/uiconfig/scalc/ui/sortdialog.ui b/sc/uiconfig/scalc/ui/sortdialog.ui
index 76e9b4d..bc92869 100644
--- a/sc/uiconfig/scalc/ui/sortdialog.ui
+++ b/sc/uiconfig/scalc/ui/sortdialog.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkDialog" id="SortDialog">
@@ -7,7 +7,13 @@
    <property name="border_width">6</property>
    <property name="title" translatable="yes" context="sortdialog|SortDialog">Sort</property>
    <property name="resizable">False</property>
    <property name="modal">True</property>
    <property name="default_width">0</property>
    <property name="default_height">0</property>
    <property name="type_hint">dialog</property>
    <child>
      <placeholder/>
    </child>
    <child internal-child="vbox">
      <object class="GtkBox" id="dialog-vbox1">
        <property name="can_focus">False</property>
@@ -18,6 +24,20 @@
            <property name="can_focus">False</property>
            <property name="layout_style">end</property>
            <child>
              <object class="GtkButton" id="reset">
                <property name="label">gtk-revert-to-saved</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="ok">
                <property name="label">gtk-ok</property>
                <property name="visible">True</property>
@@ -30,7 +50,7 @@
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
@@ -44,7 +64,7 @@
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
@@ -58,22 +78,8 @@
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">2</property>
                <property name="secondary">True</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="reset">
                <property name="label">gtk-revert-to-saved</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">3</property>
                <property name="secondary">True</property>
              </packing>
            </child>
          </object>
@@ -97,6 +103,30 @@
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
              </object>
            </child>
            <child type="tab">
@@ -116,6 +146,30 @@
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
              </object>
              <packing>
                <property name="position">1</property>
@@ -142,10 +196,10 @@
      </object>
    </child>
    <action-widgets>
      <action-widget response="0">reset</action-widget>
      <action-widget response="-5">ok</action-widget>
      <action-widget response="-6">cancel</action-widget>
      <action-widget response="-11">help</action-widget>
      <action-widget response="0">reset</action-widget>
    </action-widgets>
  </object>
</interface>
diff --git a/sc/uiconfig/scalc/ui/sortkey.ui b/sc/uiconfig/scalc/ui/sortkey.ui
index 29f5c5f..e554c5b 100644
--- a/sc/uiconfig/scalc/ui/sortkey.ui
+++ b/sc/uiconfig/scalc/ui/sortkey.ui
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <!-- interface-requires gtk+ 3.0 -->
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkFrame" id="SortKeyFrame">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -20,7 +21,7 @@
            <property name="row_spacing">6</property>
            <property name="column_spacing">12</property>
            <child>
              <object class="GtkComboBox" id="sortlb">
              <object class="GtkComboBoxText" id="sortlb">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="valign">center</property>
@@ -29,7 +30,6 @@
              <packing>
                <property name="left_attach">0</property>
                <property name="top_attach">0</property>
                <property name="width">1</property>
                <property name="height">2</property>
              </packing>
            </child>
@@ -43,13 +43,10 @@
                <property name="xalign">0</property>
                <property name="active">True</property>
                <property name="draw_indicator">True</property>
                <property name="group">down</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
                <property name="top_attach">0</property>
                <property name="width">1</property>
                <property name="height">1</property>
              </packing>
            </child>
            <child>
@@ -66,8 +63,6 @@
              <packing>
                <property name="left_attach">1</property>
                <property name="top_attach">1</property>
                <property name="width">1</property>
                <property name="height">1</property>
              </packing>
            </child>
          </object>
diff --git a/sc/uiconfig/scalc/ui/sortoptionspage.ui b/sc/uiconfig/scalc/ui/sortoptionspage.ui
index ae3251f..f7ebf77 100644
--- a/sc/uiconfig/scalc/ui/sortoptionspage.ui
+++ b/sc/uiconfig/scalc/ui/sortoptionspage.ui
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkBox" id="SortOptionsPage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -136,7 +135,7 @@
                  </packing>
                </child>
                <child>
                  <object class="GtkComboBox" id="outarealb">
                  <object class="GtkComboBoxText" id="outarealb">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="margin_left">12</property>
@@ -146,7 +145,7 @@
                    </accessibility>
                    <child internal-child="accessible">
                      <object class="AtkObject" id="outarealb-atkobject">
                      <property name="AtkObject::accessible-name" translatable="yes" context="sortoptionspage|outarealb-atkobject">Copy sort results to:</property>
                        <property name="AtkObject::accessible-name" translatable="yes" context="sortoptionspage|outarealb-atkobject">Copy sort results to:</property>
                      </object>
                    </child>
                  </object>
@@ -160,6 +159,7 @@
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="activates_default">True</property>
                    <accessibility>
                      <relation type="labelled-by" target="outarealb"/>
                    </accessibility>
@@ -193,11 +193,10 @@
                  </packing>
                </child>
                <child>
                  <object class="VclComboBoxText" id="sortuserlb">
                  <object class="GtkComboBoxText" id="sortuserlb">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="margin_left">12</property>
                    <property name="max_width_chars">65</property>
                    <accessibility>
                      <relation type="labelled-by" target="sortuser"/>
                    </accessibility>
@@ -242,17 +241,7 @@
                  </packing>
                </child>
                <child>
                  <object class="svxcorelo-SvxLanguageBox" id="language">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
                  <packing>
                    <property name="left_attach">0</property>
                    <property name="top_attach">11</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkComboBox" id="algorithmlb">
                  <object class="GtkComboBoxText" id="algorithmlb">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
@@ -262,6 +251,22 @@
                  </packing>
                </child>
                <child>
                  <object class="GtkComboBoxText" id="language">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="has_entry">True</property>
                    <child internal-child="entry">
                      <object class="GtkEntry">
                        <property name="can_focus">True</property>
                      </object>
                    </child>
                  </object>
                  <packing>
                    <property name="left_attach">0</property>
                    <property name="top_attach">11</property>
                  </packing>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
@@ -332,7 +337,6 @@
                    <property name="xalign">0</property>
                    <property name="active">True</property>
                    <property name="draw_indicator">True</property>
                    <property name="group">leftright</property>
                  </object>
                  <packing>
                    <property name="left_attach">0</property>
diff --git a/sfx2/source/dialog/tabdlg.cxx b/sfx2/source/dialog/tabdlg.cxx
index ae80237..31be0ca 100644
--- a/sfx2/source/dialog/tabdlg.cxx
+++ b/sfx2/source/dialog/tabdlg.cxx
@@ -1999,17 +1999,22 @@ void SfxTabDialogController::Start_Impl()
    assert(m_pImpl->aData.size() == static_cast<size_t>(m_xTabCtrl->get_n_pages())
            && "not all pages registered");

    // load old settings, when exists
    SvtViewOptions aDlgOpt(EViewType::TabDialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
    if (aDlgOpt.Exists())
        m_xTabCtrl->set_current_page(aDlgOpt.GetPageID());
    // load old settings, when exists, setting SetCurPageId will override the settings,
    // something that the sort dialog in calc depends on
    if (m_sAppPageId.isEmpty())
    {
        SvtViewOptions aDlgOpt(EViewType::TabDialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
        if (aDlgOpt.Exists())
            m_xTabCtrl->set_current_page(aDlgOpt.GetPageID());
    }

    ActivatePageHdl(m_xTabCtrl->get_current_page_ident());
}

void SfxTabDialogController::SetCurPageId(const OString& rIdent)
{
    m_xTabCtrl->set_current_page(rIdent);
    m_sAppPageId = rIdent;
    m_xTabCtrl->set_current_page(m_sAppPageId);
}

OString SfxTabDialogController::GetCurPageId() const
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 89a03c1..154e1ad 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -714,6 +714,8 @@ class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual we
{
private:
    VclPtr<VclScrolledWindow> m_xScrolledWindow;
    Link<ScrollBar*,void> m_aOrigVScrollHdl;
    bool m_bUserManagedScrolling;

    DECL_LINK(VscrollHdl, ScrollBar*, void);

@@ -721,8 +723,10 @@ public:
    SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, bool bTakeOwnership)
        : SalInstanceContainer(pScrolledWindow, bTakeOwnership)
        , m_xScrolledWindow(pScrolledWindow)
        , m_bUserManagedScrolling(false)
    {
        ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
        m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
        rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
    }

@@ -749,23 +753,40 @@ public:
    {
        ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
        rVertScrollBar.SetThumbPos(value);
        if (!m_bUserManagedScrolling)
            m_aOrigVScrollHdl.Call(&rVertScrollBar);
    }

    virtual int vadjustment_get_upper() const override
    {
        ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
        return rVertScrollBar.GetRangeMax();
    }

    virtual void vadjustment_set_upper(int upper) override
    {
        ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
        rVertScrollBar.SetRangeMax(upper);
    }

    virtual void set_user_managed_scrolling() override
    {
        m_bUserManagedScrolling = true;
        m_xScrolledWindow->setUserManagedScrolling(true);
    }

    virtual ~SalInstanceScrolledWindow() override
    {
        ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
        rVertScrollBar.SetScrollHdl(Link<ScrollBar*, void>());
        rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
    }
};

IMPL_LINK_NOARG(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, void)
{
    signal_vadjustment_changed();
    if (!m_bUserManagedScrolling)
        m_aOrigVScrollHdl.Call(&m_xScrolledWindow->getVertScrollBar());
}

class SalInstanceNotebook : public SalInstanceContainer, public virtual weld::Notebook
@@ -2143,7 +2164,14 @@ public:
    virtual weld::Frame* weld_frame(const OString &id, bool bTakeOwnership) override
    {
        VclFrame* pFrame = m_xBuilder->get<VclFrame>(id);
        return pFrame ? new SalInstanceFrame(pFrame, bTakeOwnership) : nullptr;
        weld::Frame* pRet = pFrame ? new SalInstanceFrame(pFrame, false) : nullptr;
        if (bTakeOwnership && pFrame)
        {
            assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
            m_aOwnedToplevel.set(pFrame);
            m_xBuilder->drop_ownership(pFrame);
        }
        return pRet;
    }

    virtual weld::ScrolledWindow* weld_scrolled_window(const OString &id, bool bTakeOwnership) override
@@ -2274,6 +2302,8 @@ public:
    {
        if (VclBuilderContainer* pOwnedToplevel = dynamic_cast<VclBuilderContainer*>(m_aOwnedToplevel.get()))
            pOwnedToplevel->m_pUIBuilder = std::move(m_xBuilder);
        else
            m_xBuilder.reset();
        m_aOwnedToplevel.disposeAndClear();
    }
};
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index d54c628..4508d34 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -917,6 +917,8 @@ void ComboBox::RemoveEntryAt(sal_Int32 const nPos)

void ComboBox::Clear()
{
    if (!m_pImpl->m_pImplLB)
        return;
    m_pImpl->m_pImplLB->Clear();
    CallEventListeners( VclEventId::ComboboxItemRemoved, reinterpret_cast<void*>(-1) );
}
@@ -955,6 +957,8 @@ OUString ComboBox::GetEntry( sal_Int32 nPos ) const

sal_Int32 ComboBox::GetEntryCount() const
{
    if (!m_pImpl->m_pImplLB)
        return 0;
    return m_pImpl->m_pImplLB->GetEntryList()->GetEntryCount() - m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
}

@@ -987,7 +991,12 @@ void ComboBox::SetDoubleClickHdl(const Link<ComboBox&,void>& rLink) { m_pImpl->m

const Link<ComboBox&,void>& ComboBox::GetDoubleClickHdl() const { return m_pImpl->m_DoubleClickHdl; }

void ComboBox::SetEntryActivateHdl(const Link<Edit&,void>& rLink) { m_pImpl->m_pSubEdit->SetActivateHdl(rLink); }
void ComboBox::SetEntryActivateHdl(const Link<Edit&,void>& rLink)
{
    if (!m_pImpl->m_pSubEdit)
        return;
    m_pImpl->m_pSubEdit->SetActivateHdl(rLink);
}

long ComboBox::CalcWindowSizePixel(sal_uInt16 nLines) const
{
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 8f8e829..9d9e053 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2041,7 +2041,13 @@ void VclViewport::setAllocation(const Size &rAllocation)
        Size aReq(getLayoutRequisition(*pChild));
        aReq.setWidth( std::max(aReq.Width(), rAllocation.Width()) );
        aReq.setHeight( std::max(aReq.Height(), rAllocation.Height()) );
        setLayoutAllocation(*pChild, Point(0, 0), aReq);
        Point aKeepPos(pChild->GetPosPixel());
        if (m_bInitialAllocation)
        {
            aKeepPos = Point(0, 0);
            m_bInitialAllocation = false;
        }
        setLayoutAllocation(*pChild, aKeepPos, aReq);
    }
}

diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index b882d68..e558ccd 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2314,6 +2314,18 @@ public:
        enable_notify_events();
    }

    virtual int vadjustment_get_upper() const override
    {
         return gtk_adjustment_get_upper(m_pVAdjustment);
    }

    virtual void vadjustment_set_upper(int upper) override
    {
        disable_notify_events();
        gtk_adjustment_set_upper(m_pVAdjustment, upper);
        enable_notify_events();
    }

    virtual void set_user_managed_scrolling() override
    {
        disable_notify_events();