include/vcl/layout.hxx | 8 + include/vcl/weld.hxx | 2 sc/source/ui/cctrl/checklistmenu.cxx | 2 vcl/source/app/salvtables.cxx | 17 ++- vcl/source/window/layout.cxx | 8 - vcl/unx/gtk3/gtk3gtkinst.cxx | 153 ++++++++++++++++++----------------- 6 files changed, 107 insertions(+), 83 deletions(-)
New commits: commit c4892a47195685cd36fe91be872206f517abc45b Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Sun May 31 16:16:37 2020 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Thu Dec 10 14:06:43 2020 +0100 allow sorting buttons via weld::Box Change-Id: I315fe2dd2e40c976edd802c1e87b7ccdb0c298fe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95221 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107523 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx index b89cf0449ffb..89a4ad72d447 100644 --- a/include/vcl/layout.hxx +++ b/include/vcl/layout.hxx @@ -94,6 +94,10 @@ public: { m_bHomogeneous = bHomogeneous; } + bool get_orientation() const + { + return m_bVerticalContainer; + } virtual bool set_property(const OString &rKey, const OUString &rValue) override; virtual boost::property_tree::ptree DumpAsPropertyTree() override; protected: @@ -211,7 +215,6 @@ public: { } virtual bool set_property(const OString &rKey, const OUString &rValue) override; - void sort_native_button_order(); virtual boost::property_tree::ptree DumpAsPropertyTree() override; protected: virtual Size calculateRequisition() const override; @@ -868,6 +871,9 @@ Size getLegacyBestSizeForChildren(const vcl::Window &rWindow); //Get first parent which is not a layout widget vcl::Window* getNonLayoutParent(vcl::Window *pParent); +//Sort ok/cancel etc buttons in platform order +void sort_native_button_order(VclBox& rContainer); + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 8e91050cc3a5..20f219154ee1 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -270,6 +270,8 @@ class VCL_DLLPUBLIC Box : virtual public Container public: // Moves child to a new position in the list of children virtual void reorder_child(weld::Widget* pWidget, int position) = 0; + // Sort ok/cancel etc buttons in platform order + virtual void sort_native_button_order() = 0; }; class VCL_DLLPUBLIC ScrolledWindow : virtual public Container diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index deeb987ee806..c913d8ddfb00 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -495,7 +495,7 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v // sort ok/cancel into native order, if this was a dialog they would be auto-sorted, but this // popup isn't a true dialog - //mxButtonBox->sort_native_button_order(); + mxButtonBox->sort_native_button_order(); if (!bIsSubMenu) { diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 12503e478646..af2f66ca9b0e 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -1146,9 +1146,12 @@ std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const class SalInstanceBox : public SalInstanceContainer, public virtual weld::Box { +private: + VclPtr<VclBox> m_xBox; public: - SalInstanceBox(vcl::Window* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership) + SalInstanceBox(VclBox* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership) : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership) + , m_xBox(pContainer) { } virtual void reorder_child(weld::Widget* pWidget, int nNewPosition) override @@ -1157,6 +1160,10 @@ public: assert(pVclWidget); pVclWidget->getWidget()->reorderWithinParent(nNewPosition); } + virtual void sort_native_button_order() override + { + ::sort_native_button_order(*m_xBox); + } }; namespace @@ -1415,7 +1422,7 @@ bool SalInstanceDialog::runAsync(std::shared_ptr<weld::DialogController> aOwner, aCtx.maEndDialogFn = rEndDialogFn; VclButtonBox* pActionArea = m_xDialog->get_action_area(); if (pActionArea) - pActionArea->sort_native_button_order(); + sort_native_button_order(*pActionArea); return m_xDialog->StartExecuteAsync(aCtx); } @@ -1429,7 +1436,7 @@ bool SalInstanceDialog::runAsync(std::shared_ptr<Dialog> const & rxSelf, const s aCtx.maEndDialogFn = rEndDialogFn; VclButtonBox* pActionArea = m_xDialog->get_action_area(); if (pActionArea) - pActionArea->sort_native_button_order(); + sort_native_button_order(*pActionArea); return m_xDialog->StartExecuteAsync(aCtx); } @@ -1506,7 +1513,7 @@ int SalInstanceDialog::run() { VclButtonBox* pActionArea = m_xDialog->get_action_area(); if (pActionArea) - pActionArea->sort_native_button_order(); + sort_native_button_order(*pActionArea); return m_xDialog->Execute(); } @@ -5961,7 +5968,7 @@ std::unique_ptr<weld::Container> SalInstanceBuilder::weld_container(const OStrin std::unique_ptr<weld::Box> SalInstanceBuilder::weld_box(const OString &id, bool bTakeOwnership) { - vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id); + VclBox* pContainer = m_xBuilder->get<VclBox>(id); return pContainer ? std::make_unique<SalInstanceBox>(pContainer, this, bTakeOwnership) : nullptr; } diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index d3f57be71fef..68a87ad67245 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -811,10 +811,10 @@ bool sortButtons::operator()(const vcl::Window *pA, const vcl::Window *pB) const return getButtonPriority(pA->GetHelpId()) < getButtonPriority(pB->GetHelpId()); } -void VclButtonBox::sort_native_button_order() +void sort_native_button_order(VclBox& rContainer) { std::vector<vcl::Window*> aChilds; - for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild; + for (vcl::Window* pChild = rContainer.GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next)) { aChilds.push_back(pChild); @@ -822,7 +822,7 @@ void VclButtonBox::sort_native_button_order() //sort child order within parent so that we match the platform //button order - std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(m_bVerticalContainer)); + std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(rContainer.get_orientation())); BuilderUtils::reorderWithinParent(aChilds, true); } @@ -2203,7 +2203,7 @@ void MessageDialog::create_message_area() break; } set_default_response(nDefaultResponse); - pButtonBox->sort_native_button_order(); + sort_native_button_order(*pButtonBox); m_pMessageBox->Show(); m_pGrid->Show(); } diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 72177d63e1f9..8850c8f87c88 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -3310,6 +3310,82 @@ std::unique_ptr<weld::Container> GtkInstanceWidget::weld_parent() const return std::make_unique<GtkInstanceContainer>(GTK_CONTAINER(pParent), m_pBuilder, false); } +namespace { + +struct ButtonOrder +{ + const char * m_aType; + int m_nPriority; +}; + +int getButtonPriority(const OString &rType) +{ + static const size_t N_TYPES = 7; + static const ButtonOrder aDiscardCancelSave[N_TYPES] = + { + { "/discard", 0 }, + { "/cancel", 1 }, + { "/no", 2 }, + { "/open", 3 }, + { "/save", 3 }, + { "/yes", 3 }, + { "/ok", 3 } + }; + + static const ButtonOrder aSaveDiscardCancel[N_TYPES] = + { + { "/open", 0 }, + { "/save", 0 }, + { "/yes", 0 }, + { "/ok", 0 }, + { "/discard", 1 }, + { "/no", 1 }, + { "/cancel", 2 } + }; + + const ButtonOrder* pOrder = &aDiscardCancelSave[0]; + + const OUString &rEnv = Application::GetDesktopEnvironment(); + + if (rEnv.equalsIgnoreAsciiCase("windows") || + rEnv.equalsIgnoreAsciiCase("tde") || + rEnv.startsWithIgnoreAsciiCase("kde")) + { + pOrder = &aSaveDiscardCancel[0]; + } + + for (size_t i = 0; i < N_TYPES; ++i, ++pOrder) + { + if (rType.endsWith(pOrder->m_aType)) + return pOrder->m_nPriority; + } + + return -1; +} + +bool sortButtons(const GtkWidget* pA, const GtkWidget* pB) +{ + //order within groups according to platform rules + return getButtonPriority(::get_help_id(pA)) < getButtonPriority(::get_help_id(pB)); +} + +void sort_native_button_order(GtkBox* pContainer) +{ + std::vector<GtkWidget*> aChildren; + GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pContainer)); + for (GList* pChild = g_list_first(pChildren); pChild; pChild = g_list_next(pChild)) + aChildren.push_back(static_cast<GtkWidget*>(pChild->data)); + g_list_free(pChildren); + + //sort child order within parent so that we match the platform button order + std::stable_sort(aChildren.begin(), aChildren.end(), sortButtons); + + for (size_t pos = 0; pos < aChildren.size(); ++pos) + gtk_box_reorder_child(pContainer, aChildren[pos], pos); +} + +} + class GtkInstanceBox : public GtkInstanceContainer, public virtual weld::Box { private: @@ -3329,6 +3405,11 @@ public: GtkWidget* pChild = pGtkWidget->getWidget(); gtk_box_reorder_child(m_pBox, pChild, nNewPosition); } + + virtual void sort_native_button_order() override + { + ::sort_native_button_order(m_pBox); + } }; namespace @@ -3348,78 +3429,6 @@ namespace namespace { - struct ButtonOrder - { - const char * m_aType; - int m_nPriority; - }; - - int getButtonPriority(const OString &rType) - { - static const size_t N_TYPES = 7; - static const ButtonOrder aDiscardCancelSave[N_TYPES] = - { - { "/discard", 0 }, - { "/cancel", 1 }, - { "/no", 2 }, - { "/open", 3 }, - { "/save", 3 }, - { "/yes", 3 }, - { "/ok", 3 } - }; - - static const ButtonOrder aSaveDiscardCancel[N_TYPES] = - { - { "/open", 0 }, - { "/save", 0 }, - { "/yes", 0 }, - { "/ok", 0 }, - { "/discard", 1 }, - { "/no", 1 }, - { "/cancel", 2 } - }; - - const ButtonOrder* pOrder = &aDiscardCancelSave[0]; - - const OUString &rEnv = Application::GetDesktopEnvironment(); - - if (rEnv.equalsIgnoreAsciiCase("windows") || - rEnv.equalsIgnoreAsciiCase("tde") || - rEnv.startsWithIgnoreAsciiCase("kde")) - { - pOrder = &aSaveDiscardCancel[0]; - } - - for (size_t i = 0; i < N_TYPES; ++i, ++pOrder) - { - if (rType.endsWith(pOrder->m_aType)) - return pOrder->m_nPriority; - } - - return -1; - } - - bool sortButtons(const GtkWidget* pA, const GtkWidget* pB) - { - //order within groups according to platform rules - return getButtonPriority(::get_help_id(pA)) < getButtonPriority(::get_help_id(pB)); - } - - void sort_native_button_order(GtkBox* pContainer) - { - std::vector<GtkWidget*> aChildren; - GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pContainer)); - for (GList* pChild = g_list_first(pChildren); pChild; pChild = g_list_next(pChild)) - aChildren.push_back(static_cast<GtkWidget*>(pChild->data)); - g_list_free(pChildren); - - //sort child order within parent so that we match the platform button order - std::stable_sort(aChildren.begin(), aChildren.end(), sortButtons); - - for (size_t pos = 0; pos < aChildren.size(); ++pos) - gtk_box_reorder_child(pContainer, aChildren[pos], pos); - } - Point get_csd_offset(GtkWidget* pTopLevel) { // try and omit drawing CSD under wayland _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits