cui/source/inc/cuitabarea.hxx    |   37 +---
 cui/source/tabpages/tpbitmap.cxx |  298 ++++++++++++++++++++++++++-------------
 cui/uiconfig/ui/imagetabpage.ui  |   32 ++--
 3 files changed, 236 insertions(+), 131 deletions(-)

New commits:
commit c4d449e3b5b468d602ee7bd0bcc7f713c4b967c8
Author:     Parth Raiyani <[email protected]>
AuthorDate: Mon Aug 4 16:57:54 2025 +0530
Commit:     Caolán McNamara <[email protected]>
CommitDate: Tue Feb 24 16:10:47 2026 +0100

    Switch to IconView for image tab page  for improved UI handling
    
    - Replaced ValueSet with IconView widget in image tab page
    - Updated imagetabpage UI to include GtkIconView and GtkTreeStore for Image
    - Added support to select and preview default when no item is selected
    - Always keep selected item and selection preview in sync
    
    Change-Id: I61a030be8b286f0e965bc72fd210abe4cb13dd29
    Signed-off-by: Parth Raiyani <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188159
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Szymon Kłos <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200186
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/cui/source/inc/cuitabarea.hxx b/cui/source/inc/cuitabarea.hxx
index 1dd9b52df2df..2a7f0a7da5fe 100644
--- a/cui/source/inc/cuitabarea.hxx
+++ b/cui/source/inc/cuitabarea.hxx
@@ -512,23 +512,6 @@ public:
 class SvxBitmapTabPage : public SfxTabPage
 {
 
-public:
-
-    class SvxPresetListBoxValueSet : public SvxPresetListBox
-    {
-    public:
-        SvxPresetListBoxValueSet(std::unique_ptr<weld::ScrolledWindow> 
pWindow);
-        virtual bool KeyInput(const KeyEvent& rKEvt) override;
-
-        void SetDialog(SvxBitmapTabPage* pSvxBitmapTabPage)
-        {
-            m_pSvxBitmapTabPage = pSvxBitmapTabPage;
-        }
-
-    private:
-        SvxBitmapTabPage* m_pSvxBitmapTabPage;
-    };
-
 private:
 
     const SfxItemSet&          m_rOutAttrs;
@@ -548,9 +531,11 @@ private:
     Size                       rBitmapSize;
     Size                       rFilledSize;
     Size                       rZoomedSize;
+    OUString                   sLastItemIdent;
+    Size                       aIconSize;
 
     SvxXRectPreview m_aCtlBitmapPreview;
-    std::unique_ptr<SvxPresetListBoxValueSet>   m_xBitmapLB;
+    std::unique_ptr<weld::IconView> m_xBitmapLB;
     std::unique_ptr<weld::ComboBox> m_xBitmapStyleLB;
     std::unique_ptr<weld::Container> m_xSizeBox;
     std::unique_ptr<weld::CheckButton> m_xTsbScale;
@@ -566,25 +551,31 @@ private:
     std::unique_ptr<weld::MetricSpinButton> m_xTileOffset;
     std::unique_ptr<weld::Button> m_xBtnImport;
     std::unique_ptr<weld::CustomWeld> m_xCtlBitmapPreview;
-    std::unique_ptr<weld::CustomWeld> m_xBitmapLBWin;
 
-    DECL_LINK( ModifyBitmapHdl, ValueSet*, void );
+    DECL_LINK( ModifyBitmapHdl, weld::IconView&, void );
     DECL_LINK( ClickScaleHdl, weld::Toggleable&, void );
     DECL_LINK( ModifyBitmapStyleHdl, weld::ComboBox&, void );
     DECL_LINK( ModifyBitmapSizeHdl, weld::MetricSpinButton&, void );
     DECL_LINK( ModifyBitmapPositionHdl, weld::ComboBox&, void );
     DECL_LINK( ModifyPositionOffsetHdl, weld::MetricSpinButton&, void );
     DECL_LINK( ModifyTileOffsetHdl, weld::MetricSpinButton&, void );
-    DECL_LINK( ClickRenameHdl, SvxPresetListBox*, void );
-    DECL_LINK( ClickDeleteHdl, SvxPresetListBox*, void );
+    DECL_LINK(MousePressHdl, const MouseEvent&, bool);
+    DECL_LINK(KeyPressHdl, const KeyEvent&, bool);
     DECL_LINK( ClickImportHdl, weld::Button&, void );
+    DECL_LINK(MenuSelectAsyncHdl, void*, void);
+    DECL_LINK(OnPopupEnd, const OUString&, void);
+    DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString);
     void ClickBitmapHdl_Impl();
     void CalculateBitmapPresetSize();
