weld ListBoxControl

Change-Id: I5a8c7d68e4c147eb938b0217dc6368c832e465c4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94154
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/dbaccess/source/ui/control/RelationControl.cxx b/dbaccess/source/ui/control/RelationControl.cxx
index 14c923c..041e7a5 100644
--- a/dbaccess/source/ui/control/RelationControl.cxx
+++ b/dbaccess/source/ui/control/RelationControl.cxx
@@ -218,7 +218,8 @@ namespace dbaui
        long nRow = GetCurRow();
        if ( nRow != BROWSER_ENDOFSELECTION )
        {
            OUString sFieldName(m_pListCell->GetSelectedEntry());
            weld::ComboBox& rListBox = m_pListCell->get_widget();
            OUString sFieldName(rListBox.get_active_text());
            OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList();
            if ( rLines.size() <= o3tl::make_unsigned(nRow) )
            {
@@ -307,14 +308,15 @@ namespace dbaui

        fillListBox(xDef);
        OUString sName = GetCellText( nRow, nColumnId );
        m_pListCell->SelectEntry( sName );
        if ( m_pListCell->GetSelectedEntry() != sName )
        weld::ComboBox& rList = m_pListCell->get_widget();
        rList.set_active_text(sName);
        if (rList.get_active_text() != sName)
        {
            m_pListCell->InsertEntry( sName );
            m_pListCell->SelectEntry( sName );
            rList.append_text(sName);
            rList.set_active_text(sName);
        }

        m_pListCell->SetHelpId(sHelpId);
        rList.set_help_id(sHelpId);
    }

    CellController* ORelationControl::GetController( long /*nRow*/, sal_uInt16 /*nColumnId*/ )
@@ -348,7 +350,8 @@ namespace dbaui
    }
    void ORelationControl::fillListBox(const Reference< XPropertySet>& _xDest)
    {
        m_pListCell->Clear();
        weld::ComboBox& rList = m_pListCell->get_widget();
        rList.clear();
        try
        {
            if ( _xDest.is() )
@@ -361,9 +364,9 @@ namespace dbaui
                const OUString* pEnd = pIter + aNames.getLength();
                for(;pIter != pEnd;++pIter)
                {
                    m_pListCell->InsertEntry( *pIter );
                    rList.append_text(*pIter);
                }
                m_pListCell->InsertEntry(OUString(), 0);
                rList.insert_text(0, OUString());
            }
        }
        catch( const Exception& )
diff --git a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
index 9f11f0e..8676ff2 100644
--- a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
+++ b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
@@ -208,9 +208,10 @@ static constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | Br
            InsertDataColumn(COLUMN_ID_ORDER, sColumnName, nSortOrderColumnWidth, HeaderBarItemBits::STDSTYLE, 1);

            m_pSortingCell = VclPtr<ListBoxControl>::Create(&GetDataWindow());
            m_pSortingCell->InsertEntry(m_sAscendingText);
            m_pSortingCell->InsertEntry(m_sDescendingText);
            m_pSortingCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER );
            weld::ComboBox& rSortingListBox = m_pSortingCell->get_widget();
            rSortingListBox.append_text(m_sAscendingText);
            rSortingListBox.append_text(m_sDescendingText);
            rSortingListBox.set_help_id(HID_DLGINDEX_INDEXDETAILS_SORTORDER);

            nFieldNameWidth -= nSortOrderColumnWidth;
        }
@@ -224,12 +225,13 @@ static constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | Br
        // create the cell controllers
        // for the field name cell
        m_pFieldNameCell = VclPtr<ListBoxControl>::Create(&GetDataWindow());
        m_pFieldNameCell->InsertEntry(OUString());
        m_pFieldNameCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD );
        weld::ComboBox& rNameListBox = m_pFieldNameCell->get_widget();
        rNameListBox.append_text(OUString());
        rNameListBox.set_help_id(HID_DLGINDEX_INDEXDETAILS_FIELD);
        const OUString* pFields = _rAvailableFields.getConstArray();
        const OUString* pFieldsEnd = pFields + _rAvailableFields.getLength();
        for (;pFields < pFieldsEnd; ++pFields)
            m_pFieldNameCell->InsertEntry(*pFields);
            rNameListBox.append_text(*pFields);
    }

    CellController* IndexFieldsControl::GetController(long _nRow, sal_uInt16 _nColumnId)
