framework/source/uielement/generictoolbarcontroller.cxx |   14 ++++++
 include/framework/generictoolbarcontroller.hxx          |    1 
 include/vcl/weld.hxx                                    |    1 
 sfx2/source/toolbox/weldutils.cxx                       |    7 +--
 vcl/inc/salvtables.hxx                                  |    2 
 vcl/source/app/salvtables.cxx                           |    6 ++
 vcl/source/window/toolbox2.cxx                          |   13 ------
 vcl/unx/gtk3/gtkinst.cxx                                |   33 ++++++++++++----
 8 files changed, 53 insertions(+), 24 deletions(-)

New commits:
commit 4fb8c0d14cb2468f7336438004f699b9eb7e7e4a
Author:     Maxim Monastirsky <momonas...@gmail.com>
AuthorDate: Fri Jul 29 00:36:18 2022 +0300
Commit:     Maxim Monastirsky <momonas...@gmail.com>
CommitDate: Tue Aug 30 13:08:03 2022 +0200

    tdf#149741 tdf#149956 Make flipping work also in the sidebar
    
    - Reset the icon each time, as there seems to be no easy
    way to retrieve the existing icon from a gtk widget in
    order to mirror it, like we used to do for vcl. Similar
    approach is currently taken in
    ToolboxButtonColorUpdaterBase::Update.
    
    - Store the flipping state also in GtkInstanceToolbar,
    similar to vcl's ToolBox. This seems to be the easiest
    way to make flipping not break on icon theme change,
    covering all 4 cases (ToolBarManager, SidebarToolBox,
    ToolbarUnoDispatcher, GenericToolbarController), w/o
    too involved changes in each. This might benefit from
    some refactoring later on, but should be good enough
    for now.
    
    - One unsolved problem is the appearance of flipped
    icons with svg themes, as the regular variant is handed
    to gtk directly, whereas the flipped one is loaded by us,
    resulting with a different (blurry) look.
    
    Change-Id: I48c16827b46fb75fd798a041851af6e2648ae8fe
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139021
    Tested-by: Jenkins
    Reviewed-by: Maxim Monastirsky <momonas...@gmail.com>