-    void DeleteBitmapHdl_Impl(const sal_uInt16 nId);
     sal_Int32 SearchBitmapList(std::u16string_view rBitmapName);
     sal_Int32 SearchBitmapList(const GraphicObject& rGraphicObject);
     tools::Long AddBitmap(const GraphicObject& rGraphicObject, const OUString& 
rName,
                           bool bOnlyForThisDocument = false);
+    static VclPtr<VirtualDevice> GetVirtualDevice(Bitmap aBitmap);
+    void FillPresetListBox();
+    void ShowContextMenu(const Point& pPos);
+    void ClickRenameHdl();
+    void ClickDeleteHdl();
 
 public:
     SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* 
pController, const SfxItemSet& rInAttrs);
diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx
index 494348fefd88..f5961e35f6bb 100644
--- a/cui/source/tabpages/tpbitmap.cxx
+++ b/cui/source/tabpages/tpbitmap.cxx
@@ -82,7 +82,8 @@ SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, 
weld::DialogControlle
     , m_aXFillAttr(rInAttrs.GetPool())
     , m_rXFSet(m_aXFillAttr.GetItemSet())
     , mpView(nullptr)
-    , m_xBitmapLB(new 
SvxPresetListBoxValueSet(m_xBuilder->weld_scrolled_window(u"imagewin"_ustr, 
true)))
+    , aIconSize(60, 64)
+    , m_xBitmapLB(m_xBuilder->weld_icon_view(u"image_iconview"_ustr))
     , m_xBitmapStyleLB(m_xBuilder->weld_combo_box(u"imagestyle"_ustr))
     , m_xSizeBox(m_xBuilder->weld_container(u"sizebox"_ustr))
     , m_xTsbScale(m_xBuilder->weld_check_button(u"scaletsb"_ustr))
@@ -98,17 +99,17 @@ SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, 
weld::DialogControlle
     , m_xTileOffset(m_xBuilder->weld_metric_spin_button(u"tileoffmtr"_ustr, 
FieldUnit::PERCENT))
     , m_xBtnImport(m_xBuilder->weld_button(u"BTN_IMPORT"_ustr))
     , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, 