@@ -280,7 +282,8 @@ static constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | Br
        {
            case COLUMN_ID_FIELDNAME:
            {
                OUString sFieldSelected = m_pFieldNameCell->GetSelectedEntry();
                weld::ComboBox& rNameListBox = m_pFieldNameCell->get_widget();
                OUString sFieldSelected = rNameListBox.get_active_text();
                bool bEmptySelected = sFieldSelected.isEmpty();
                if (isNewField())
                {
@@ -326,8 +329,9 @@ static constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | Br
            {
                OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
                // selected entry
                sal_Int32 nPos = m_pSortingCell->GetSelectedEntryPos();
                OSL_ENSURE(LISTBOX_ENTRY_NOTFOUND != nPos, "IndexFieldsControl::SaveModified: how did you get this selection??");
                weld::ComboBox& rSortingListBox = m_pSortingCell->get_widget();
                sal_Int32 nPos = rSortingListBox.get_active();
                OSL_ENSURE(nPos != -1, "IndexFieldsControl::SaveModified: how did you get this selection??");
                // adjust the sort flag in the index field description
                OIndexField& rCurrentField = m_aFields[GetCurRow()];
                rCurrentField.bSortAscending = (0 == nPos);
@@ -348,14 +352,20 @@ static constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | Br
        switch (_nColumnId)
        {
            case COLUMN_ID_FIELDNAME:
                m_pFieldNameCell->SelectEntry(bNewField ? OUString() : aFieldDescription->sFieldName);
                m_pFieldNameCell->SaveValue();
            {
                weld::ComboBox& rNameListBox = m_pFieldNameCell->get_widget();
                rNameListBox.set_active_text(bNewField ? OUString() : aFieldDescription->sFieldName);
                rNameListBox.save_value();
                break;
            }

            case COLUMN_ID_ORDER:
                m_pSortingCell->SelectEntry(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText);
                m_pSortingCell->SaveValue();
            {
                weld::ComboBox& rSortingListBox = m_pSortingCell->get_widget();
                rSortingListBox.set_active_text(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText);
                rSortingListBox.save_value();
                break;
            }

            default:
                OSL_FAIL("IndexFieldsControl::InitController: invalid column id!");
@@ -364,17 +374,17 @@ static constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | Br

    IMPL_LINK( IndexFieldsControl, OnListEntrySelected, DbaMouseDownListBoxController&, rController, void )
    {
        ListBoxControl& rListBox = rController.GetListBox();
        if (!rListBox.IsTravelSelect())
        weld::ComboBox& rListBox = rController.GetListBox();
        if (!rListBox.get_popup_shown())
            m_aModifyHdl.Call(*this);

        if (&rListBox != m_pFieldNameCell.get())
        if (&rListBox != &m_pFieldNameCell->get_widget())
            return;

// a field has been selected
        if (GetCurRow() >= GetRowCount() - 2)
        {   // and we're in one of the last two rows
            OUString sSelectedEntry = m_pFieldNameCell->GetSelectedEntry();
            OUString sSelectedEntry = rListBox.get_active_text();
            sal_Int32 nCurrentRow = GetCurRow();
            sal_Int32 rowCount = GetRowCount();

diff --git a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
index c2b4cd9..98d782d 100644
--- a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
+++ b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
@@ -121,14 +121,15 @@ OSelectionBrowseBox::OSelectionBrowseBox( vcl::Window* pParent )

    m_pTextCell     = VclPtr<Edit>::Create(&GetDataWindow(), 0);
    m_pVisibleCell  = VclPtr<CheckBoxControl>::Create(&GetDataWindow());
    m_pTableCell    = VclPtr<ListBoxControl>::Create(&GetDataWindow());     m_pTableCell->SetDropDownLineCount( 20 );
    m_pTableCell    = VclPtr<ListBoxControl>::Create(&GetDataWindow());
    m_pFieldCell    = VclPtr<ComboBoxControl>::Create(&GetDataWindow());
    m_pOrderCell    = VclPtr<ListBoxControl>::Create(&GetDataWindow());
    m_pFunctionCell = VclPtr<ListBoxControl>::Create(&GetDataWindow());     m_pFunctionCell->SetDropDownLineCount( 20 );
    m_pFunctionCell = VclPtr<ListBoxControl>::Create(&GetDataWindow());

    m_pVisibleCell->SetHelpId(HID_QRYDGN_ROW_VISIBLE);
    m_pTableCell->SetHelpId(HID_QRYDGN_ROW_TABLE);
    m_pFieldCell->SetHelpId(HID_QRYDGN_ROW_FIELD);
    weld::ComboBox& rOrderBox = m_pOrderCell->get_widget();
    m_pOrderCell->SetHelpId(HID_QRYDGN_ROW_ORDER);
    m_pFunctionCell->SetHelpId(HID_QRYDGN_ROW_FUNCTION);

@@ -141,7 +142,7 @@ OSelectionBrowseBox::OSelectionBrowseBox( vcl::Window* pParent )

    const OUString aTxt(DBA_RES(STR_QUERY_SORTTEXT));
    for (sal_Int32 nIdx {0}; nIdx>=0;)
        m_pOrderCell->InsertEntry(aTxt.getToken(0, ';', nIdx));
        rOrderBox.append_text(aTxt.getToken(0, ';', nIdx));

    m_bVisibleRow.insert(m_bVisibleRow.end(), BROW_ROW_CNT, true);

@@ -202,13 +203,15 @@ void OSelectionBrowseBox::initialize()
        // We slip in a few optionals one, too.
        if ( lcl_SupportsCoreSQLGrammar(xConnection) )
        {
            weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
            for (sal_Int32 nIdx {0}; nIdx>=0;)
                m_pFunctionCell->InsertEntry(m_aFunctionStrings.getToken(0, ';', nIdx));
                rComboBox.append_text(m_aFunctionStrings.getToken(0, ';', nIdx));
        }
        else // else only COUNT(*) and COUNT("table".*)
        {
            m_pFunctionCell->InsertEntry(m_aFunctionStrings.getToken(0, ';'));
            m_pFunctionCell->InsertEntry(m_aFunctionStrings.getToken(2, ';')); // 2 -> COUNT
            weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
            rComboBox.append_text(m_aFunctionStrings.getToken(0, ';'));
            rComboBox.append_text(m_aFunctionStrings.getToken(2, ';')); // 2 -> COUNT
        }
        try
        {
@@ -493,18 +496,19 @@ void OSelectionBrowseBox::InitController(CellControllerRef& /*rController*/, lon
        }   break;
        case BROW_TABLE_ROW:
        {
            m_pTableCell->Clear();
            enableControl(pEntry,m_pTableCell);
            weld::ComboBox& rComboBox = m_pTableCell->get_widget();
            rComboBox.clear();
            enableControl(pEntry, m_pTableCell);
            if ( !pEntry->isCondition() )
            {
                for (auto const& tabWin : getDesignView()->getTableView()->GetTabWinMap())
                    m_pTableCell->InsertEntry(static_cast<OQueryTableWindow*>(tabWin.second.get())->GetAliasName());
                    rComboBox.append_text(static_cast<OQueryTableWindow*>(tabWin.second.get())->GetAliasName());

                m_pTableCell->InsertEntry(DBA_RES(STR_QUERY_NOTABLE), 0);
                rComboBox.insert_text(0, DBA_RES(STR_QUERY_NOTABLE));
                if (!pEntry->GetAlias().isEmpty())
                    m_pTableCell->SelectEntry(pEntry->GetAlias());
                    rComboBox.set_active_text(pEntry->GetAlias());
                else
                    m_pTableCell->SelectEntry(DBA_RES(STR_QUERY_NOTABLE));
                    rComboBox.set_active_text(DBA_RES(STR_QUERY_NOTABLE));
            }
        }   break;
        case BROW_VIS_ROW:
@@ -531,10 +535,13 @@ void OSelectionBrowseBox::InitController(CellControllerRef& /*rController*/, lon
            }
        }   break;
        case BROW_ORDER_ROW:
            m_pOrderCell->SelectEntryPos(
        {
            weld::ComboBox& rComboBox = m_pOrderCell->get_widget();
            rComboBox.set_active(
                sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()));
            enableControl(pEntry,m_pOrderCell);
            break;
        }
        case BROW_COLUMNALIAS_ROW:
            setTextCellContext(pEntry,pEntry->GetFieldAlias(),HID_QRYDGN_ROW_ALIAS);
            break;
@@ -983,9 +990,10 @@ bool OSelectionBrowseBox::SaveModified()

            case BROW_TABLE_ROW:
            {
                OUString aAliasName = m_pTableCell->GetSelectedEntry();
                weld::ComboBox& rComboBox = m_pTableCell->get_widget();
                OUString aAliasName = rComboBox.get_active_text();
                strOldCellContents = pEntry->GetAlias();
                if ( m_pTableCell->GetSelectedEntryPos() != 0 )
                if (rComboBox.get_active() != 0)
                {
                    pEntry->SetAlias(aAliasName);
                    // we have to set the table name as well as the table window
@@ -1014,8 +1022,9 @@ bool OSelectionBrowseBox::SaveModified()
            case BROW_ORDER_ROW:
            {
                strOldCellContents = OUString::number(static_cast<sal_uInt16>(pEntry->GetOrderDir()));
                sal_Int32 nIdx = m_pOrderCell->GetSelectedEntryPos();
                if (nIdx == LISTBOX_ENTRY_NOTFOUND)
                weld::ComboBox& rComboBox = m_pOrderCell->get_widget();
                sal_Int32 nIdx = rComboBox.get_active();
                if (nIdx == -1)
                    nIdx = 0;
                pEntry->SetOrderDir(EOrderDir(nIdx));
                if(!m_bOrderByUnRelated)
@@ -1035,9 +1044,10 @@ bool OSelectionBrowseBox::SaveModified()
            case BROW_FUNCTION_ROW:
                {
                    strOldCellContents = pEntry->GetFunction();
                    sal_Int32 nPos = m_pFunctionCell->GetSelectedEntryPos();
                    weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
                    sal_Int32 nPos = rComboBox.get_active();
                    // these functions are only available in CORE
                    OUString sFunctionName        = m_pFunctionCell->GetEntry(nPos);
                    OUString sFunctionName        = rComboBox.get_text(nPos);
                    OUString sGroupFunctionName   = m_aFunctionStrings.copy(m_aFunctionStrings.lastIndexOf(';')+1);
                    bool bGroupBy = false;
                    if ( sGroupFunctionName == sFunctionName ) // check if the function name is GROUP
@@ -1856,9 +1866,10 @@ void OSelectionBrowseBox::CellModified()
            {
                OTableFieldDescRef  pEntry = getEntry(GetColumnPos(GetCurColumnId()) - 1);

                sal_Int32 nIdx = m_pOrderCell->GetSelectedEntryPos();
                weld::ComboBox& rComboBox = m_pOrderCell->get_widget();
                sal_Int32 nIdx = rComboBox.get_active();
                if(!m_bOrderByUnRelated && nIdx > 0 &&
                    nIdx != LISTBOX_ENTRY_NOTFOUND  &&
                    nIdx != -1 &&
                    !pEntry->IsEmpty()              &&
                    pEntry->GetOrderDir() != ORDER_NONE)
                {
@@ -2137,52 +2148,53 @@ OUString OSelectionBrowseBox::GetCellText(long nRow, sal_uInt16 nColId) const

bool OSelectionBrowseBox::GetFunctionName(sal_uInt32 _nFunctionTokenId, OUString& rFkt)
{
    weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
    switch(_nFunctionTokenId)
    {
        case SQL_TOKEN_COUNT:
            rFkt = (m_pFunctionCell->GetEntryCount() < 3) ? m_pFunctionCell->GetEntry(1) : m_pFunctionCell->GetEntry(2);
            rFkt = (rComboBox.get_count() < 3) ? rComboBox.get_text(1) : rComboBox.get_text(2);
            break;
        case SQL_TOKEN_AVG:
            rFkt = m_pFunctionCell->GetEntry(1);
            rFkt = rComboBox.get_text(1);
            break;
        case SQL_TOKEN_MAX:
            rFkt = m_pFunctionCell->GetEntry(3);
            rFkt = rComboBox.get_text(3);
            break;
        case SQL_TOKEN_MIN:
            rFkt = m_pFunctionCell->GetEntry(4);
            rFkt = rComboBox.get_text(4);
            break;
        case SQL_TOKEN_SUM:
            rFkt = m_pFunctionCell->GetEntry(5);
            rFkt = rComboBox.get_text(5);
            break;
        case SQL_TOKEN_EVERY:
            rFkt = m_pFunctionCell->GetEntry(6);
            rFkt = rComboBox.get_text(6);
            break;
        case SQL_TOKEN_ANY:
            rFkt = m_pFunctionCell->GetEntry(7);
            rFkt = rComboBox.get_text(7);
            break;
        case SQL_TOKEN_SOME:
            rFkt = m_pFunctionCell->GetEntry(8);
            rFkt = rComboBox.get_text(8);
            break;
        case SQL_TOKEN_STDDEV_POP:
            rFkt = m_pFunctionCell->GetEntry(9);
            rFkt = rComboBox.get_text(9);
            break;
        case SQL_TOKEN_STDDEV_SAMP:
            rFkt = m_pFunctionCell->GetEntry(10);
            rFkt = rComboBox.get_text(10);
            break;
        case SQL_TOKEN_VAR_SAMP:
            rFkt = m_pFunctionCell->GetEntry(11);
            rFkt = rComboBox.get_text(11);
            break;
        case SQL_TOKEN_VAR_POP:
            rFkt = m_pFunctionCell->GetEntry(12);
            rFkt = rComboBox.get_text(12);
            break;
        case SQL_TOKEN_COLLECT:
            rFkt = m_pFunctionCell->GetEntry(13);
            rFkt = rComboBox.get_text(13);
            break;
        case SQL_TOKEN_FUSION:
            rFkt = m_pFunctionCell->GetEntry(14);
            rFkt = rComboBox.get_text(14);
            break;
        case SQL_TOKEN_INTERSECTION:
            rFkt = m_pFunctionCell->GetEntry(15);
            rFkt = rComboBox.get_text(15);
            break;
        default:
            {
@@ -2218,8 +2230,8 @@ OUString OSelectionBrowseBox::GetCellContents(sal_Int32 nCellIndex, sal_uInt16 n
            return pEntry->IsVisible() ? OUStringLiteral("1") : OUStringLiteral("0");
        case BROW_ORDER_ROW:
        {
            sal_Int32 nIdx = m_pOrderCell->GetSelectedEntryPos();
            if (nIdx == LISTBOX_ENTRY_NOTFOUND)
            sal_Int32 nIdx = m_pOrderCell->get_widget().get_active();
            if (nIdx == -1)
                nIdx = 0;
            return OUString::number(nIdx);
        }
@@ -2608,10 +2620,11 @@ void OSelectionBrowseBox::setFunctionCell(OTableFieldDescRef const & _pEntry)
    {
        sal_Int32 nIdx {0};
        // if we have an asterisk, no other function than count is allowed
        m_pFunctionCell->Clear();
        m_pFunctionCell->InsertEntry(m_aFunctionStrings.getToken(0, ';', nIdx));
        weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
        rComboBox.clear();
        rComboBox.append_text(m_aFunctionStrings.getToken(0, ';', nIdx));
        if ( isFieldNameAsterisk(_pEntry->GetField()) )
            m_pFunctionCell->InsertEntry(m_aFunctionStrings.getToken(1, ';', nIdx)); // 2nd token: COUNT
            rComboBox.append_text(m_aFunctionStrings.getToken(1, ';', nIdx)); // 2nd token: COUNT
        else
        {
            const bool bSkipLastToken {_pEntry->isNumeric()};
@@ -2620,36 +2633,37 @@ void OSelectionBrowseBox::setFunctionCell(OTableFieldDescRef const & _pEntry)
                const OUString sTok {m_aFunctionStrings.getToken(0, ';', nIdx)};
                if (bSkipLastToken && nIdx<0)
                    break;
                m_pFunctionCell->InsertEntry(sTok);
                rComboBox.append_text(sTok);
            }
        }

        if ( _pEntry->IsGroupBy() )
        {
            OSL_ENSURE(!_pEntry->isNumeric(),"Not allowed to combine group by and numeric values!");
            m_pFunctionCell->SelectEntry(m_pFunctionCell->GetEntry(m_pFunctionCell->GetEntryCount() - 1));
            rComboBox.set_active_text(rComboBox.get_text(rComboBox.get_count() - 1));
        }
        else if ( m_pFunctionCell->GetEntryPos(_pEntry->GetFunction()) != LISTBOX_ENTRY_NOTFOUND )
            m_pFunctionCell->SelectEntry(_pEntry->GetFunction());
        else if (rComboBox.find_text(_pEntry->GetFunction()) != -1)
            rComboBox.set_active_text(_pEntry->GetFunction());
        else
            m_pFunctionCell->SelectEntryPos(0);
            rComboBox.set_active(0);

        enableControl(_pEntry,m_pFunctionCell);
        enableControl(_pEntry, m_pFunctionCell);
    }
    else
    {
        // only COUNT(*) and COUNT("table".*) allowed
        bool bCountRemoved = !isFieldNameAsterisk(_pEntry->GetField());
        weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
        if ( bCountRemoved )
            m_pFunctionCell->RemoveEntry(1);
            rComboBox.remove(1);

        if ( !bCountRemoved && m_pFunctionCell->GetEntryCount() < 2)
            m_pFunctionCell->InsertEntry(m_aFunctionStrings.getToken(2, ';')); // 2 -> COUNT
        if ( !bCountRemoved && rComboBox.get_count() < 2)
            rComboBox.append_text(m_aFunctionStrings.getToken(2, ';')); // 2 -> COUNT

        if(m_pFunctionCell->GetEntryPos(_pEntry->GetFunction()) != LISTBOX_ENTRY_NOTFOUND)
            m_pFunctionCell->SelectEntry(_pEntry->GetFunction());
        if (rComboBox.find_text(_pEntry->GetFunction()) != -1)
            rComboBox.set_active_text(_pEntry->GetFunction());
        else
            m_pFunctionCell->SelectEntryPos(0);
            rComboBox.set_active(0);
    }
}

diff --git a/dbaccess/source/ui/tabledesign/TEditControl.cxx b/dbaccess/source/ui/tabledesign/TEditControl.cxx
index 76300c5..a17cf27 100644
--- a/dbaccess/source/ui/tabledesign/TEditControl.cxx
+++ b/dbaccess/source/ui/tabledesign/TEditControl.cxx
@@ -209,7 +209,6 @@ void OTableEditorCtrl::InitCellController()

    // Cell type
    pTypeCell = VclPtr<ListBoxControl>::Create( &GetDataWindow() );
    pTypeCell->SetDropDownLineCount( 15 );

    // Cell description
    pDescrCell = VclPtr<Edit>::Create( &GetDataWindow(), WB_LEFT );
@@ -241,7 +240,7 @@ void OTableEditorCtrl::ClearModified()
    pNameCell->ClearModifyFlag();
    pDescrCell->ClearModifyFlag();
    pHelpTextCell->ClearModifyFlag();
    pTypeCell->SaveValue();
    pTypeCell->get_widget().save_value();
}

OTableEditorCtrl::~OTableEditorCtrl()
@@ -367,14 +366,15 @@ void OTableEditorCtrl::InitController(CellControllerRef&, long nRow, sal_uInt16 
                    aInitString = pActFieldDescr->getTypeInfo()->aUIName;

                // Set the ComboBox contents
                pTypeCell->Clear();
                weld::ComboBox& rTypeList = pTypeCell->get_widget();
                rTypeList.clear();
                if( !pActFieldDescr )
                    break;

                const OTypeInfoMap& rTypeInfo = GetView()->getController().getTypeInfo();
                for (auto const& elem : rTypeInfo)
                    pTypeCell->InsertEntry( elem.second->aUIName );
                pTypeCell->SelectEntry( aInitString );
                    rTypeList.append_text(elem.second->aUIName);
                rTypeList.set_active_text(aInitString);
            }

            break;
@@ -681,8 +681,8 @@ void OTableEditorCtrl::CellModified( long nRow, sal_uInt16 nColId )

void OTableEditorCtrl::resetType()
{
    sal_Int32 nPos = pTypeCell->GetSelectedEntryPos();
    if(nPos != LISTBOX_ENTRY_NOTFOUND)
    sal_Int32 nPos = pTypeCell->get_widget().get_active();
    if(nPos != -1)
        SwitchType( GetView()->getController().getTypeInfo(nPos) );
    else
        SwitchType(TOTypeInfoSP());
@@ -1564,9 +1564,10 @@ void OTableEditorCtrl::SwitchType( const TOTypeInfoSP& _pType )
    pRow->SetFieldType( _pType, true );
    if ( _pType.get() )
    {
        const sal_Int32 nCurrentlySelected = pTypeCell->GetSelectedEntryPos();
        weld::ComboBox& rTypeList = pTypeCell->get_widget();
        const sal_Int32 nCurrentlySelected = rTypeList.get_active();

        if  (   ( LISTBOX_ENTRY_NOTFOUND == nCurrentlySelected )
        if  (   ( nCurrentlySelected == -1 )
            ||  ( GetView()->getController().getTypeInfo( nCurrentlySelected ) != _pType )
            )
        {
@@ -1578,8 +1579,8 @@ void OTableEditorCtrl::SwitchType( const TOTypeInfoSP& _pType )
                    break;
                ++nEntryPos;
            }
            if (nEntryPos < pTypeCell->GetEntryCount())
                pTypeCell->SelectEntryPos( nEntryPos );
            if (nEntryPos < rTypeList.get_count())
                rTypeList.set_active(nEntryPos);
        }
    }

diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index 228edb7..175dbe6 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -26,7 +26,6 @@
#include <svtools/svtdllapi.h>
#include <tools/ref.hxx>
#include <vcl/window.hxx>
#include <vcl/lstbox.hxx>

#include <svtools/brwbox.hxx>
#include <svtools/brwhead.hxx>
@@ -327,6 +326,8 @@ namespace svt

        weld::ComboBox& get_widget() { return *m_xWidget; }

        virtual void dispose() override;

    private:
        std::unique_ptr<weld::ComboBox> m_xWidget;
    };
@@ -348,30 +349,28 @@ namespace svt
        DECL_LINK(ModifyHdl, weld::ComboBox&, void);
    };


    //= ListBoxControl

    class SVT_DLLPUBLIC ListBoxControl final : public ListBox
    class SVT_DLLPUBLIC ListBoxControl final : public InterimItemWindow
    {
        friend class ListBoxCellController;

    public:
        ListBoxControl(vcl::Window* pParent);

        weld::ComboBox& get_widget() { return *m_xWidget; }

        virtual void dispose() override;
    private:
        virtual bool PreNotify( NotifyEvent& rNEvt ) override;
        std::unique_ptr<weld::ComboBox> m_xWidget;
    };


    //= ListBoxCellController

    class SVT_DLLPUBLIC ListBoxCellController : public CellController
    {
    public:

        ListBoxCellController(ListBoxControl* pParent);
        const ListBoxControl& GetListBox() const { return static_cast<const ListBoxControl &>(GetWindow()); }
        ListBoxControl& GetListBox() { return static_cast<ListBoxControl &>(GetWindow()); }
        weld::ComboBox& GetListBox() const { return static_cast<ListBoxControl&>(GetWindow()).get_widget(); }

        virtual bool IsModified() const override;
        virtual void ClearModified() override;
@@ -379,12 +378,10 @@ namespace svt
    protected:
        virtual bool MoveAllowed(const KeyEvent& rEvt) const override;
    private:
        DECL_LINK(ListBoxSelectHdl, ListBox&, void);
        DECL_LINK(ListBoxSelectHdl, weld::ComboBox&, void);
    };


    //= FormattedFieldCellController

    class SVT_DLLPUBLIC FormattedFieldCellController final : public EditCellController
    {
    public:
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index fd73430..d7a9ec2 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -749,6 +749,16 @@ public:
    virtual void set_max_mru_count(int nCount) = 0;
    virtual OUString get_mru_entries() const = 0;
    virtual void set_mru_entries(const OUString& rEntries) = 0;

    // Form Controls List Box related multi-selection support
    // Only SelectionMode::Single or SelectionMode::Multiple are supported.
    // SelectionMode::Multiple mode is basically bizarre but in use in
    // the Form Controls List Box which we seem stuck with
    virtual void set_selection_mode(SelectionMode eMode) = 0;
    virtual void scroll_to_row(int pos) = 0;
    virtual void select(int pos) = 0;
    virtual void unselect(int pos) = 0;
    virtual std::vector<int> get_selected_rows() const = 0;
};

class VCL_DLLPUBLIC TreeIter
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
index 65f333d..b60c71f 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -33,6 +33,12 @@ namespace svt
    {
    }

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

    //= ComboBoxCellController
    ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
                             :CellController(pWin)
@@ -98,51 +104,27 @@ namespace svt

    //= ListBoxControl
    ListBoxControl::ListBoxControl(vcl::Window* pParent)
                  :ListBox(pParent, WB_DROPDOWN|WB_NOBORDER)
        : InterimItemWindow(pParent, "svt/ui/listcontrol.ui", "ListControl")
        , m_xWidget(m_xBuilder->weld_combo_box("listbox"))
    {
        EnableAutoSize(false);
        EnableMultiSelection(false);
        SetDropDownLineCount(20);
    }

    bool ListBoxControl::PreNotify( NotifyEvent& rNEvt )
    void ListBoxControl::dispose()
    {
        if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT && !IsInDropDown())
        {
            const KeyEvent *pEvt = rNEvt.GetKeyEvent();
            const vcl::KeyCode rKey = pEvt->GetKeyCode();

            if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
                (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
            {
                // select next resp. previous entry
                sal_Int32 nPos = GetSelectedEntryPos();
                int nDir = (rKey.GetCode() == KEY_DOWN ? 1 : -1);
                if (!((nPos == 0 && nDir == -1) || (nPos >= GetEntryCount() && nDir == 1)))
                {
                    nPos += nDir;
                    SelectEntryPos(nPos);
                }
                Select();   // for calling Modify
                return true;
            }
            else if (GetParent()->PreNotify(rNEvt))
                return true;
        }
        return ListBox::PreNotify(rNEvt);
        m_xWidget.reset();
        InterimItemWindow::dispose();
    }

    //= ListBoxCellController
    ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
                             :CellController(pWin)
    {
        GetListBox().SetSelectHdl(LINK(this, ListBoxCellController, ListBoxSelectHdl));
        GetListBox().connect_changed(LINK(this, ListBoxCellController, ListBoxSelectHdl));
    }


    bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
    {
        const ListBoxControl& rBox = GetListBox();
        const weld::ComboBox& rBox = GetListBox();
        switch (rEvt.GetKeyCode().GetCode())
        {
            case KEY_UP:
@@ -157,7 +139,7 @@ namespace svt
                [[fallthrough]];
            case KEY_PAGEUP:
            case KEY_PAGEDOWN:
                if (rBox.IsTravelSelect())
                if (rBox.get_popup_shown())
                    return false;
                [[fallthrough]];
            default:
@@ -165,28 +147,22 @@ namespace svt
        }
    }


    bool ListBoxCellController::IsModified() const
    {
        return GetListBox().IsValueChangedFromSaved();
        return GetListBox().get_value_changed_from_saved();
    }


    void ListBoxCellController::ClearModified()
    {
        GetListBox().SaveValue();
        GetListBox().save_value();
    }


    IMPL_LINK_NOARG(ListBoxCellController, ListBoxSelectHdl, ListBox&, void)
    IMPL_LINK_NOARG(ListBoxCellController, ListBoxSelectHdl, weld::ComboBox&, void)
    {
        callModifyHdl();
    }


    //= CheckBoxControl


    CheckBoxControl::CheckBoxControl(vcl::Window* pParent)
                   :Control(pParent, 0)
    {
@@ -210,7 +186,6 @@ namespace svt
        pBox->Show();
    }


    CheckBoxControl::~CheckBoxControl()
    {
        disposeOnce();
diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index 82b3b41..2eef5e6 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -2502,7 +2502,6 @@ DbListBox::DbListBox(DbGridColumn& _rColumn)
    doPropertyListening( FM_PROP_LINECOUNT );
}


void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent )
{
    if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
@@ -2515,12 +2514,13 @@ void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent
    }
}


void DbListBox::SetList(const Any& rItems)
{
    ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());

    pField->Clear();
    weld::ComboBox& rFieldList = pField->get_widget();

    rFieldList.clear();
    m_bBound = false;

    css::uno::Sequence<OUString> aTest;
@@ -2529,7 +2529,7 @@ void DbListBox::SetList(const Any& rItems)
        if (aTest.hasElements())
        {
            for (const OUString& rString : std::as_const(aTest))
                 pField->InsertEntry(rString);
                 rFieldList.append_text(rString);

            m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
            m_bBound = m_aValueList.hasElements();
@@ -2540,7 +2540,6 @@ void DbListBox::SetList(const Any& rItems)
    }
}


void DbListBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
{
    m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
@@ -2555,25 +2554,16 @@ void DbListBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
    DbCellControl::Init( rParent, xCursor );
}


void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*rxModel*/ )
{
    DBG_ASSERT( m_pWindow, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
    DBG_ASSERT( _rxModel.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
    if ( m_pWindow && _rxModel.is() )
    {
        sal_Int16  nLines   = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
        static_cast< ListBoxControl* >( m_pWindow.get() )->SetDropDownLineCount( nLines );
    }
    // ignore FM_PROP_LINECOUNT
}


CellControllerRef DbListBox::CreateController() const
{
    return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
}


OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
{
    OUString sText;
@@ -2586,7 +2576,7 @@ OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField
            {
                sal_Int32 nPos = ::comphelper::findValue( m_aValueList, sText );
                if ( nPos != -1 )
                    sText = static_cast<ListBox*>(m_pWindow.get())->GetEntry(nPos);
                    sText = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget().get_text(nPos);
                else
                    sText.clear();
            }
@@ -2599,17 +2589,16 @@ OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField
    return sText;
}


void DbListBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
{
    OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
    weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
    if (!sFormattedText.isEmpty())
        static_cast< ListBox* >( m_pWindow.get() )->SelectEntry( sFormattedText );
        rComboBox.set_active_text(sFormattedText);
    else
        static_cast< ListBox* >( m_pWindow.get() )->SetNoSelection();
        rComboBox.set_active(-1);
}


void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
{
    OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
@@ -2621,23 +2610,24 @@ void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
    if ( aSelection.hasElements() )
        nSelection = aSelection[ 0 ];

    ListBox* pListBox = static_cast< ListBox* >( m_pWindow.get() );
    weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();

    if ( ( nSelection >= 0 ) && ( nSelection < pListBox->GetEntryCount() ) )
        pListBox->SelectEntryPos( nSelection );
    if (nSelection >= 0 && nSelection < rComboBox.get_count())
        rComboBox.set_active(nSelection);
    else
        pListBox->SetNoSelection( );
        rComboBox.set_active(-1);
}


bool DbListBox::commitControl()
{
    Any aVal;
    Sequence<sal_Int16> aSelectSeq;
    if (static_cast<ListBox*>(m_pWindow.get())->GetSelectedEntryCount())
    weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
    auto nActive = rComboBox.get_active();
    if (nActive != -1)
    {
        aSelectSeq.realloc(1);
        *aSelectSeq.getArray() = static_cast<sal_Int16>(static_cast<ListBox*>(m_pWindow.get())->GetSelectedEntryPos());
        *aSelectSeq.getArray() = static_cast<sal_Int16>(nActive);
    }
    aVal <<= aSelectSeq;
    m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
@@ -2655,7 +2645,6 @@ DbFilterField::DbFilterField(const Reference< XComponentContext >& rxContext,DbG
    setAlignedController( false );
}


DbFilterField::~DbFilterField()
{
    if (m_nControlClass == css::form::FormComponentType::CHECKBOX)
@@ -2663,7 +2652,6 @@ DbFilterField::~DbFilterField()

}


void DbFilterField::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
{
    static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
@@ -2673,14 +2661,13 @@ void DbFilterField::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
            DbCellControl::PaintCell( rDev, rRect );
            break;
        case FormComponentType::LISTBOX:
            rDev.DrawText(rRect, static_cast<ListBox*>(m_pWindow.get())->GetSelectedEntry(), nStyle);
            rDev.DrawText(rRect, static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().get_active_text(), nStyle);
            break;
        default:
            rDev.DrawText(rRect, m_aText, nStyle);
    }
}


void DbFilterField::SetList(const Any& rItems, bool bComboBox)
{
    css::uno::Sequence<OUString> aTest;
@@ -2696,16 +2683,16 @@ void DbFilterField::SetList(const Any& rItems, bool bComboBox)
        }
        else
        {
            ListBox* pField = static_cast<ListBox*>(m_pWindow.get());
            ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
            weld::ComboBox& rFieldBox = pField->get_widget();
            for (const OUString& rString : std::as_const(aTest))
                pField->InsertEntry(rString);
                rFieldBox.append_text(rString);

            m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
        }
    }
}


void DbFilterField::CreateControl(vcl::Window* pParent, const Reference< css::beans::XPropertySet >& xModel)
{
    switch (m_nControlClass)
@@ -2722,10 +2709,8 @@ void DbFilterField::CreateControl(vcl::Window* pParent, const Reference< css::be
        case css::form::FormComponentType::LISTBOX:
        {
            m_pWindow = VclPtr<ListBoxControl>::Create(pParent);
            sal_Int16  nLines       = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
            Any  aItems      = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
            Any  aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
            SetList(aItems, false);
            static_cast<ListBox*>(m_pWindow.get())->SetDropDownLineCount(nLines);
        }   break;
        case css::form::FormComponentType::COMBOBOX:
        {
@@ -2837,10 +2822,13 @@ bool DbFilterField::commitControl()
        case css::form::FormComponentType::CHECKBOX:
            return true;
        case css::form::FormComponentType::LISTBOX:
        {
            aText.clear();
            if (static_cast<ListBox*>(m_pWindow.get())->GetSelectedEntryCount())
            weld::ComboBox& rComboBox = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget();
            auto nActive = rComboBox.get_active();
            if (nActive != -1)
            {
                sal_Int16 nPos = static_cast<sal_Int16>(static_cast<ListBox*>(m_pWindow.get())->GetSelectedEntryPos());
                sal_Int16 nPos = static_cast<sal_Int16>(nActive);
                if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
                    aText = m_aValueList.getConstArray()[nPos];
            }
@@ -2851,6 +2839,7 @@ bool DbFilterField::commitControl()
                m_aCommitLink.Call(*this);
            }
            return true;
        }
        default:
            aText = m_pWindow->GetText();
    }
@@ -2927,10 +2916,7 @@ void DbFilterField::SetText(const OUString& rText)
        case css::form::FormComponentType::LISTBOX:
        {
            sal_Int32 nPos = ::comphelper::findValue(m_aValueList, m_aText);
            if (nPos != -1)
                static_cast<ListBox*>(m_pWindow.get())->SelectEntryPos(nPos);
            else
                static_cast<ListBox*>(m_pWindow.get())->SetNoSelection();
            static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().set_active(nPos);
        }   break;
        default:
            m_pWindow->SetText(m_aText);
@@ -3977,16 +3963,16 @@ void FmXCheckBoxCell::onWindowEvent( const VclEventId _nEventId, const vcl::Wind
}

FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl)
               :FmXTextCell( pColumn, std::move(pControl) )
               ,m_aItemListeners(m_aMutex)
               ,m_aActionListeners(m_aMutex)
               ,m_pBox( &static_cast< ListBox& >( m_pCellControl->GetWindow() ) )
  : FmXTextCell(pColumn, std::move(pControl))
  , m_aItemListeners(m_aMutex)
  , m_aActionListeners(m_aMutex)
  , m_pBox(&static_cast<svt::ListBoxControl&>(m_pCellControl->GetWindow()).get_widget())
  , m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
  , m_bMulti(false)
{

    m_pBox->SetDoubleClickHdl( LINK( this, FmXListBoxCell, OnDoubleClick ) );
    m_pBox->connect_changed(LINK(this, FmXListBoxCell, ChangedHdl));
}


FmXListBoxCell::~FmXListBoxCell()
{
    if (!OComponentHelper::rBHelper.bDisposed)
@@ -3994,25 +3980,21 @@ FmXListBoxCell::~FmXListBoxCell()
        acquire();
        dispose();
    }

}

// OComponentHelper

void FmXListBoxCell::disposing()
{
    css::lang::EventObject aEvt(*this);
    m_aItemListeners.disposeAndClear(aEvt);
    m_aActionListeners.disposeAndClear(aEvt);

    m_pBox->SetSelectHdl( Link<ListBox&,void>() );
    m_pBox->SetDoubleClickHdl( Link<ListBox&,void>() );
    m_pBox->connect_changed( Link<weld::ComboBox&,void>() );
    m_pBox = nullptr;

    FmXTextCell::disposing();
}


Any SAL_CALL FmXListBoxCell::queryAggregation( const css::uno::Type& _rType )
{
    Any aReturn = FmXTextCell::queryAggregation(_rType);
@@ -4023,7 +4005,6 @@ Any SAL_CALL FmXListBoxCell::queryAggregation( const css::uno::Type& _rType )
    return aReturn;
}


Sequence< css::uno::Type > SAL_CALL FmXListBoxCell::getTypes(  )
{
    return ::comphelper::concatSequences(
@@ -4032,10 +4013,8 @@ Sequence< css::uno::Type > SAL_CALL FmXListBoxCell::getTypes(  )
    );
}


IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell )


void SAL_CALL FmXListBoxCell::addItemListener(const Reference< css::awt::XItemListener >& l)
{
    m_aItemListeners.addInterface( l );
@@ -4059,15 +4038,13 @@ void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< css::awt::XA
    m_aActionListeners.removeInterface( l );
}


void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if (m_pBox)
        m_pBox->InsertEntry( aItem, nPos );
        m_pBox->insert_text(nPos, aItem);
}


void SAL_CALL FmXListBoxCell::addItems(const css::uno::Sequence<OUString>& aItems, sal_Int16 nPos)
{
    ::osl::MutexGuard aGuard( m_aMutex );
@@ -4076,36 +4053,33 @@ void SAL_CALL FmXListBoxCell::addItems(const css::uno::Sequence<OUString>& aItem
        sal_uInt16 nP = nPos;
        for ( const auto& rItem : aItems )
        {
            m_pBox->InsertEntry( rItem, nP );
            m_pBox->insert_text(nP, rItem);
            if ( nPos != -1 )    // Not if 0xFFFF, because LIST_APPEND
                nP++;
        }
    }
}


void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_pBox )
    {
        for ( sal_uInt16 n = nCount; n; )
            m_pBox->RemoveEntry( nPos + (--n) );
            m_pBox->remove( nPos + (--n) );
    }
}


sal_Int16 SAL_CALL FmXListBoxCell::getItemCount()
{
    ::osl::MutexGuard aGuard( m_aMutex );
    return m_pBox ? m_pBox->GetEntryCount() : 0;
    return m_pBox ? m_pBox->get_count() : 0;
}


OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    return m_pBox ? m_pBox->GetEntry(nPos) : OUString();
    return m_pBox ? m_pBox->get_text(nPos) : OUString();
}

css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getItems()
@@ -4115,25 +4089,24 @@ css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getItems()
    css::uno::Sequence<OUString> aSeq;
    if (m_pBox)
    {
        const sal_Int32 nEntries = m_pBox ->GetEntryCount();
        const sal_Int32 nEntries = m_pBox->get_count();
        aSeq = css::uno::Sequence<OUString>( nEntries );
        for ( sal_Int32 n = nEntries; n; )
        {
            --n;
            aSeq.getArray()[n] = m_pBox ->GetEntry( n );
            aSeq.getArray()[n] = m_pBox->get_text( n );
        }
    }
    return aSeq;
}


sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos()
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if (m_pBox)
    {
        UpdateFromColumn();
        sal_Int32 nPos = m_pBox->GetSelectedEntryPos();
        sal_Int32 nPos = m_pBox->get_active();
        if (nPos > SHRT_MAX || nPos < SHRT_MIN)
            throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
        return nPos;
@@ -4141,7 +4114,6 @@ sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos()
    return 0;
}


Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos()
{
    ::osl::MutexGuard aGuard( m_aMutex );
@@ -4150,10 +4122,11 @@ Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos()
    if (m_pBox)
    {
        UpdateFromColumn();
        const sal_Int32 nSelEntries = m_pBox->GetSelectedEntryCount();
        auto aSelected = m_pBox->get_selected_rows();
        size_t nSelEntries = aSelected.size();
        aSeq = Sequence<sal_Int16>( nSelEntries );
        for ( sal_Int32 n = 0; n < nSelEntries; ++n )
            aSeq.getArray()[n] = m_pBox->GetSelectedEntryPos( n );
        for (size_t n = 0; n < nSelEntries; ++n)
            aSeq.getArray()[n] = aSelected[n];
    }
    return aSeq;
}
@@ -4167,13 +4140,12 @@ OUString SAL_CALL FmXListBoxCell::getSelectedItem()
    if (m_pBox)
    {
        UpdateFromColumn();
        aItem = m_pBox->GetSelectedEntry();
        aItem = m_pBox->get_active_text();
    }

    return aItem;
}


css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getSelectedItems()
{
    ::osl::MutexGuard aGuard( m_aMutex );
@@ -4183,24 +4155,28 @@ css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getSelectedItems()
    if (m_pBox)
    {
        UpdateFromColumn();
        const sal_Int32 nSelEntries = m_pBox->GetSelectedEntryCount();
        auto aSelected = m_pBox->get_selected_rows();
        const size_t nSelEntries = aSelected.size();
        aSeq = css::uno::Sequence<OUString>( nSelEntries );
        for ( sal_Int32 n = 0; n < nSelEntries; ++n )
            aSeq.getArray()[n] = m_pBox->GetSelectedEntry( n );
        for (size_t n = 0; n < nSelEntries; ++n)
            aSeq.getArray()[n] = m_pBox->get_text(aSelected[n]);
    }
    return aSeq;
}


void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if (m_pBox)
        m_pBox->SelectEntryPos( nPos, bSelect );
    {
        if (bSelect)
            m_pBox->select(nPos);
        else
            m_pBox->unselect(nPos);
    }
}


