[Libreoffice-commits] core.git: cui/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Jan 8 21:01:03 UTC 2019


 cui/source/inc/cuitabline.hxx  |    1 
 cui/source/tabpages/tpline.cxx |   17 +-
 vcl/unx/gtk3/gtk3gtkinst.cxx   |  323 +++++++++++++++++++++++------------------
 3 files changed, 193 insertions(+), 148 deletions(-)

New commits:
commit 6b4ea2d8ddd681fec98773d7e0bbec9657a1fc08
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jan 8 16:48:20 2019 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Jan 8 22:00:37 2019 +0100

    tdf#122527 dot symbols in chart menubutton not working
    
    a few problems here
    
    *) each symbol was drawn on top of the previous one instead of clearing it
    *) some spurious placeholder text in the menu entry
    *) m_nSymbolType not set correctly on activation of a submenu entry
    *) under gtk3 adding entries to the submenus didn't inform the
       menubutton of their addition
    *) we can drop m_xMenu because set_item_sensitive can be used
       instead, which didn't exist at the initial time of writing
    
    Change-Id: Id339992c4192f3782fddfd56cb3e9b67cfcbe2a2
    Reviewed-on: https://gerrit.libreoffice.org/65977
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/cui/source/inc/cuitabline.hxx b/cui/source/inc/cuitabline.hxx
index 639ad645c7ce..284a0e656a55 100644
--- a/cui/source/inc/cuitabline.hxx
+++ b/cui/source/inc/cuitabline.hxx
@@ -148,7 +148,6 @@ private:
     std::unique_ptr<weld::MetricSpinButton> m_xMtrEndWidth;
     std::unique_ptr<weld::CheckButton> m_xTsbCenterEnd;
     std::unique_ptr<weld::CheckButton> m_xCbxSynchronize;
-    std::unique_ptr<weld::Menu> m_xMenu;
     std::unique_ptr<weld::Menu> m_xGalleryMenu;
     std::unique_ptr<weld::Menu> m_xSymbolsMenu;
     std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
diff --git a/cui/source/tabpages/tpline.cxx b/cui/source/tabpages/tpline.cxx
index c71f5de04910..1fb061467e77 100644
--- a/cui/source/tabpages/tpline.cxx
+++ b/cui/source/tabpages/tpline.cxx
@@ -108,7 +108,6 @@ SvxLineTabPage::SvxLineTabPage(TabPageParent pParent, const SfxItemSet& rInAttrs
     , m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_END_WIDTH", FieldUnit::CM))
     , m_xTsbCenterEnd(m_xBuilder->weld_check_button("TSB_CENTER_END"))
     , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
-    , m_xMenu(m_xBuilder->weld_menu("menuSELECT"))
     , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
     , m_xFLEdgeStyle(m_xBuilder->weld_widget("FL_EDGE_STYLE"))
     , m_xGridEdgeCaps(m_xBuilder->weld_widget("gridEDGE_CAPS"))
@@ -1410,7 +1409,7 @@ IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::ToggleButton&, void)
                     aBitmap.Scale(nScale, nScale);
 
                 }
-                pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
+                pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
                 pVD->DrawBitmapEx(Point(), aBitmap);
                 m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
             }
@@ -1422,7 +1421,7 @@ IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::ToggleButton&, void)
         }
 
         if (m_aGrfNames.empty())
-            m_xMenu->set_sensitive("gallery", false);
+            m_xSymbolMB->set_item_sensitive("gallery", false);
     }
 
     if (!m_xSymbolsMenu && m_pSymbolList)
@@ -1494,15 +1493,15 @@ IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::ToggleButton&, void)
                                         double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
                     aBitmapEx.Scale(nScale, nScale);
                 }
-                pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel(), false);
+                pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel());
                 pVD->DrawBitmapEx(Point(), aBitmapEx);
-                m_xSymbolsMenu->append(pInfo->sItemId, "foo", *pVD);
+                m_xSymbolsMenu->append(pInfo->sItemId, "", *pVD);
             }
             pInvisibleSquare=pPage->RemoveObject(0);
             SdrObject::Free(pInvisibleSquare);
 
             if (m_aGrfNames.empty())
-                m_xMenu->set_sensitive("symbols", false);
+                m_xSymbolMB->set_item_sensitive("symbols", false);
         }
     }
 }
@@ -1522,10 +1521,12 @@ IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
     {
         SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[sNumber.toUInt32()].get();
         pGraphic = pInfo->pBrushItem->GetGraphic();
+        m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
     }
     else if (rIdent.startsWith("symbol", &sNumber))
     {
-        SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[sNumber.toUInt32()].get();
+        m_nSymbolType = sNumber.toUInt32();
+        SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
         pGraphic = pInfo->pBrushItem->GetGraphic();
     }
     else if (rIdent == "automatic")