u"CTL_IMAGE_PREVIEW"_ustr, m_aCtlBitmapPreview))
-    , m_xBitmapLBWin(new weld::CustomWeld(*m_xBuilder, u"IMAGE"_ustr, 
*m_xBitmapLB))
 {
     // setting the output device
     m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
     m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
     m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
 
-    m_xBitmapLB->SetSelectHdl( LINK(this, SvxBitmapTabPage, ModifyBitmapHdl) );
-    m_xBitmapLB->SetRenameHdl( LINK(this, SvxBitmapTabPage, ClickRenameHdl) );
-    m_xBitmapLB->SetDeleteHdl( LINK(this, SvxBitmapTabPage, ClickDeleteHdl) );
-    m_xBitmapLB->SetDialog(this);
+    m_xBitmapLB->connect_selection_changed(LINK(this, SvxBitmapTabPage, 
ModifyBitmapHdl));
+    m_xBitmapLB->connect_mouse_press(LINK(this, SvxBitmapTabPage, 
MousePressHdl));
+    m_xBitmapLB->connect_key_press(LINK(this, SvxBitmapTabPage, KeyPressHdl));
+    m_xBitmapLB->connect_query_tooltip(LINK(this, SvxBitmapTabPage, 
QueryTooltipHdl));
+
     m_xBitmapStyleLB->connect_changed( LINK(this, SvxBitmapTabPage, 
ModifyBitmapStyleHdl) );
     Link<weld::MetricSpinButton&, void> aLink1( LINK(this, SvxBitmapTabPage, 
ModifyBitmapSizeHdl) );
     m_xBitmapWidth->connect_value_changed( aLink1 );
@@ -125,7 +126,6 @@ SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, 
weld::DialogControlle
 
     // Calculate size of display boxes
     Size aSize = 
getDrawPreviewOptimalSize(m_aCtlBitmapPreview.GetDrawingArea()->get_ref_device());
-    m_xBitmapLB->set_size_request(aSize.Width(), aSize.Height());
     m_xCtlBitmapPreview->set_size_request(aSize.Width(), aSize.Height());
 
     SfxItemPool* pPool = m_rXFSet.GetPool();
@@ -134,8 +134,6 @@ SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, 
weld::DialogControlle
     SetFieldUnit( *m_xBitmapWidth, meFieldUnit, true );
     SetFieldUnit( *m_xBitmapHeight, meFieldUnit, true );
 
-    m_xBitmapLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
-
     SfxViewShell* pViewShell = SfxViewShell::Current();
     if( pViewShell )
         mpView = pViewShell->GetDrawView();
@@ -144,7 +142,6 @@ SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, 
weld::DialogControlle
 
 SvxBitmapTabPage::~SvxBitmapTabPage()
 {
-    m_xBitmapLBWin.reset();
     m_xBitmapLB.reset();
     m_xCtlBitmapPreview.reset();
 
@@ -162,7 +159,37 @@ SvxBitmapTabPage::~SvxBitmapTabPage()
 
 void SvxBitmapTabPage::Construct()
 {
-    m_xBitmapLB->FillPresetListBox( *m_pBitmapList );
+    FillPresetListBox();
+}
+
+void SvxBitmapTabPage::FillPresetListBox()
+{
+    m_xBitmapLB->clear();
+
+    m_xBitmapLB->freeze();
+    for (tools::Long nId = 0; nId < m_pBitmapList->Count(); nId++)
+    {
+        const XBitmapEntry* pEntry = m_pBitmapList->GetBitmap(nId);
+
+        OUString sId = OUString::number(nId);
+        Bitmap aBitmap = m_pBitmapList->GetBitmapForPreview(nId, aIconSize);
+        VclPtr<VirtualDevice> aVDev = GetVirtualDevice(aBitmap);
+        Bitmap aBmp = aVDev->GetBitmap(Point(), aVDev->GetOutputSizePixel());
+        OUString sImageName = pEntry->GetName();
+
+        if (!m_xBitmapLB->get_id(nId).isEmpty())
+        {
+            m_xBitmapLB->set_image(nId, *aVDev);
+            m_xBitmapLB->set_id(nId, sId);
+            m_xBitmapLB->set_text(nId, sImageName);
+        }
+        else
+        {
+            m_xBitmapLB->insert(-1, &sImageName, &sId, &aBmp, nullptr);
+        }
+    }
+
+    m_xBitmapLB->thaw();
 }
 
 void SvxBitmapTabPage::ActivatePage( const SfxItemSet& rSet )
@@ -188,8 +215,9 @@ void SvxBitmapTabPage::ActivatePage( const SfxItemSet& rSet 
)
         const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeYItem( GetCoreValue( 
*m_xBitmapHeight, mePoolUnit ) ) );
     }
 
-    sal_uInt16 nId = m_xBitmapLB->GetItemId( static_cast<size_t>( nPos ) );
-    m_xBitmapLB->SelectItem( nId );
+    OUString sId = m_xBitmapLB->get_id( static_cast<size_t>( nPos ) );
+    sal_uInt32 nId = !sId.isEmpty() ? sId.toInt32() : 0;
+    m_xBitmapLB->select( nId );
 }
 
 DeactivateRC SvxBitmapTabPage::DeactivatePage( SfxItemSet* _pSet )
