cui/source/dialogs/AdditionsDialog.cxx | 10 +-- cui/source/inc/AdditionsDialog.hxx | 4 - include/vcl/weld.hxx | 15 ++++ vcl/inc/qt5/QtInstanceBuilder.hxx | 1 vcl/inc/salvtables.hxx | 15 ++++ vcl/qt5/QtInstanceBuilder.cxx | 6 + vcl/source/app/salvtables.cxx | 46 +++++++++++++++ vcl/unx/gtk3/gtkinst.cxx | 101 +++++++++++++++++++++++++++++++++ 8 files changed, 191 insertions(+), 7 deletions(-)
New commits: commit b7faeb1a70ee57c19531bc0f23538dd0ce6f07d1 Author: Michael Weghorn <[email protected]> AuthorDate: Mon Dec 16 11:42:05 2024 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Tue Dec 17 22:54:19 2024 +0100 weld: Port AdditionsDialog to new weld::Grid API See previous commit Change-Id: I67f5ea16b5108e8359820850f0815e34db439ef1 Author: Michael Weghorn <[email protected]> Date: Mon Dec 16 11:02:00 2024 +0100 weld: Add weld::Grid to handle grid child positions for more background. The changed code path can e.g. be triggered in Writer as follows: * "File" -> "Templates" -> "Manage Templates", * click the "Manage" combobox * select the "Extensions" entry Change-Id: I28f258fde8700ade4d5c6ded39d6063f31bc2e30 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178571 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/cui/source/dialogs/AdditionsDialog.cxx b/cui/source/dialogs/AdditionsDialog.cxx index a8eabf6d369c..ed35df71468e 100644 --- a/cui/source/dialogs/AdditionsDialog.cxx +++ b/cui/source/dialogs/AdditionsDialog.cxx @@ -433,7 +433,7 @@ AdditionsDialog::AdditionsDialog(weld::Window* pParent, const OUString& sAdditio , m_xEntrySearch(m_xBuilder->weld_entry(u"entrySearch"_ustr)) , m_xButtonClose(m_xBuilder->weld_button(u"buttonClose"_ustr)) , m_xContentWindow(m_xBuilder->weld_scrolled_window(u"contentWindow"_ustr)) - , m_xContentGrid(m_xBuilder->weld_container(u"contentGrid"_ustr)) + , m_xContentGrid(m_xBuilder->weld_grid(u"contentGrid"_ustr)) , m_xLabelProgress(m_xBuilder->weld_label(u"labelProgress"_ustr)) , m_xGearBtn(m_xBuilder->weld_menu_button(u"buttonGear"_ustr)) { @@ -602,9 +602,9 @@ bool AdditionsDialog::sortByDownload(const AdditionInfo& a, const AdditionInfo& return a.sDownloadNumber.toUInt32() > b.sDownloadNumber.toUInt32(); } -AdditionsItem::AdditionsItem(weld::Widget* pParent, AdditionsDialog* pParentDialog, +AdditionsItem::AdditionsItem(weld::Grid* pParentGrid, AdditionsDialog* pParentDialog, const AdditionInfo& additionInfo) - : m_xBuilder(Application::CreateBuilder(pParent, u"cui/ui/additionsfragment.ui"_ustr)) + : m_xBuilder(Application::CreateBuilder(pParentGrid, u"cui/ui/additionsfragment.ui"_ustr)) , m_xContainer(m_xBuilder->weld_widget(u"additionsEntry"_ustr)) , m_xImageScreenshot(m_xBuilder->weld_image(u"imageScreenshot"_ustr)) , m_xButtonInstall(m_xBuilder->weld_button(u"buttonInstall"_ustr)) @@ -629,8 +629,8 @@ AdditionsItem::AdditionsItem(weld::Widget* pParent, AdditionsDialog* pParentDial SolarMutexGuard aGuard; // AdditionsItem set location - m_xContainer->set_grid_left_attach(0); - m_xContainer->set_grid_top_attach(pParentDialog->m_aAdditionsItems.size()); + pParentGrid->set_child_left_attach(*m_xContainer, 0); + pParentGrid->set_child_top_attach(*m_xContainer, pParentDialog->m_aAdditionsItems.size()); // Set maximum length of the extension title OUString sExtensionName; diff --git a/cui/source/inc/AdditionsDialog.hxx b/cui/source/inc/AdditionsDialog.hxx index 559a4ca911ff..f94eefd3addb 100644 --- a/cui/source/inc/AdditionsDialog.hxx +++ b/cui/source/inc/AdditionsDialog.hxx @@ -72,7 +72,7 @@ public: std::vector<AdditionInfo> m_aAllExtensionsVector; // Stores the all extensions' info std::unique_ptr<weld::ScrolledWindow> m_xContentWindow; - std::unique_ptr<weld::Container> m_xContentGrid; + std::unique_ptr<weld::Grid> m_xContentGrid; std::unique_ptr<weld::Label> m_xLabelProgress; std::unique_ptr<weld::MenuButton> m_xGearBtn; @@ -102,7 +102,7 @@ public: class AdditionsItem { public: - AdditionsItem(weld::Widget* pParent, AdditionsDialog* pParentDialog, + AdditionsItem(weld::Grid* pParentGrid, AdditionsDialog* pParentDialog, const AdditionInfo& additionInfo); bool getExtensionFile(OUString& sExtensionFile); commit 7056ea9c29c7e454c21b525e61cdc1e0c03f7301 Author: Michael Weghorn <[email protected]> AuthorDate: Mon Dec 16 11:02:00 2024 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Tue Dec 17 22:54:10 2024 +0100 weld: Add weld::Grid to handle grid child positions Currently, weld::Widget provides methods that can be used to retrieve and change the position (and column span) of widgets that are located inside of a grid (parent), e.g. weld::Widget::set_grid_left_attach to set the column. These methods however only make sense for widgets that are actually direct children of a grid, not for any "random" weld::Widget. Generally, it's the grid's responsibility to manage child positions, and the gtk3/gtk4 implementations actually assume that the parent is a GtkGrid, retrieve that parent and then call the corresponding GTK API functions for that grid. Align the weld API more with the concept of the grid being responsible for positioning its children by introducing a new weld::Grid class with methods equivalent to the current weld::Widget ones, but that take the child widget as an additional parameter. Take over the existing logic from the corresponding weld::Widget methods for both, the gtk and vcl implementations (e.g. GtkInstanceWidget::set_grid_left_attach -> GtkInstanceGrid::set_child_left_attach). Add an assert that the passed widget is actually a grid child. Deprecate the existing weld::Widget methods for grid position handling. They will be removed once existing code has been ported to the new weld::Grid API. The fact that the vcl implementation, VclGrid (used by vcl's new SalInstanceGrid implementation of weld::Grid), still relies on its vcl::Window children having the corresponding members set correctly remains unaffected. Change-Id: I67f5ea16b5108e8359820850f0815e34db439ef1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178570 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index ebe2d8a25ef8..32fd70fd575b 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -195,6 +195,10 @@ public: virtual OUString get_help_id() const = 0; virtual void set_help_id(const OUString& rName) = 0; + // NOTE: The following 5 methods for handling grid positions + // and column span are deprecated and should not be used in new code. + // Call the corresponding weld::Grid methods on the parent grid instead. + // (These deprecated methods will be dropped once existing code has been ported.) virtual void set_grid_left_attach(int nAttach) = 0; virtual int get_grid_left_attach() const = 0; virtual void set_grid_width(int nCols) = 0; @@ -422,6 +426,16 @@ public: virtual void sort_native_button_order() = 0; }; +class VCL_DLLPUBLIC Grid : virtual public Container +{ +public: + virtual void set_child_left_attach(weld::Widget& rWidget, int nAttach) = 0; + virtual int get_child_left_attach(weld::Widget& rWidget) const = 0; + virtual void set_child_column_span(weld::Widget& rWidget, int nCols) = 0; + virtual void set_child_top_attach(weld::Widget& rWidget, int nAttach) = 0; + virtual int get_child_top_attach(weld::Widget& rWidget) const = 0; +}; + class VCL_DLLPUBLIC Paned : virtual public Container { public: @@ -2657,6 +2671,7 @@ public: virtual std::unique_ptr<Widget> weld_widget(const OUString& id) = 0; virtual std::unique_ptr<Container> weld_container(const OUString& id) = 0; virtual std::unique_ptr<Box> weld_box(const OUString& id) = 0; + virtual std::unique_ptr<Grid> weld_grid(const OUString& id) = 0; virtual std::unique_ptr<Paned> weld_paned(const OUString& id) = 0; virtual std::unique_ptr<Button> weld_button(const OUString& id) = 0; virtual std::unique_ptr<MenuButton> weld_menu_button(const OUString& id) = 0; diff --git a/vcl/inc/qt5/QtInstanceBuilder.hxx b/vcl/inc/qt5/QtInstanceBuilder.hxx index fe200913dfdd..3380b8beb571 100644 --- a/vcl/inc/qt5/QtInstanceBuilder.hxx +++ b/vcl/inc/qt5/QtInstanceBuilder.hxx @@ -36,6 +36,7 @@ public: virtual std::unique_ptr<weld::Widget> weld_widget(const OUString& rId) override; virtual std::unique_ptr<weld::Container> weld_container(const OUString& rId) override; virtual std::unique_ptr<weld::Box> weld_box(const OUString&) override; + virtual std::unique_ptr<weld::Grid> weld_grid(const OUString& rId) override; virtual std::unique_ptr<weld::Paned> weld_paned(const OUString&) override; virtual std::unique_ptr<weld::Frame> weld_frame(const OUString& rId) override; virtual std::unique_ptr<weld::ScrolledWindow> diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 62dc0e8ea8db..c51f2c12a999 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -64,6 +64,8 @@ public: virtual std::unique_ptr<weld::Box> weld_box(const OUString& id) override; + virtual std::unique_ptr<weld::Grid> weld_grid(const OUString& id) override; + virtual std::unique_ptr<weld::Paned> weld_paned(const OUString& id) override; virtual std::unique_ptr<weld::Frame> weld_frame(const OUString& id) override; @@ -2137,6 +2139,19 @@ public: virtual void sort_native_button_order() override; }; +class SalInstanceGrid : public SalInstanceContainer, public virtual weld::Grid +{ +public: + SalInstanceGrid(VclGrid* pGrid, SalInstanceBuilder* pBuilder, bool bTakeOwnership); + +public: + virtual void set_child_left_attach(weld::Widget& rWidget, int nAttach) override; + virtual int get_child_left_attach(weld::Widget& rWidget) const override; + virtual void set_child_column_span(weld::Widget& rWidget, int nCols) override; + virtual void set_child_top_attach(weld::Widget& rWidget, int nAttach) override; + virtual int get_child_top_attach(weld::Widget& rWidget) const override; +}; + class SalInstanceImage : public SalInstanceWidget, public virtual weld::Image { private: diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 66561985ee94..342986862de4 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -153,6 +153,12 @@ std::unique_ptr<weld::Box> QtInstanceBuilder::weld_box(const OUString&) return nullptr; } +std::unique_ptr<weld::Grid> QtInstanceBuilder::weld_grid(const OUString&) +{ + assert(false && "Not implemented yet"); + return nullptr; +} + std::unique_ptr<weld::Paned> QtInstanceBuilder::weld_paned(const OUString&) { assert(false && "Not implemented yet"); diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 2533f7def9d5..c8edbc05da2f 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -1528,6 +1528,46 @@ void SalInstanceBox::reorder_child(weld::Widget* pWidget, int nNewPosition) void SalInstanceBox::sort_native_button_order() { ::sort_native_button_order(*m_xBox); } +SalInstanceGrid::SalInstanceGrid(VclGrid* pGrid, SalInstanceBuilder* pBuilder, bool bTakeOwnership) + : SalInstanceContainer(pGrid, pBuilder, bTakeOwnership) +{ +} + +void SalInstanceGrid::set_child_left_attach(weld::Widget& rWidget, int nAttach) +{ + vcl::Window* pChild = dynamic_cast<SalInstanceWidget&>(rWidget).getWidget(); + assert(pChild && pChild->GetParent() == getWidget() && "widget is not a grid child"); + pChild->set_grid_left_attach(nAttach); +} + +int SalInstanceGrid::get_child_left_attach(weld::Widget& rWidget) const +{ + vcl::Window* pChild = dynamic_cast<SalInstanceWidget&>(rWidget).getWidget(); + assert(pChild && pChild->GetParent() == getWidget() && "widget is not a grid child"); + return pChild->get_grid_left_attach(); +} + +void SalInstanceGrid::set_child_column_span(weld::Widget& rWidget, int nCols) +{ + vcl::Window* pChild = dynamic_cast<SalInstanceWidget&>(rWidget).getWidget(); + assert(pChild && pChild->GetParent() == getWidget() && "widget is not a grid child"); + pChild->set_grid_width(nCols); +} + +void SalInstanceGrid::set_child_top_attach(weld::Widget& rWidget, int nAttach) +{ + vcl::Window* pChild = dynamic_cast<SalInstanceWidget&>(rWidget).getWidget(); + assert(pChild && pChild->GetParent() == getWidget() && "widget is not a grid child"); + pChild->set_grid_top_attach(nAttach); +} + +int SalInstanceGrid::get_child_top_attach(weld::Widget& rWidget) const +{ + vcl::Window* pChild = dynamic_cast<SalInstanceWidget&>(rWidget).getWidget(); + assert(pChild && pChild->GetParent() == getWidget() && "widget is not a grid child"); + return pChild->get_grid_top_attach(); +} + namespace { void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft, @@ -7262,6 +7302,12 @@ std::unique_ptr<weld::Box> SalInstanceBuilder::weld_box(const OUString& id) return pContainer ? std::make_unique<SalInstanceBox>(pContainer, this, false) : nullptr; } +std::unique_ptr<weld::Grid> SalInstanceBuilder::weld_grid(const OUString& id) +{ + VclGrid* pGrid = m_xBuilder->get<VclGrid>(id); + return pGrid ? std::make_unique<SalInstanceGrid>(pGrid, this, false) : nullptr; +} + std::unique_ptr<weld::Paned> SalInstanceBuilder::weld_paned(const OUString& id) { VclPaned* pPaned = m_xBuilder->get<VclPaned>(id); diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 729d4dcc93ac..c3042eab5b77 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -6201,6 +6201,98 @@ public: } }; +class GtkInstanceGrid : public GtkInstanceContainer, public virtual weld::Grid +{ +private: + GtkGrid* m_pGrid; + +public: + GtkInstanceGrid(GtkGrid* pGrid, GtkInstanceBuilder* pBuilder, bool bTakeOwnership) +#if !GTK_CHECK_VERSION(4, 0, 0) + : GtkInstanceContainer(GTK_CONTAINER(pGrid), pBuilder, bTakeOwnership) +#else + : GtkInstanceContainer(GTK_WIDGET(pGrid), pBuilder, bTakeOwnership) +#endif + , m_pGrid(pGrid) + { + } + +public: + virtual void set_child_left_attach(weld::Widget& rWidget, int nAttach) override + { + GtkWidget* pWidget = dynamic_cast<GtkInstanceWidget&>(rWidget).getWidget(); + assert(gtk_widget_get_parent(pWidget) == GTK_WIDGET(m_pGrid) && "widget is not a grid child"); +#if GTK_CHECK_VERSION(4, 0, 0) + int row, width, height; + gtk_grid_query_child(m_pGrid, pWidget, nullptr, &row, &width, &height); + g_object_ref(pWidget); + gtk_grid_remove(m_pGrid, pWidget); + gtk_grid_attach(m_pGrid, pWidget, nAttach, row, width, height); + g_object_unref(pWidget); +#else + gtk_container_child_set(GTK_CONTAINER(m_pGrid), pWidget, "left-attach", nAttach, nullptr); +#endif + } + + virtual int get_child_left_attach(weld::Widget& rWidget) const override + { + GtkWidget* pWidget = dynamic_cast<GtkInstanceWidget&>(rWidget).getWidget(); + assert(gtk_widget_get_parent(pWidget) == GTK_WIDGET(m_pGrid) && "widget is not a grid child"); + gint nAttach(0); +#if GTK_CHECK_VERSION(4, 0, 0) + gtk_grid_query_child(m_pGrid, pWidget, &nAttach, nullptr, nullptr, nullptr); +#else + gtk_container_child_get(GTK_CONTAINER(m_pGrid), pWidget, "left-attach", &nAttach, nullptr); +#endif + return nAttach; + } + + virtual void set_child_column_span(weld::Widget& rWidget, int nCols) override + { + GtkWidget* pWidget = dynamic_cast<GtkInstanceWidget&>(rWidget).getWidget(); + assert(gtk_widget_get_parent(pWidget) == GTK_WIDGET(m_pGrid) && "widget is not a grid child"); +#if GTK_CHECK_VERSION(4, 0, 0) + int col, row, height; + gtk_grid_query_child(m_pGrid, pWidget, &col, &row, nullptr, &height); + g_object_ref(pWidget); + gtk_grid_remove(m_pGrid, pWidget); + gtk_grid_attach(m_pGrid, pWidget, col, row, nCols, height); + g_object_unref(pWidget); +#else + gtk_container_child_set(GTK_CONTAINER(m_pGrid), pWidget, "width", nCols, nullptr); +#endif + } + + virtual void set_child_top_attach(weld::Widget& rWidget, int nAttach) override + { + GtkWidget* pWidget = dynamic_cast<GtkInstanceWidget&>(rWidget).getWidget(); + assert(gtk_widget_get_parent(pWidget) == GTK_WIDGET(m_pGrid) && "widget is not a grid child"); +#if GTK_CHECK_VERSION(4, 0, 0) + int col, width, height; + gtk_grid_query_child(m_pGrid, pWidget, &col, nullptr, &width, &height); + g_object_ref(pWidget); + gtk_grid_remove(m_pGrid, pWidget); + gtk_grid_attach(m_pGrid, pWidget, col, nAttach, width, height); + g_object_unref(pWidget); +#else + gtk_container_child_set(GTK_CONTAINER(m_pGrid), pWidget, "top-attach", nAttach, nullptr); +#endif + } + + virtual int get_child_top_attach(weld::Widget& rWidget) const override + { + GtkWidget* pWidget = dynamic_cast<GtkInstanceWidget&>(rWidget).getWidget(); + assert(gtk_widget_get_parent(pWidget) == GTK_WIDGET(m_pGrid) && "widget is not a grid child"); + gint nAttach(0); +#if GTK_CHECK_VERSION(4, 0, 0) + gtk_grid_query_child(m_pGrid, pWidget, nullptr, &nAttach, nullptr, nullptr); +#else + gtk_container_child_get(GTK_CONTAINER(m_pGrid), pWidget, "top-attach", &nAttach, nullptr); +#endif + return nAttach; + } +}; + } namespace @@ -24586,6 +24678,15 @@ public: return std::make_unique<GtkInstanceBox>(pBox, this, false); } + virtual std::unique_ptr<weld::Grid> weld_grid(const OUString &id) override + { + GtkGrid* pGrid = GTK_GRID(gtk_builder_get_object(m_pBuilder, OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr())); + if (!pGrid) + return nullptr; + auto_add_parentless_widgets_to_container(GTK_WIDGET(pGrid)); + return std::make_unique<GtkInstanceGrid>(pGrid, this, false); + } + virtual std::unique_ptr<weld::Paned> weld_paned(const OUString &id) override { GtkPaned* pPaned = GTK_PANED(gtk_builder_get_object(m_pBuilder, OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr()));