diff --git a/framework/source/uielement/generictoolbarcontroller.cxx 
b/framework/source/uielement/generictoolbarcontroller.cxx
index e8e49cb30933..312b5ed9e77f 100644
--- a/framework/source/uielement/generictoolbarcontroller.cxx
+++ b/framework/source/uielement/generictoolbarcontroller.cxx
@@ -91,6 +91,7 @@ GenericToolbarController::GenericToolbarController( const 
Reference< XComponentC
     ,   m_xToolbar( pToolbar )
     ,   m_nID( nID )
     ,   m_bEnumCommand( isEnumCommand( aCommand ))
+    ,   m_bMirrored( false )
     ,   m_bMadeInvisible( false )
     ,   m_aEnumCommand( getEnumCommand( aCommand ))
 {
@@ -189,6 +190,7 @@ void GenericToolbarController::statusChanged( const 
FeatureStateEvent& Event )
 
         bool        bValue;
         OUString    aStrValue;
+        SfxImageItem aImageItem;
 
         if ( Event.State >>= bValue )
         {
@@ -199,6 +201,13 @@ void GenericToolbarController::statusChanged( const 
FeatureStateEvent& Event )
         {
             m_pToolbar->set_item_label(sId, aStrValue);
         }
+        else if ( aImageItem.PutValue( Event.State, 0 ) && 
aImageItem.IsMirrored() != m_bMirrored )
+        {
+            m_pToolbar->set_item_image_mirrored(sId, aImageItem.IsMirrored());
+            auto 
xGraphic(vcl::CommandInfoProvider::GetXGraphicForCommand(m_aCommandURL, 
m_xFrame, m_pToolbar->get_icon_size()));
+            m_pToolbar->set_item_image(sId, xGraphic);
+            m_bMirrored = !m_bMirrored;
+        }
         else
             m_pToolbar->set_item_active(sId, false);
 
@@ -295,9 +304,12 @@ void GenericToolbarController::statusChanged( const 
FeatureStateEvent& Event )
         if ( m_bMadeInvisible )
             m_xToolbar->ShowItem( m_nID );
     }
-    else if ( aImageItem.PutValue( Event.State, 0 ) )
+    else if ( aImageItem.PutValue( Event.State, 0 ) && aImageItem.IsMirrored() 
!= m_bMirrored )
     {
         m_xToolbar->SetItemImageMirrorMode( m_nID, aImageItem.IsMirrored() );
+        Image aImage( vcl::CommandInfoProvider::GetImageForCommand( 
m_aCommandURL, m_xFrame, m_xToolbar->GetImageSize() ));
+        m_xToolbar->SetItemImage( m_nID, aImage );
+        m_bMirrored = !m_bMirrored;
         if ( m_bMadeInvisible )
             m_xToolbar->ShowItem( m_nID );
     }
diff --git a/include/framework/generictoolbarcontroller.hxx 
b/include/framework/generictoolbarcontroller.hxx
index e177ea5f00a9..473941a7682a 100644
--- a/include/framework/generictoolbarcontroller.hxx
+++ b/include/framework/generictoolbarcontroller.hxx
@@ -64,6 +64,7 @@ class FWK_DLLPUBLIC GenericToolbarController final : public 
svt::ToolboxControll
         VclPtr<ToolBox>     m_xToolbar;
         ToolBoxItemId       m_nID;
         bool                m_bEnumCommand : 1,
+                            m_bMirrored : 1,
                             m_bMadeInvisible : 1;
         OUString            m_aEnumCommand;
 };
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index b3bbe60a7390..adbd35d85df6 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -2461,6 +2461,7 @@ public:
     virtual void set_item_tooltip_text(const OString& rIdent, const OUString& 
rTip) = 0;
     virtual OUString get_item_tooltip_text(const OString& rIdent) const = 0;
     virtual void set_item_icon_name(const OString& rIdent, const OUString& 
rIconName) = 0;
+    virtual void set_item_image_mirrored(const OString& rIdent, bool 
bMirrored) = 0;
     virtual void set_item_image(const OString& rIdent,
                                 const 
css::uno::Reference<css::graphic::XGraphic>& rIcon)
         = 0;
diff --git a/sfx2/source/toolbox/weldutils.cxx 
b/sfx2/source/toolbox/weldutils.cxx
index 5c1f1c58fa4f..25b173de633f 100644
--- a/sfx2/source/toolbox/weldutils.cxx
+++ b/sfx2/source/toolbox/weldutils.cxx
@@ -158,9 +158,10 @@ IMPL_LINK_NOARG(ToolbarUnoDispatcher, 
ChangedIconSizeHandler, LinkParamNone*, vo
 
     for (int i = 0, nItems = m_pToolbar->get_n_items(); i < nItems; ++i)
     {
-        OUString sCommand = OUString::fromUtf8(m_pToolbar->get_item_ident(i));
-        auto xImage(vcl::CommandInfoProvider::GetXGraphicForCommand(sCommand, 
m_xFrame, eSize));
-        m_pToolbar->set_item_image(i, xImage);
+        OString sIdent(m_pToolbar->get_item_ident(i));
+        auto 
xImage(vcl::CommandInfoProvider::GetXGraphicForCommand(OUString::fromUtf8(sIdent),
+                                                                    m_xFrame, 
eSize));
+        m_pToolbar->set_item_image(sIdent, xImage);
     }
 
     for (auto const& it : maControllers)
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 642eabd49990..ed6e35d6e48f 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1259,6 +1259,8 @@ public:
 
     virtual void set_item_icon_name(const OString& rIdent, const OUString& 
rIconName) override;
 
+    virtual void set_item_image_mirrored(const OString& rIdent, bool 
bMirrored) override;
+
     virtual void set_item_image(const OString& rIdent,
                                 const 
css::uno::Reference<css::graphic::XGraphic>& rIcon) override;
 
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 3874e76ab79d..74327b0bf72e 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1153,6 +1153,12 @@ void SalInstanceToolbar::set_item_icon_name(const 
OString& rIdent, const OUStrin
                              Image(StockImage::Yes, rIconName));
 }
 
+void SalInstanceToolbar::set_item_image_mirrored(const OString& rIdent, bool 
bMirrored)
+{
+    
m_xToolBox->SetItemImageMirrorMode(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
+                                       bMirrored);
+}
+
 void SalInstanceToolbar::set_item_image(const OString& rIdent,
                                         const 
css::uno::Reference<css::graphic::XGraphic>& rIcon)
 {
diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx
index fe50d399a5a8..701d77624d90 100644
--- a/vcl/source/window/toolbox2.cxx
+++ b/vcl/source/window/toolbox2.cxx
@@ -1025,18 +1025,7 @@ void ToolBox::SetItemImageMirrorMode( ToolBoxItemId 
nItemId, bool bMirror )
         return;
 
     ImplToolItem* pItem = &mpData->m_aItems[nPos];
-
-    if (pItem->mbMirrorMode != bMirror)
-    {
-        pItem->mbMirrorMode = bMirror;
-        if (!!pItem->maImage)
-        {
-            pItem->maImage = ImplMirrorImage(pItem->maImage);
-        }
-
-        if (!mbCalc)
-            ImplUpdateItem(nPos);
-    }
+    pItem->mbMirrorMode = bMirror;
 }
 
 Image ToolBox::GetItemImage(ToolBoxItemId nItemId) const
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 1eb056936a41..19372ab78446 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -4801,9 +4801,18 @@ GdkPixbuf* load_icon_by_name(const OUString& rIconName)
 
 namespace
 {
-    GdkPixbuf* getPixbuf(const css::uno::Reference<css::graphic::XGraphic>& 
rImage)
+    Image mirrorImage(const Image& rImage)
+    {
+        BitmapEx aMirrBitmapEx(rImage.GetBitmapEx());
+        aMirrBitmapEx.Mirror(BmpMirrorFlags::Horizontal);
+        return Image(aMirrBitmapEx);
+    }
+
+    GdkPixbuf* getPixbuf(const css::uno::Reference<css::graphic::XGraphic>& 
rImage, bool bMirror = false)
     {
         Image aImage(rImage);
+        if (bMirror)
+            aImage = mirrorImage(aImage);
 
         OUString sStock(aImage.GetStock());
         if (!sStock.isEmpty())
@@ -11649,6 +11658,7 @@ private:
 
     std::map<OString, GtkWidget*> m_aMap;
     std::map<OString, std::unique_ptr<GtkInstanceMenuButton>> m_aMenuButtonMap;
+    std::map<OString, bool> m_aMirroredMap;
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
     // at the time of writing there is no gtk_menu_tool_button_set_popover 
available
@@ -11813,14 +11823,14 @@ private:
 #endif
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
-    static void set_item_image(GtkToolButton* pItem, const 
css::uno::Reference<css::graphic::XGraphic>& rIcon)
+    static void set_item_image(GtkToolButton* pItem, const 
css::uno::Reference<css::graphic::XGraphic>& rIcon, bool bMirror)
 #else
-    static void set_item_image(GtkWidget* pItem, const 
css::uno::Reference<css::graphic::XGraphic>& rIcon)
+    static void set_item_image(GtkWidget* pItem, const 
css::uno::Reference<css::graphic::XGraphic>& rIcon, bool bMirror)
 #endif
     {
         GtkWidget* pImage = nullptr;
 
-        if (GdkPixbuf* pixbuf = getPixbuf(rIcon))
+        if (GdkPixbuf* pixbuf = getPixbuf(rIcon, bMirror))
         {
             pImage = gtk_image_new_from_pixbuf(pixbuf);
             g_object_unref(pixbuf);
@@ -12194,17 +12204,24 @@ public:
 #endif
     }
 
+    virtual void set_item_image_mirrored(const OString& rIdent, bool 
bMirrored) override
+    {
+        m_aMirroredMap[rIdent] = bMirrored;
+    }
+
     virtual void set_item_image(const OString& rIdent, const 
css::uno::Reference<css::graphic::XGraphic>& rIcon) override
     {
         GtkWidget* pItem = m_aMap[rIdent];
+        auto it = m_aMirroredMap.find(rIdent);
+        bool bMirrored = it != m_aMirroredMap.end() && it->second;
 #if !GTK_CHECK_VERSION(4, 0, 0)
         if (!pItem || !GTK_IS_TOOL_BUTTON(pItem))
             return;
-        set_item_image(GTK_TOOL_BUTTON(pItem), rIcon);
+        set_item_image(GTK_TOOL_BUTTON(pItem), rIcon, bMirrored);
 #else
         if (!pItem)
             return;
-        set_item_image(pItem, rIcon);
+        set_item_image(pItem, rIcon, bMirrored);
 #endif
     }
 
@@ -12228,9 +12245,9 @@ public:
 #if !GTK_CHECK_VERSION(4, 0, 0)
         if (!GTK_IS_TOOL_BUTTON(pItem))
             return;
-        set_item_image(GTK_TOOL_BUTTON(pItem), rIcon);
+        set_item_image(GTK_TOOL_BUTTON(pItem), rIcon, false);
 #else
-        set_item_image(pItem, rIcon);
+        set_item_image(pItem, rIcon, false);
 #endif
     }
 

Reply via email to