@@ -204,11 +232,12 @@ DeactivateRC SvxBitmapTabPage::DeactivatePage( 
SfxItemSet* _pSet )
 bool SvxBitmapTabPage::FillItemSet( SfxItemSet* rAttrs )
 {
     rAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
-    size_t nPos = m_xBitmapLB->GetSelectItemPos();
-    if(VALUESET_ITEM_NOTFOUND != nPos)
+    OUString sId = m_xBitmapLB->get_selected_id();
+    sal_Int32 nPos = !sId.isEmpty() ? sId.toInt32() : -1;
+    if(nPos != -1)
     {
         const XBitmapEntry* pXBitmapEntry = m_pBitmapList->GetBitmap(nPos);
-        const OUString aString(m_xBitmapLB->GetItemText( 
m_xBitmapLB->GetSelectedItemId() ));
+        const OUString aString(pXBitmapEntry->GetName());
         rAttrs->Put(XFillBitmapItem(aString, 
pXBitmapEntry->GetGraphicObject()));
     }
 
@@ -444,43 +473,9 @@ std::unique_ptr<SfxTabPage> 
SvxBitmapTabPage::Create(weld::Container* pPage, wel
 
 void SvxBitmapTabPage::ClickBitmapHdl_Impl()
 {
-    m_xBitmapLBWin->set_sensitive(true);
     m_xCtlBitmapPreview->set_sensitive(true);
 
-    ModifyBitmapHdl(m_xBitmapLB.get());
-}
-
-void SvxBitmapTabPage::DeleteBitmapHdl_Impl(const sal_uInt16 nId)
-{
-    const size_t nPos = m_xBitmapLB->GetItemPos(nId);
-    if( nPos == VALUESET_ITEM_NOTFOUND )
-        return;
-
-    std::unique_ptr<weld::Builder> 
xBuilder(Application::CreateBuilder(GetFrameWeld(), 
u"cui/ui/querydeletebitmapdialog.ui"_ustr));
-    std::unique_ptr<weld::MessageDialog> 
xQueryBox(xBuilder->weld_message_dialog(u"AskDelBitmapDialog"_ustr));
-
-    if (xQueryBox->run() != RET_YES)
-        return;
-
-    sal_uInt16 nNextId = m_xBitmapLB->GetSelectedItemId();
-    const bool bDeletingSelectedItem(nId == nNextId);
-    if (bDeletingSelectedItem)
-    {
-        nNextId = m_xBitmapLB->GetItemId(nPos + 1);
-        if (!nNextId)
-            nNextId = m_xBitmapLB->GetItemId(nPos - 1);
-    }
-
-    m_pBitmapList->Remove( static_cast<sal_uInt16>(nPos) );
-    m_xBitmapLB->RemoveItem( nId );
-
-    if (bDeletingSelectedItem)
-    {
-        m_xBitmapLB->SelectItem(nNextId);
-        m_aCtlBitmapPreview.Invalidate();
-    }
-    ModifyBitmapHdl(m_xBitmapLB.get());
-    m_nBitmapListState |= ChangeType::MODIFIED;
+    ModifyBitmapHdl(*m_xBitmapLB);
 }
 
 void SvxBitmapTabPage::CalculateBitmapPresetSize()
@@ -507,12 +502,13 @@ void SvxBitmapTabPage::CalculateBitmapPresetSize()
     }
 }
 
-IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, ValueSet*, void)
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, weld::IconView&, void)
 {
     std::unique_ptr<GraphicObject> pGraphicObject;
-    size_t nPos = m_xBitmapLB->GetSelectItemPos();
+    OUString sId = m_xBitmapLB->get_selected_id();
+    sal_Int32 nPos = !sId.isEmpty() ? sId.toInt32() : -1;
 
-    if( nPos != VALUESET_ITEM_NOTFOUND )
+    if( nPos != -1 )
     {
         pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap( 
static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
     }
@@ -529,15 +525,10 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, 
ValueSet*, void)
             }
         }
 
-        if(!pGraphicObject)
+        if(!pGraphicObject && m_xBitmapLB->n_children() > 0)
         {
-            sal_uInt16 nId = m_xBitmapLB->GetItemId(0);
-            m_xBitmapLB->SelectItem(nId);
-
-            if(0 != nId)
-            {
-                pGraphicObject.reset(new 
GraphicObject(m_pBitmapList->GetBitmap(0)->GetGraphicObject()));
-            }
+            m_xBitmapLB->select(0);
+            pGraphicObject.reset(new 
GraphicObject(m_pBitmapList->GetBitmap(0)->GetGraphicObject()));
         }
     }
 
@@ -568,12 +559,88 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, 
ValueSet*, void)
 
 }
 
-IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, SvxPresetListBox*, void)
+IMPL_LINK(SvxBitmapTabPage, QueryTooltipHdl, const weld::TreeIter&, rIter, 
OUString)
+{
+    OUString sId = m_xBitmapLB->get_id(rIter);
+    sal_Int32 nId = !sId.isEmpty() ? sId.toInt32() : -1;
+
+    if (nId >= 0)
+    {
+        const XBitmapEntry* pEntry = m_pBitmapList->GetBitmap(nId);
+        return pEntry->GetName();
+    }
+    return OUString();
+}
+
+IMPL_LINK(SvxBitmapTabPage, KeyPressHdl, const KeyEvent&, rKEvt, bool)
+{
+    if (rKEvt.GetKeyCode().GetCode() == KEY_DELETE)
+    {
+        ClickDeleteHdl();
+        return true;
+    }
+    return false;
+}
+
+IMPL_LINK(SvxBitmapTabPage, MousePressHdl, const MouseEvent&, rMEvt, bool)
+{
+    if (!rMEvt.IsRight())
+        return false;
+
+    // Disable context menu for LibreOfficeKit mode
+    if (comphelper::LibreOfficeKit::isActive())
+        return false;
+
+    const Point& pPos = rMEvt.GetPosPixel();
+    for (int i = 0; i < m_xBitmapLB->n_children(); i++)
+    {
+        const ::tools::Rectangle aRect = m_xBitmapLB->get_rect(i);
+        if (aRect.Contains(pPos))
+        {
+            ShowContextMenu(pPos);
+            break;
+        }
+    }
+    return false;
+}
+
+void SvxBitmapTabPage::ShowContextMenu(const Point& pPos)
+{
+    ::tools::Rectangle aRect(pPos, Size(1, 1));
+    std::unique_ptr<weld::Builder> xBuilder(
+        Application::CreateBuilder(m_xBitmapLB.get(), 
u"svx/ui/presetmenu.ui"_ustr));
+    std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr));
+
+    xMenu->connect_activate(LINK(this, SvxBitmapTabPage, OnPopupEnd));
+    xMenu->popup_at_rect(m_xBitmapLB.get(), aRect);
+}
+
+IMPL_LINK(SvxBitmapTabPage, OnPopupEnd, const OUString&, sCommand, void)
 {
-    const sal_uInt16 nId = m_xBitmapLB->GetContextMenuItemId();
-    const size_t nPos = m_xBitmapLB->GetItemPos(nId);
+    sLastItemIdent = sCommand;
+    if (sLastItemIdent.isEmpty())
+        return;
+
+    Application::PostUserEvent(LINK(this, SvxBitmapTabPage, 
MenuSelectAsyncHdl));
+}
 
-    if( nPos == VALUESET_ITEM_NOTFOUND )
+IMPL_LINK_NOARG(SvxBitmapTabPage, MenuSelectAsyncHdl, void*, void)
+{
+    if (sLastItemIdent == u"rename")
+    {
+        ClickRenameHdl();
+    }
+    else if (sLastItemIdent == u"delete")
+    {
+        ClickDeleteHdl();
+    }
+}
+
+void SvxBitmapTabPage::ClickRenameHdl()
+{
+    const OUString sId = m_xBitmapLB->get_selected_id();
+    const sal_Int32 nPos = !sId.isEmpty() ? sId.toInt32() : -1;
+    if( nPos == -1 )
         return;
 
     OUString aDesc( CuiResId( RID_CUISTR_DESC_NEW_BITMAP ) );
@@ -587,14 +654,14 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, 
SvxPresetListBox*, void)
     {
         aName = pDlg->GetName();
         sal_Int32 nBitmapPos = SearchBitmapList( aName );
-        bool bValidBitmapName = (nBitmapPos == static_cast<sal_Int32>(nPos) ) 
|| (nBitmapPos == -1);
+        bool bValidBitmapName = (nBitmapPos == nPos ) || (nBitmapPos == -1);
 
         if(bValidBitmapName)
         {
             bLoop = false;
             m_pBitmapList->GetBitmap(nPos)->SetName(aName);
 
-            m_xBitmapLB->SetItemText(nId, aName);
+            m_xBitmapLB->set_text(nPos, aName);
 
             m_nBitmapListState |= ChangeType::MODIFIED;
         }
@@ -607,31 +674,35 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, 
SvxPresetListBox*, void)
     }
 }
 
-IMPL_LINK_NOARG(SvxBitmapTabPage, ClickDeleteHdl, SvxPresetListBox*, void)
+void SvxBitmapTabPage::ClickDeleteHdl()
 {
-    DeleteBitmapHdl_Impl(m_xBitmapLB->GetContextMenuItemId());
-}
+    const OUString sId = m_xBitmapLB->get_selected_id();
+    const sal_Int32 nPos = !sId.isEmpty() ? sId.toInt32() : -1;
 
+    if( nPos == -1 )
+        return;
 
-SvxBitmapTabPage::SvxPresetListBoxValueSet::SvxPresetListBoxValueSet(std::unique_ptr<weld::ScrolledWindow>
 pWindow)
-    : SvxPresetListBox(std::move(pWindow))
-    , m_pSvxBitmapTabPage(nullptr)
-{
-}
+    std::unique_ptr<weld::Builder> 
xBuilder(Application::CreateBuilder(GetFrameWeld(), 
u"cui/ui/querydeletebitmapdialog.ui"_ustr));
+    std::unique_ptr<weld::MessageDialog> 
xQueryBox(xBuilder->weld_message_dialog(u"AskDelBitmapDialog"_ustr));
 
-bool SvxBitmapTabPage::SvxPresetListBoxValueSet::KeyInput(const KeyEvent& 
rKEvt)
-{
-    switch (rKEvt.GetKeyCode().GetCode())
-    {
-        case KEY_DELETE:
-        {
-            m_pSvxBitmapTabPage->DeleteBitmapHdl_Impl(GetSelectedItemId());
-            return true;
-        }
-        break;
-        default:
-            return SvxPresetListBox::KeyInput(rKEvt);
-    }
+    if (xQueryBox->run() != RET_YES)
+        return;
+
+    m_pBitmapList->Remove( static_cast<sal_uInt16>(nPos) );
+    m_xBitmapLB->remove( nPos );
+
+    FillPresetListBox();
+
+    sal_Int32 nNextId = nPos;
+    if (nPos >= m_xBitmapLB->n_children())
+        nNextId = m_xBitmapLB->n_children() - 1;
+
+    if(m_xBitmapLB->n_children() > 0)
+        m_xBitmapLB->select(nNextId);
+
+    m_aCtlBitmapPreview.Invalidate();
+    ModifyBitmapHdl(*m_xBitmapLB);
+    m_nBitmapListState |= ChangeType::MODIFIED;
 }
 
 IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapSizeHdl, 
weld::MetricSpinButton&, void )
@@ -818,7 +889,23 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickImportHdl, 
weld::Button&, void)
         pDlg.disposeAndClear();
 
         if( !nError )
-            AddBitmap(std::move(aGraphic), aName);
+        {
+            m_pBitmapList->Insert(std::make_unique<XBitmapEntry>(aGraphic, 
aName), nCount);
+
+            OUString sId = nCount > 0 ? m_xBitmapLB->get_id( nCount - 1 ) : 
OUString();
+            sal_Int32 nId = !sId.isEmpty() ? sId.toInt32() : -1;
+            Bitmap aBitmap = m_pBitmapList->GetBitmapForPreview( nCount, 
aIconSize );
+            VclPtr<VirtualDevice> pVDev = GetVirtualDevice(aBitmap);
+            Bitmap aBmp = pVDev->GetBitmap(Point(), 
pVDev->GetOutputSizePixel());
+
+            m_xBitmapLB->insert( nId + 1, &aName, &sId, &aBmp, nullptr);
+            FillPresetListBox();
+
+            m_xBitmapLB->select( nId + 1 );
+            m_nBitmapListState |= ChangeType::MODIFIED;
+
+            ModifyBitmapHdl(*m_xBitmapLB);
+        }
     }
     else
     {
@@ -829,6 +916,19 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickImportHdl, 
weld::Button&, void)
     }
 }
 