void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect)
{
    ::osl::MutexGuard aGuard( m_aMutex );
@@ -4208,117 +4184,107 @@ void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPosit
    if (m_pBox)
    {
        for ( sal_uInt16 n = static_cast<sal_uInt16>(aPositions.getLength()); n; )
            m_pBox->SelectEntryPos( static_cast<sal_uInt16>(aPositions.getConstArray()[--n]), bSelect );
        {
            auto nPos = static_cast<sal_uInt16>(aPositions.getConstArray()[--n]);
            if (bSelect)
                m_pBox->select(nPos);
            else
                m_pBox->unselect(nPos);
        }
    }
}


void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if (m_pBox)
        m_pBox->SelectEntry( aItem, bSelect );
    {
        auto nPos = m_pBox->find_text(aItem);
        if (bSelect)
            m_pBox->select(nPos);
        else
            m_pBox->unselect(nPos);
    }
}


sal_Bool SAL_CALL FmXListBoxCell::isMutipleMode()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    bool bMulti = false;
    if (m_pBox)
        bMulti = m_pBox->IsMultiSelectionEnabled();
    return bMulti;
    return m_bMulti;
}


void SAL_CALL FmXListBoxCell::setMultipleMode(sal_Bool bMulti)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if (m_pBox)
        m_pBox->EnableMultiSelection( bMulti );
}
    m_bMulti = bMulti;

    if (m_pBox)
        m_pBox->set_selection_mode(bMulti ? SelectionMode::Multiple : SelectionMode::Single);
}

