summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2013-05-03 09:48:27 +0100
committerCaolán McNamara <caolanm@redhat.com>2013-05-03 09:49:04 +0100
commitba69c0851b99a0f063e0f82fe93f22db25f65de8 (patch)
tree623fa72798d400b15f9543a9aecaa1c23ad02800
parent2e2e1fecd5768829d6c0a2133206d2d740b941af (diff)
implement native button order for messageboxes
Change-Id: I85d0991da3d2a1efa9d5c15569164d8bd2194356
-rw-r--r--include/vcl/builder.hxx10
-rw-r--r--include/vcl/layout.hxx6
-rw-r--r--sfx2/uiconfig/ui/querysavedialog.ui12
-rw-r--r--vcl/source/window/layout.cxx110
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();
}