diff options
author | Caolán McNamara <caolanm@redhat.com> | 2013-05-03 09:48:27 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-05-03 09:49:04 +0100 |
commit | ba69c0851b99a0f063e0f82fe93f22db25f65de8 (patch) | |
tree | 623fa72798d400b15f9543a9aecaa1c23ad02800 | |
parent | 2e2e1fecd5768829d6c0a2133206d2d740b941af (diff) |
implement native button order for messageboxes
Change-Id: I85d0991da3d2a1efa9d5c15569164d8bd2194356
-rw-r--r-- | include/vcl/builder.hxx | 10 | ||||
-rw-r--r-- | include/vcl/layout.hxx | 6 | ||||
-rw-r--r-- | sfx2/uiconfig/ui/querysavedialog.ui | 12 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 110 |
4 files changed, 128 insertions, 10 deletions
diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx index fc7a28690bc4..9ad812e7aa54 100644 --- a/include/vcl/builder.hxx +++ b/include/vcl/builder.hxx @@ -290,9 +290,14 @@ public: static OString extractCustomProperty(stringmap &rMap); - //see m_aDeferredProperties + //see m_aDeferredProperties, you need this for toplevel dialogs + //which build themselves from their ctor. The properties on + //the top level are stored in m_aDeferredProperties and need + //to be applied post ctor void setDeferredProperties(); + //Helpers to retrofit all the existing code to the builder + static void reorderWithinParent(Window &rWindow, sal_uInt16 nNewPosition); private: Window *insertObject(Window *pParent, const OString &rClass, const OString &rID, stringmap &rProps, stringmap &rPangoAttributes, @@ -350,9 +355,6 @@ private: void cleanupWidgetOwnScrolling(Window *pScrollParent, Window *pWindow, stringmap &rMap); void set_response(OString sID, short nResponse); - - //Helpers to retrofit all the existing code to the builder - static void reorderWithinParent(Window &rWindow, sal_uInt16 nNewPosition); }; diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx index f45fcb239089..5237c72c9bce 100644 --- a/include/vcl/layout.hxx +++ b/include/vcl/layout.hxx @@ -61,6 +61,7 @@ class VCL_DLLPUBLIC VclBox : public VclContainer { protected: bool m_bHomogeneous; + bool m_bVerticalContainer; int m_nSpacing; public: VclBox(Window *pParent, bool bHomogeneous, int nSpacing) @@ -112,6 +113,7 @@ public: VclVBox(Window *pParent, bool bHomogeneous = false, int nSpacing = 0) : VclBox(pParent, bHomogeneous, nSpacing) { + m_bVerticalContainer = true; } protected: virtual long getPrimaryDimension(const Size &rSize) const @@ -158,6 +160,7 @@ public: VclHBox(Window *pParent, bool bHomogeneous = false, int nSpacing = 0) : VclBox(pParent, bHomogeneous, nSpacing) { + m_bVerticalContainer = false; } protected: virtual long getPrimaryDimension(const Size &rSize) const @@ -225,6 +228,7 @@ public: return m_eLayoutStyle; } virtual bool set_property(const OString &rKey, const OString &rValue); + void sort_native_button_order(); protected: virtual Size calculateRequisition() const; virtual void setAllocation(const Size &rAllocation); @@ -248,6 +252,7 @@ public: VclVButtonBox(Window *pParent, int nSpacing = 0) : VclButtonBox(pParent, nSpacing) { + m_bVerticalContainer = true; } protected: virtual long getPrimaryDimension(const Size &rSize) const @@ -294,6 +299,7 @@ public: VclHButtonBox(Window *pParent, int nSpacing = 0) : VclButtonBox(pParent, nSpacing) { + m_bVerticalContainer = false; } protected: virtual long getPrimaryDimension(const Size &rSize) const diff --git a/sfx2/uiconfig/ui/querysavedialog.ui b/sfx2/uiconfig/ui/querysavedialog.ui index 42d0371bfd07..8fdce8118291 100644 --- a/sfx2/uiconfig/ui/querysavedialog.ui +++ b/sfx2/uiconfig/ui/querysavedialog.ui @@ -20,7 +20,7 @@ <property name="can_focus">False</property> <property name="layout_style">end</property> <child> - <object class="GtkButton" id="button3"> + <object class="GtkButton" id="discard"> <property name="label" translatable="yes">Close _without saving</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -34,7 +34,7 @@ </packing> </child> <child> - <object class="GtkButton" id="button1"> + <object class="GtkButton" id="cancel"> <property name="label">gtk-cancel</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -49,7 +49,7 @@ </packing> </child> <child> - <object class="GtkButton" id="button2"> + <object class="GtkButton" id="save"> <property name="label">gtk-save</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -75,9 +75,9 @@ </object> </child> <action-widgets> - <action-widget response="3">button3</action-widget> - <action-widget response="0">button1</action-widget> - <action-widget response="2">button2</action-widget> + <action-widget response="3">discard</action-widget> + <action-widget response="0">cancel</action-widget> + <action-widget response="2">save</action-widget> </action-widgets> </object> </interface> diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index 84351e2709da..d19ffaeba42d 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -11,6 +11,7 @@ #include <vcl/dialog.hxx> #include <vcl/layout.hxx> #include <vcl/msgbox.hxx> +#include <vcl/svapp.hxx> #include "window.h" VclContainer::VclContainer(Window *pParent, WinBits nStyle) @@ -596,6 +597,110 @@ void VclButtonBox::setAllocation(const Size &rAllocation) } } +struct ButtonOrder +{ + OString m_aType; + int m_nPriority; +}; + +int getButtonPriority(const OString &rType) +{ + const size_t N_TYPES = 3; + static const ButtonOrder aDiscardCancelSave[N_TYPES] = + { + { "/discard", 0 }, + { "/cancel", 1 }, + { "/save", 2 } + }; + + static const ButtonOrder aSaveDiscardCancel[N_TYPES] = + { + { "/save", 0 }, + { "/discard", 1 }, + { "/cancel", 2 } + }; + + const ButtonOrder* pOrder = &aDiscardCancelSave[0]; + + const OUString &rEnv = Application::GetDesktopEnvironment(); + + if (rEnv.equalsIgnoreAsciiCase("windows") || + rEnv.equalsIgnoreAsciiCase("kde4") || + rEnv.equalsIgnoreAsciiCase("tde") || + rEnv.equalsIgnoreAsciiCase("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; +} + +class sortButtons + : public std::binary_function<const Window*, const Window*, bool> +{ + bool m_bVerticalContainer; +public: + sortButtons(bool bVerticalContainer) + : m_bVerticalContainer(bVerticalContainer) + { + } + bool operator()(const Window *pA, const Window *pB) const; +}; + +bool sortButtons::operator()(const Window *pA, const Window *pB) const +{ + //sort into two groups of pack start and pack end + VclPackType ePackA = pA->get_pack_type(); + VclPackType ePackB = pB->get_pack_type(); + if (ePackA < ePackB) + return true; + if (ePackA > ePackB) + return false; + bool bPackA = pA->get_secondary(); + bool bPackB = pB->get_secondary(); + if (!m_bVerticalContainer) + { + //for horizontal boxes group secondaries before primaries + if (bPackA > bPackB) + return true; + if (bPackA < bPackB) + return false; + } + else + { + //for vertical boxes group secondaries after primaries + if (bPackA < bPackB) + return true; + if (bPackA > bPackB) + return false; + } + + //now order within groups according to platform rules + return getButtonPriority(pA->GetHelpId()) < getButtonPriority(pB->GetHelpId()); +} + +void VclButtonBox::sort_native_button_order() +{ + std::vector<Window*> aChilds; + for (Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; + pChild = pChild->GetWindow(WINDOW_NEXT)) + { + aChilds.push_back(pChild); + } + + //sort child order within parent so that we match the platform + //button order + std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(m_bVerticalContainer)); + for (size_t i = 0; i < aChilds.size(); ++i) + VclBuilder::reorderWithinParent(*aChilds[i], i); +} + VclGrid::array_type VclGrid::assembleGrid() const { ext_array_type A; @@ -1692,6 +1797,11 @@ short MessageDialog::Execute() m_pGrid->Show(); setButtonHandlers(); + + VclButtonBox *pButtonBox = get_action_area(); + assert(pButtonBox); + pButtonBox->sort_native_button_order(); + } return Dialog::Execute(); } |