sal_Int16 SAL_CALL FmXListBoxCell::getDropDownLineCount()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    sal_Int16 nLines = 0;
    if (m_pBox)
        nLines = m_pBox->GetDropDownLineCount();

    return nLines;
    return m_nLines;
}


void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if (m_pBox)
        m_pBox->SetDropDownLineCount( nLines );
    m_nLines = nLines; // just store it to return it
}


void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 nEntry)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if (m_pBox)
        m_pBox->SetTopEntry( nEntry );
        m_pBox->scroll_to_row(nEntry);
}


void FmXListBoxCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
IMPL_LINK_NOARG(FmXListBoxCell, ChangedHdl, weld::ComboBox&, void)
{
    if  (   ( &_rWindow == m_pBox )
        &&  ( _nEventId == VclEventId::ListboxSelect )
        )
    {
        OnDoubleClick( *m_pBox );

        css::awt::ItemEvent aEvent;
        aEvent.Source = *this;
        aEvent.Highlighted = 0;

        // with multiple selection 0xFFFF, otherwise the ID
        aEvent.Selected = (m_pBox->GetSelectedEntryCount() == 1 )
            ? m_pBox->GetSelectedEntryPos() : 0xFFFF;

        m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
    if (!m_pBox || !m_pBox->changed_by_direct_pick())
        return;
    }

    FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
    OnDoubleClick();

    css::awt::ItemEvent aEvent;
    aEvent.Source = *this;
    aEvent.Highlighted = 0;

    // with multiple selection 0xFFFF, otherwise the ID
    aEvent.Selected = (m_pBox->get_selected_rows().size() == 1 )
        ? m_pBox->get_active() : 0xFFFF;

    m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
    return;
}


IMPL_LINK_NOARG(FmXListBoxCell, OnDoubleClick, ListBox&, void)
void FmXListBoxCell::OnDoubleClick()
{
    if (m_pBox)
    {
        ::comphelper::OInterfaceIteratorHelper2 aIt( m_aActionListeners );
    ::comphelper::OInterfaceIteratorHelper2 aIt( m_aActionListeners );

        css::awt::ActionEvent aEvent;
        aEvent.Source = *this;
        aEvent.ActionCommand = m_pBox->GetSelectedEntry();
    css::awt::ActionEvent aEvent;
    aEvent.Source = *this;
    aEvent.ActionCommand = m_pBox->get_active_text();

        while( aIt.hasMoreElements() )
            static_cast< css::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
    }
    while( aIt.hasMoreElements() )
        static_cast< css::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
}

FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
    :FmXTextCell( pColumn, std::move(pControl) )
    ,m_aItemListeners( m_aMutex )
    ,m_aActionListeners( m_aMutex )
    ,m_rComboBox(static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()).get_widget())
    ,m_pComboBox(&static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()).get_widget())
    ,m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
{
    m_rComboBox.connect_changed(LINK(this, FmXComboBoxCell, ChangedHdl));
    m_pComboBox->connect_changed(LINK(this, FmXComboBoxCell, ChangedHdl));
}

FmXComboBoxCell::~FmXComboBoxCell()
@@ -4337,6 +4303,9 @@ void FmXComboBoxCell::disposing()
    m_aItemListeners.disposeAndClear(aEvt);
    m_aActionListeners.disposeAndClear(aEvt);

    m_pComboBox->connect_changed( Link<weld::ComboBox&,void>() );
    m_pComboBox = nullptr;

    FmXTextCell::disposing();
}

@@ -4384,16 +4353,20 @@ void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActio
void SAL_CALL FmXComboBoxCell::addItem( const OUString& Item, sal_Int16 Pos )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    m_rComboBox.insert_text(Pos, Item);
    if (!m_pComboBox)
        return;
    m_pComboBox->insert_text(Pos, Item);
}

void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_Int16 Pos )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if (!m_pComboBox)
        return;
    sal_uInt16 nP = Pos;
    for ( const auto& rItem : Items )
    {
        m_rComboBox.insert_text(nP, rItem);
        m_pComboBox->insert_text(nP, rItem);
        if ( Pos != -1 )
            nP++;
    }
@@ -4402,20 +4375,26 @@ void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_
void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 Pos, sal_Int16 Count )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if (!m_pComboBox)
        return;
    for ( sal_uInt16 n = Count; n; )
        m_rComboBox.remove( Pos + (--n) );
        m_pComboBox->remove( Pos + (--n) );
}

sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount()
{
    ::osl::MutexGuard aGuard( m_aMutex );
    return m_rComboBox.get_count();
    if (!m_pComboBox)
        return 0;
    return m_pComboBox->get_count();
}

OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 Pos )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    return m_rComboBox.get_text(Pos);
    if (!m_pComboBox)
        return OUString();
    return m_pComboBox->get_text(Pos);
}

Sequence< OUString > SAL_CALL FmXComboBoxCell::getItems()
@@ -4423,11 +4402,14 @@ Sequence< OUString > SAL_CALL FmXComboBoxCell::getItems()
    ::osl::MutexGuard aGuard( m_aMutex );

    Sequence< OUString > aItems;
    const sal_Int32 nEntries = m_rComboBox.get_count();
    aItems.realloc( nEntries );
    OUString* pItem = aItems.getArray();
    for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
        *pItem = m_rComboBox.get_text(n);
    if (m_pComboBox)
    {
        const sal_Int32 nEntries = m_pComboBox->get_count();
        aItems.realloc( nEntries );
        OUString* pItem = aItems.getArray();
        for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
            *pItem = m_pComboBox->get_text(n);
    }
    return aItems;
}

@@ -4440,13 +4422,12 @@ sal_Int16 SAL_CALL FmXComboBoxCell::getDropDownLineCount()
void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    // just store it to return it
    m_nLines = nLines;
    m_nLines = nLines; // just store it to return it
}

IMPL_LINK_NOARG(FmXComboBoxCell, ChangedHdl, weld::ComboBox&, void)
{
    if (!m_rComboBox.changed_by_direct_pick())
    if (!m_pComboBox || !m_pComboBox->changed_by_direct_pick())
        return;

    awt::ItemEvent aEvent;
@@ -4454,8 +4435,8 @@ IMPL_LINK_NOARG(FmXComboBoxCell, ChangedHdl, weld::ComboBox&, void)
    aEvent.Highlighted = 0;

    // with invalid selection 0xFFFF, otherwise the position
    aEvent.Selected =   ( m_rComboBox.get_active() != -1 )
                    ?   m_rComboBox.get_active()
    aEvent.Selected =   ( m_pComboBox->get_active() != -1 )
                    ?   m_pComboBox->get_active()
                    :   0xFFFF;
    m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
}
diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx
index f30d96c8..360e6d8 100644
--- a/svx/source/inc/gridcell.hxx
+++ b/svx/source/inc/gridcell.hxx
@@ -993,14 +993,17 @@ public:
    virtual void SAL_CALL makeVisible(sal_Int16 nEntry) override;

private:
    virtual void onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData ) override;
    virtual ~FmXListBoxCell() override;

    DECL_LINK( OnDoubleClick, ListBox&, void );
    DECL_LINK(ChangedHdl, weld::ComboBox&, void);

    void OnDoubleClick();

    ::comphelper::OInterfaceContainerHelper2   m_aItemListeners,
                                        m_aActionListeners;
    VclPtr<ListBox>                     m_pBox;
    weld::ComboBox* m_pBox;
    sal_uInt16 m_nLines;
    bool m_bMulti;
};


@@ -1012,7 +1015,7 @@ class FmXComboBoxCell   :public FmXTextCell
private:
    ::comphelper::OInterfaceContainerHelper2   m_aItemListeners,
                                        m_aActionListeners;
    weld::ComboBox& m_rComboBox;
    weld::ComboBox* m_pComboBox;
    sal_uInt16 m_nLines;

    DECL_LINK(ChangedHdl, weld::ComboBox&, void);
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 6cc8573..006ad1f 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -923,6 +923,16 @@ public:

    virtual void set_mru_entries(const OUString&) override;

    virtual void set_selection_mode(SelectionMode eMode) override;

    virtual void scroll_to_row(int nRow) override;

    virtual void select(int pos) override;

    virtual void unselect(int pos) override;

    virtual std::vector<int> get_selected_rows() const override;

    virtual void HandleEventListener(VclWindowEvent& rEvent) override;

    virtual ~SalInstanceComboBoxWithoutEdit() override;
@@ -993,6 +1003,16 @@ public:

    virtual void set_mru_entries(const OUString& rEntries) override;

    virtual void set_selection_mode(SelectionMode eMode) override;

    virtual void scroll_to_row(int nRow) override;

    virtual void select(int pos) override;

    virtual void unselect(int pos) override;

    virtual std::vector<int> get_selected_rows() const override;

    virtual void HandleEventListener(VclWindowEvent& rEvent) override;

    virtual ~SalInstanceComboBoxWithEdit() override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index b3c9d2c..b256caa 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -5770,6 +5770,35 @@ void SalInstanceComboBoxWithoutEdit::set_mru_entries(const OUString&)
    assert(false && "not implemented");
}

void SalInstanceComboBoxWithoutEdit::set_selection_mode(SelectionMode eMode)
{
    m_xComboBox->EnableMultiSelection(eMode == SelectionMode::Multiple);
}

std::vector<int> SalInstanceComboBoxWithoutEdit::get_selected_rows() const
{
    std::vector<int> aRet;
    const sal_Int32 nSelEntries = m_xComboBox->GetSelectedEntryCount();
    for (sal_Int32 n = 0; n < nSelEntries; ++n)
        aRet.push_back(m_xComboBox->GetSelectedEntryPos(n));
    return aRet;
}

void SalInstanceComboBoxWithoutEdit::scroll_to_row(int nRow)
{
    m_xComboBox->SetTopEntry(nRow);
}

void SalInstanceComboBoxWithoutEdit::select(int nRow)
{
    m_xComboBox->SelectEntryPos(nRow, true);
}