+VclPtr<VirtualDevice> SvxBitmapTabPage::GetVirtualDevice(Bitmap aBitmap)
+{
+    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    const Point aNull(0, 0);
+    if (pVDev->GetDPIScaleFactor() > 1)
+        aBitmap.Scale(pVDev->GetDPIScaleFactor(), pVDev->GetDPIScaleFactor());
+    const Size aSize(aBitmap.GetSizePixel());
+    pVDev->SetOutputSizePixel(aSize);
+    pVDev->DrawBitmap(aNull, aBitmap);
+
+    return pVDev;
+}
+
 sal_Int32 SvxBitmapTabPage::SearchBitmapList(const GraphicObject& 
rGraphicObject)
 {
     tools::Long nCount = m_pBitmapList->Count();
@@ -872,14 +972,20 @@ tools::Long SvxBitmapTabPage::AddBitmap(const 
GraphicObject& rGraphicObject, con
         xBitmapEntry->SetSavingAllowed(false);
     m_pBitmapList->Insert(std::move(xBitmapEntry), nLastPos);
 
-    Bitmap aBitmap = m_pBitmapList->GetBitmapForPreview(nLastPos, 
m_xBitmapLB->GetIconSize());
-
-    const sal_uInt16 nHighestId = m_xBitmapLB->GetItemId(nLastPos - 1);
-    m_xBitmapLB->InsertItem(nHighestId + 1, Image(aBitmap), rName);
-    m_xBitmapLB->SelectItem(nHighestId + 1);
+    Bitmap aBitmap = m_pBitmapList->GetBitmapForPreview(nLastPos, aIconSize);
+    VclPtr<VirtualDevice> pVDev = GetVirtualDevice(aBitmap);
+    Bitmap aBmp = pVDev->GetBitmap(Point(), pVDev->GetOutputSizePixel());
+
+    OUString sId = nLastPos > 0 ? m_xBitmapLB->get_id(nLastPos - 1) : 
OUString();
+    sal_Int32 nId = !sId.isEmpty() ? sId.toInt32() : -1;
+    OUString sName(rName);
+    OUString sNewId = OUString::number(nLastPos);
+    m_xBitmapLB->insert(nId + 1, &sName, &sNewId, &aBmp, nullptr);
+    FillPresetListBox();
+    m_xBitmapLB->select(nId + 1);
     m_nBitmapListState |= ChangeType::MODIFIED;
 
-    ModifyBitmapHdl(m_xBitmapLB.get());
+    ModifyBitmapHdl(*m_xBitmapLB);
 
     // inform sidebar, etc. that the list of images has changed.
     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
diff --git a/cui/uiconfig/ui/imagetabpage.ui b/cui/uiconfig/ui/imagetabpage.ui
index d5ca69d92fa1..54bcd43892c0 100644
--- a/cui/uiconfig/ui/imagetabpage.ui
+++ b/cui/uiconfig/ui/imagetabpage.ui
@@ -7,6 +7,14 @@
     <property name="step-increment">1</property>
     <property name="page-increment">10</property>
   </object>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name pixbuf -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkBox" id="ImageTabPage">
     <property name="visible">True</property>
     <property name="can-focus">False</property>
@@ -29,25 +37,25 @@
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
-              <object class="GtkScrolledWindow" id="imagewin">
+              <object class="GtkScrolledWindow">
                 <property name="visible">True</property>
                 <property name="can-focus">True</property>
                 <property name="vexpand">True</property>
                 <property name="hscrollbar-policy">never</property>
-                <property name="vscrollbar-policy">never</property>
+                <property name="vscrollbar-policy">always</property>
                 <property name="shadow-type">in</property>
                 <child>
-                  <object class="GtkViewport">
+                  <object class="GtkIconView" id="image_iconview">
                     <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <child>
-                      <object class="GtkDrawingArea" id="IMAGE">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="events">GDK_BUTTON_MOTION_MASK | 
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                        <property name="vexpand">True</property>
-                      </object>
-                    </child>
+                    <property name="item-padding">2</property>
+                    <property name="can-focus">True</property>
+                    <property name="hexpand">False</property>
+                    <property name="vexpand">True</property>
+                    <property name="model">liststore1</property>
+                    <property name="pixbuf-column">0</property>
+                    <property name="margin">6</property>
+                    <property name="columns">3</property>
+                    <property name="activate-on-single-click">True</property>
                   </object>
                 </child>
               </object>

Reply via email to