@@ -1559,7 +1560,7 @@ IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
             return;
     }
 
-    if(pGraphic)
+    if (pGraphic)
     {
         Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
         aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index ef712f5b6584..265a921f3f7c 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1894,145 +1894,6 @@ public:
     }
 };
 
-class GtkInstanceMenu : public MenuHelper, public virtual weld::Menu
-{
-protected:
-    OString m_sActivated;
-
-private:
-    virtual void signal_activate(GtkMenuItem* pItem) override
-    {
-        const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pItem));
-        m_sActivated = OString(pStr, pStr ? strlen(pStr) : 0);
-    }
-
-public:
-    GtkInstanceMenu(GtkMenu* pMenu, bool bTakeOwnership)
-        : MenuHelper(pMenu, bTakeOwnership)
-    {
-    }
-
-    virtual OString popup_at_rect(weld::Widget* pParent, const tools::Rectangle &rRect) override
-    {
-        m_sActivated.clear();
-
-        GtkInstanceWidget* pGtkWidget = dynamic_cast<GtkInstanceWidget*>(pParent);
-        assert(pGtkWidget);
-
-        GtkWidget* pWidget = pGtkWidget->getWidget();
-        gtk_menu_attach_to_widget(m_pMenu, pWidget, nullptr);
-
-        //run in a sub main loop because we need to keep vcl PopupMenu alive to use
-        //it during DispatchCommand, returning now to the outer loop causes the
-        //launching PopupMenu to be destroyed, instead run the subloop here
-        //until the gtk menu is destroyed
-        GMainLoop* pLoop = g_main_loop_new(nullptr, true);
-        gulong nSignalId = g_signal_connect_swapped(G_OBJECT(m_pMenu), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop);
-
-#if GTK_CHECK_VERSION(3,22,0)
-        if (gtk_check_version(3, 22, 0) == nullptr)
-        {
-            GdkRectangle aRect{static_cast<int>(rRect.Left()), static_cast<int>(rRect.Top()),
-                               static_cast<int>(rRect.GetWidth()), static_cast<int>(rRect.GetHeight())};
-            if (AllSettings::GetLayoutRTL())
-                aRect.x = gtk_widget_get_allocated_width(pWidget) - aRect.width - 1 - aRect.x;
-            gtk_menu_popup_at_rect(m_pMenu, gtk_widget_get_window(pWidget), &aRect, GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST, nullptr);
-        }
-        else
-#else
-        (void) rRect;
-#endif
-        {
-            guint nButton;
-            guint32 nTime;
-
-            //typically there is an event, and we can then distinguish if this was
-            //launched from the keyboard (gets auto-mnemoniced) or the mouse (which
-            //doesn't)
-            GdkEvent *pEvent = gtk_get_current_event();
-            if (pEvent)
-            {
-                gdk_event_get_button(pEvent, &nButton);
-                nTime = gdk_event_get_time(pEvent);
-            }
-            else
-            {
-                nButton = 0;
-                nTime = GtkSalFrame::GetLastInputEventTime();
-            }
-
-            gtk_menu_popup(m_pMenu, nullptr, nullptr, nullptr, nullptr, nButton, nTime);
-        }
-
-        if (g_main_loop_is_running(pLoop))
-        {
-            gdk_threads_leave();
-            g_main_loop_run(pLoop);
-            gdk_threads_enter();
-        }
-        g_main_loop_unref(pLoop);
-        g_signal_handler_disconnect(m_pMenu, nSignalId);
-
-        return m_sActivated;
-    }
-
-    virtual void set_sensitive(const OString& rIdent, bool bSensitive) override
-    {
-        set_item_sensitive(rIdent, bSensitive);
-    }
-
-    virtual void set_active(const OString& rIdent, bool bActive) override
-    {
-        set_item_active(rIdent, bActive);
-    }
-
-    virtual void show(const OString& rIdent, bool bShow) override
-    {
-        show_item(rIdent, bShow);
-    }
-
-    virtual void insert(int pos, const OUString& rId, const OUString& rStr,
-                        const OUString* pIconName, VirtualDevice* pImageSufface,
-                        bool bCheck) override
-    {
-        GtkWidget* pImage = nullptr;
-        if (pIconName)
-        {
-            GdkPixbuf* pixbuf = load_icon_by_name(*pIconName);
-            if (!pixbuf)
-            {
-                pImage = gtk_image_new_from_pixbuf(pixbuf);
-                g_object_unref(pixbuf);
-            }
-        }
-        else if (pImageSufface)
-            pImage = gtk_image_new_from_surface(get_underlying_cairo_surface(*pImageSufface));
-
-        GtkWidget *pItem;
-        if (pImage)
-        {
-            GtkWidget *pBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-            GtkWidget *pLabel = gtk_label_new(MapToGtkAccelerator(rStr).getStr());
-            pItem = bCheck ? gtk_check_menu_item_new() : gtk_menu_item_new();
-            gtk_container_add(GTK_CONTAINER(pBox), pImage);
-            gtk_container_add(GTK_CONTAINER(pBox), pLabel);
-            gtk_container_add(GTK_CONTAINER(pItem), pBox);
-            gtk_widget_show_all(pItem);
-        }
-        else
-        {
-            pItem = bCheck ? gtk_check_menu_item_new_with_label(MapToGtkAccelerator(rStr).getStr())
-                           : gtk_menu_item_new_with_label(MapToGtkAccelerator(rStr).getStr());
-        }
-        gtk_buildable_set_name(GTK_BUILDABLE(pItem), OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr());
-        gtk_menu_shell_append(GTK_MENU_SHELL(m_pMenu), pItem);
-        gtk_widget_show(pItem);
-        add_to_map(GTK_MENU_ITEM(pItem));
-        if (pos != -1)
-            gtk_menu_reorder_child(m_pMenu, pItem, pos);
-    }
-};
-
 class GtkInstanceSizeGroup : public weld::SizeGroup
 {
 private:
@@ -4233,6 +4094,190 @@ public:
     }
 };
 