void SalInstanceComboBoxWithoutEdit::unselect(int nRow)
{
    m_xComboBox->SelectEntryPos(nRow, false);
}

void SalInstanceComboBoxWithoutEdit::HandleEventListener(VclWindowEvent& rEvent)
{
    CallHandleEventListener(rEvent);
@@ -5946,6 +5975,34 @@ void SalInstanceComboBoxWithEdit::set_mru_entries(const OUString& rEntries)
    m_xComboBox->SetMRUEntries(rEntries);
}

void SalInstanceComboBoxWithEdit::set_selection_mode(SelectionMode /*eMode*/)
{
}

std::vector<int> SalInstanceComboBoxWithEdit::get_selected_rows() const
{
    std::vector<int> aRet;
    int nActive = get_active();
    if (nActive != -1)
        aRet.push_back(nActive);
    return aRet;
}

void SalInstanceComboBoxWithEdit::scroll_to_row(int /*nRow*/)
{
    assert(false && "not implemented");
}

void SalInstanceComboBoxWithEdit::select(int /*nRow*/)
{
    assert(false && "not implemented");
}

void SalInstanceComboBoxWithEdit::unselect(int /*nRow*/)
{
    assert(false && "not implemented");
}

void SalInstanceComboBoxWithEdit::HandleEventListener(VclWindowEvent& rEvent)
{
    if (rEvent.GetId() == VclEventId::DropdownPreOpen)
@@ -6113,6 +6170,31 @@ public:
        assert(false && "not implemented");
    }

    virtual void set_selection_mode(SelectionMode eMode) override
    {
        m_pTreeView->set_selection_mode(eMode);
    }

    virtual std::vector<int> get_selected_rows() const override
    {
        return m_pTreeView->get_selected_rows();
    }

    void scroll_to_row(int nRow) override
    {
        m_pTreeView->scroll_to_row(nRow);
    }

    virtual void select(int pos) override
    {
        m_pTreeView->select(pos);
    }

    virtual void unselect(int pos) override
    {
        m_pTreeView->unselect(pos);
    }

    virtual void set_item_menu(const OString&, weld::Menu*) override
    {
        assert(false && "not implemented");
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 530a115..4ca5903 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -9033,6 +9033,62 @@ tools::Rectangle get_row_area(GtkTreeView* pTreeView, GList* pColumns, GtkTreePa
    return aRet;
}

std::vector<int> get_selected_rows(GtkTreeView* pTreeView)
{
    std::vector<int> aRows;

    GList* pList = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(pTreeView), nullptr);
    for (GList* pItem = g_list_first(pList); pItem; pItem = g_list_next(pItem))
    {
        GtkTreePath* path = static_cast<GtkTreePath*>(pItem->data);

        gint depth;
        gint* indices = gtk_tree_path_get_indices_with_depth(path, &depth);
        int nRow = indices[depth-1];

        aRows.push_back(nRow);
    }
    g_list_free_full(pList, reinterpret_cast<GDestroyNotify>(gtk_tree_path_free));

    return aRows;
}

void scroll_to_row(GtkTreeView* pTreeView, int pos)
{
    GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
    gtk_tree_view_scroll_to_cell(pTreeView, path, nullptr, false, 0, 0);
    gtk_tree_path_free(path);
}

void select_tree(GtkTreeView* pTreeView, GtkTreeModel* pTreeModel, int pos)
{
    if (pos == -1 || (pos == 0 && gtk_tree_model_iter_n_children(pTreeModel, nullptr) == 0))
    {
        gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(pTreeView));
    }
    else
    {
        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
        gtk_tree_selection_select_path(gtk_tree_view_get_selection(pTreeView), path);
        gtk_tree_view_scroll_to_cell(pTreeView, path, nullptr, false, 0, 0);
        gtk_tree_path_free(path);
    }
}

void unselect_tree(GtkTreeView* pTreeView, GtkTreeModel* pTreeModel, int pos)
{
    if (pos == -1 || (pos == 0 && gtk_tree_model_iter_n_children(pTreeModel, nullptr) == 0))
    {
        gtk_tree_selection_select_all(gtk_tree_view_get_selection(pTreeView));
    }
    else
    {
        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
        gtk_tree_selection_unselect_path(gtk_tree_view_get_selection(pTreeView), path);
        gtk_tree_path_free(path);
    }
}

class GtkInstanceTreeView : public GtkInstanceContainer, public virtual weld::TreeView
{
private:
@@ -10125,17 +10181,7 @@ public:
    {
        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when frozen, select after thaw. Note selection doesn't survive a freeze");
        disable_notify_events();
        if (pos == -1 || (pos == 0 && n_children() == 0))
        {
            gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(m_pTreeView));
        }
        else
        {
            GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
            gtk_tree_selection_select_path(gtk_tree_view_get_selection(m_pTreeView), path);
            gtk_tree_view_scroll_to_cell(m_pTreeView, path, nullptr, false, 0, 0);
            gtk_tree_path_free(path);
        }
        select_tree(m_pTreeView, GTK_TREE_MODEL(m_pTreeStore), pos);
        enable_notify_events();
    }

@@ -10153,9 +10199,7 @@ public:
    {
        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when frozen, select after thaw. Note selection doesn't survive a freeze");
        disable_notify_events();
        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
        gtk_tree_view_scroll_to_cell(m_pTreeView, path, nullptr, false, 0, 0);
        gtk_tree_path_free(path);
        ::scroll_to_row(m_pTreeView, pos);
        enable_notify_events();
    }

@@ -10170,37 +10214,13 @@ public:
    {
        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when frozen, select after thaw. Note selection doesn't survive a freeze");
        disable_notify_events();
        if (pos == -1 || (pos == 0 && n_children() == 0))
        {
            gtk_tree_selection_select_all(gtk_tree_view_get_selection(m_pTreeView));
        }
        else
        {
            GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
            gtk_tree_selection_unselect_path(gtk_tree_view_get_selection(m_pTreeView), path);
            gtk_tree_path_free(path);
        }
        unselect_tree(m_pTreeView, GTK_TREE_MODEL(m_pTreeStore), pos);
        enable_notify_events();
    }

    virtual std::vector<int> get_selected_rows() const override
    {
        std::vector<int> aRows;

        GList* pList = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(m_pTreeView), nullptr);
        for (GList* pItem = g_list_first(pList); pItem; pItem = g_list_next(pItem))
        {
            GtkTreePath* path = static_cast<GtkTreePath*>(pItem->data);

            gint depth;
            gint* indices = gtk_tree_path_get_indices_with_depth(path, &depth);
            int nRow = indices[depth-1];

            aRows.push_back(nRow);
        }
        g_list_free_full(pList, reinterpret_cast<GDestroyNotify>(gtk_tree_path_free));

        return aRows;
        return ::get_selected_rows(m_pTreeView);
    }

    virtual void all_foreach(const std::function<bool(weld::TreeIter&)>& func) override
@@ -14344,6 +14364,31 @@ public:
        return nWidth;
    }

    virtual void set_selection_mode(SelectionMode eMode) override
    {
        gtk_tree_selection_set_mode(gtk_tree_view_get_selection(m_pTreeView), VclToGtk(eMode));
    }

    void scroll_to_row(int nRow) override
    {
        ::scroll_to_row(m_pTreeView, nRow);
    }

    virtual std::vector<int> get_selected_rows() const override
    {
        return ::get_selected_rows(m_pTreeView);
    }

    void select(int nRow) override
    {
        select_tree(m_pTreeView, m_pTreeModel, nRow);
    }

    void unselect(int nRow) override
    {
        unselect_tree(m_pTreeView, m_pTreeModel, nRow);
    }

    virtual ~GtkInstanceComboBox() override
    {
        m_xCustomMenuButtonHelper.reset();
@@ -14771,6 +14816,31 @@ public:
        return 0;
    }

    virtual void set_selection_mode(SelectionMode eMode) override
    {
        m_pTreeView->set_selection_mode(eMode);
    }

    virtual std::vector<int> get_selected_rows() const override
    {
        return m_pTreeView->get_selected_rows();
    }

    void scroll_to_row(int nRow) override
    {
        m_pTreeView->scroll_to_row(nRow);
    }

    void select(int nRow) override
    {
        m_pTreeView->select(nRow);
    }

    void unselect(int nRow) override
    {
        m_pTreeView->unselect(nRow);
    }

    virtual ~GtkInstanceEntryTreeView() override
    {
        if (m_nAutoCompleteIdleId)