+class GtkInstanceMenu : public MenuHelper, public virtual weld::Menu
+{
+protected:
+    OString m_sActivated;
+    GtkInstanceMenuButton* m_pTopLevelMenuButton;
+
+private:
+    virtual void signal_activate(GtkMenuItem* pItem) override
+    {
+        const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pItem));
+        m_sActivated = OString(pStr, pStr ? strlen(pStr) : 0);
+    }
+
+public:
+    GtkInstanceMenu(GtkMenu* pMenu, bool bTakeOwnership)
+        : MenuHelper(pMenu, bTakeOwnership)
+        , m_pTopLevelMenuButton(nullptr)
+    {
+        // tdf#122527 if we're welding a submenu of a menu of a MenuButton,
+        // then find that MenuButton parent so that when adding items to this
+        // menu we can inform the MenuButton of their addition
+        GtkMenu* pTopLevelMenu = pMenu;
+        while (true)
+        {
+            GtkWidget* pAttached = gtk_menu_get_attach_widget(pTopLevelMenu);
+            if (!pAttached || !GTK_IS_MENU_ITEM(pAttached))
+                break;
+            GtkWidget* pParent = gtk_widget_get_parent(pAttached);
+            if (!pParent || !GTK_IS_MENU(pParent))
+                break;
+            pTopLevelMenu = GTK_MENU(pParent);
+        }
+        if (pTopLevelMenu != pMenu)
+        {
+            GtkWidget* pAttached = gtk_menu_get_attach_widget(pTopLevelMenu);
+            if (pAttached && GTK_IS_MENU_BUTTON(pAttached))
+            {
+                void* pData = g_object_get_data(G_OBJECT(pAttached), "g-lo-GtkInstanceButton");
+                m_pTopLevelMenuButton = dynamic_cast<GtkInstanceMenuButton*>(static_cast<GtkInstanceButton*>(pData));
+            }
+        }
+    }
+
+    virtual OString popup_at_rect(weld::Widget* pParent, const tools::Rectangle &rRect) override
+    {
+        m_sActivated.clear();
+
+        GtkInstanceWidget* pGtkWidget = dynamic_cast<GtkInstanceWidget*>(pParent);
+        assert(pGtkWidget);
+
+        GtkWidget* pWidget = pGtkWidget->getWidget();
+        gtk_menu_attach_to_widget(m_pMenu, pWidget, nullptr);
+
+        //run in a sub main loop because we need to keep vcl PopupMenu alive to use
+        //it during DispatchCommand, returning now to the outer loop causes the
+        //launching PopupMenu to be destroyed, instead run the subloop here
+        //until the gtk menu is destroyed
+        GMainLoop* pLoop = g_main_loop_new(nullptr, true);
+        gulong nSignalId = g_signal_connect_swapped(G_OBJECT(m_pMenu), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop);
+
+#if GTK_CHECK_VERSION(3,22,0)
+        if (gtk_check_version(3, 22, 0) == nullptr)
+        {
+            GdkRectangle aRect{static_cast<int>(rRect.Left()), static_cast<int>(rRect.Top()),
+                               static_cast<int>(rRect.GetWidth()), static_cast<int>(rRect.GetHeight())};
+            if (AllSettings::GetLayoutRTL())
+                aRect.x = gtk_widget_get_allocated_width(pWidget) - aRect.width - 1 - aRect.x;
+            gtk_menu_popup_at_rect(m_pMenu, gtk_widget_get_window(pWidget), &aRect, GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST, nullptr);
+        }
+        else
+#else
+        (void) rRect;
+#endif
+        {
+            guint nButton;
+            guint32 nTime;
+
+            //typically there is an event, and we can then distinguish if this was
+            //launched from the keyboard (gets auto-mnemoniced) or the mouse (which
+            //doesn't)
+            GdkEvent *pEvent = gtk_get_current_event();
+            if (pEvent)
+            {
+                gdk_event_get_button(pEvent, &nButton);
+                nTime = gdk_event_get_time(pEvent);
+            }
+            else
+            {
+                nButton = 0;
+                nTime = GtkSalFrame::GetLastInputEventTime();
+            }
+
+            gtk_menu_popup(m_pMenu, nullptr, nullptr, nullptr, nullptr, nButton, nTime);
+        }
+
+        if (g_main_loop_is_running(pLoop))
+        {
+            gdk_threads_leave();
+            g_main_loop_run(pLoop);
+            gdk_threads_enter();
+        }
+        g_main_loop_unref(pLoop);
+        g_signal_handler_disconnect(m_pMenu, nSignalId);
+
+        return m_sActivated;
+    }
+
+    virtual void set_sensitive(const OString& rIdent, bool bSensitive) override
+    {
+        set_item_sensitive(rIdent, bSensitive);
+    }
+
+    virtual void set_active(const OString& rIdent, bool bActive) override
+    {
+        set_item_active(rIdent, bActive);
+    }
+
+    virtual void show(const OString& rIdent, bool bShow) override
+    {
+        show_item(rIdent, bShow);
+    }
+
+    virtual void insert(int pos, const OUString& rId, const OUString& rStr,
+                        const OUString* pIconName, VirtualDevice* pImageSufface,
+                        bool bCheck) override
+    {
+        GtkWidget* pImage = nullptr;
+        if (pIconName)
+        {
+            GdkPixbuf* pixbuf = load_icon_by_name(*pIconName);
+            if (!pixbuf)
+            {
+                pImage = gtk_image_new_from_pixbuf(pixbuf);
+                g_object_unref(pixbuf);
+            }
+        }
+        else if (pImageSufface)
+        {
+            cairo_surface_t* surface = get_underlying_cairo_surface(*pImageSufface);
+
+            Size aSize(pImageSufface->GetOutputSizePixel());
+            cairo_surface_t* target = cairo_surface_create_similar(surface,
+                                                                    cairo_surface_get_content(surface),
+                                                                    aSize.Width(),
+                                                                    aSize.Height());
+
+            cairo_t* cr = cairo_create(target);
+            cairo_set_source_surface(cr, surface, 0, 0);
+            cairo_paint(cr);
+            cairo_destroy(cr);
+
+            pImage = gtk_image_new_from_surface(target);
+
+            cairo_surface_destroy(target);
+        }
+
+        GtkWidget *pItem;
+        if (pImage)
+        {
+            GtkWidget *pBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
+            GtkWidget *pLabel = gtk_label_new(MapToGtkAccelerator(rStr).getStr());
+            pItem = bCheck ? gtk_check_menu_item_new() : gtk_menu_item_new();
+            gtk_container_add(GTK_CONTAINER(pBox), pImage);
+            gtk_container_add(GTK_CONTAINER(pBox), pLabel);
+            gtk_container_add(GTK_CONTAINER(pItem), pBox);
+            gtk_widget_show_all(pItem);
+        }
+        else
+        {
+            pItem = bCheck ? gtk_check_menu_item_new_with_label(MapToGtkAccelerator(rStr).getStr())
+                           : gtk_menu_item_new_with_label(MapToGtkAccelerator(rStr).getStr());
+        }
+        gtk_buildable_set_name(GTK_BUILDABLE(pItem), OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr());
+        gtk_menu_shell_append(GTK_MENU_SHELL(m_pMenu), pItem);
+        gtk_widget_show(pItem);
+        GtkMenuItem* pMenuItem = GTK_MENU_ITEM(pItem);
+        add_to_map(pMenuItem);
+        if (m_pTopLevelMenuButton)
+            m_pTopLevelMenuButton->add_to_map(pMenuItem);
+        if (pos != -1)
+            gtk_menu_reorder_child(m_pMenu, pItem, pos);
+    }
+};
+
 class GtkInstanceRadioButton : public GtkInstanceToggleButton, public virtual weld::RadioButton
 {
 public:


More information about the Libreoffice-commits mailing list