summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2012-04-30 10:19:19 +0100
committerCaolán McNamara <caolanm@redhat.com>2012-09-28 08:48:18 +0100
commit8f256819b14044afce7e8cf44fbecbe1cb8cb4cf (patch)
treead2e593ff37101618789bf9eca4b08e1b4e1d253
parentd3f29153feb273e2e14375045323356bd550abb7 (diff)
implement RadioButton groups
-rw-r--r--vcl/inc/vcl/builder.hxx16
-rw-r--r--vcl/inc/vcl/button.hxx12
-rw-r--r--vcl/source/control/button.cxx42
-rw-r--r--vcl/source/window/builder.cxx46
4 files changed, 102 insertions, 14 deletions
diff --git a/vcl/inc/vcl/builder.hxx b/vcl/inc/vcl/builder.hxx
index ffb2e5410fcd..730fd34e15f1 100644
--- a/vcl/inc/vcl/builder.hxx
+++ b/vcl/inc/vcl/builder.hxx
@@ -49,6 +49,19 @@ private:
}
};
std::vector<WinAndId> m_aChildren;
+
+ struct RadioButtonGroupMap
+ {
+ rtl::OString m_sID;
+ rtl::OString m_sGroup;
+ RadioButtonGroupMap(const rtl::OString &rId, const rtl::OString &rGroup)
+ : m_sID(rId)
+ , m_sGroup(rGroup)
+ {
+ }
+ };
+ std::vector<RadioButtonGroupMap> m_aGroups;
+
rtl::OString m_sID;
Window *m_pParent;
public:
@@ -60,7 +73,8 @@ public:
typedef std::map<rtl::OString, rtl::OString> stringmap;
private:
Window *insertObject(Window *pParent, const rtl::OString &rClass, const rtl::OString &rID, stringmap &rVec);
- Window *makeObject(Window *pParent, const rtl::OString &rClass, stringmap &rVec);
+ Window *makeObject(Window *pParent, const rtl::OString &rClass, const rtl::OString &rID, stringmap &rVec);
+ bool extractGroup(const rtl::OString &id, stringmap &rVec);
void handleChild(Window *pParent, xmlreader::XmlReader &reader);
Window* handleObject(Window *pParent, xmlreader::XmlReader &reader);
diff --git a/vcl/inc/vcl/button.hxx b/vcl/inc/vcl/button.hxx
index 1c42ec2455b9..d47abe219c5c 100644
--- a/vcl/inc/vcl/button.hxx
+++ b/vcl/inc/vcl/button.hxx
@@ -37,6 +37,7 @@
#include <vcl/bitmap.hxx>
#include <vcl/salnativewidgets.hxx>
+#include <set>
#include <vector>
class UserDrawEvent;
@@ -287,10 +288,10 @@ private:
Rectangle maStateRect;
Rectangle maMouseRect;
Image maImage;
- sal_Bool mbChecked;
- sal_Bool mbSaveValue;
- sal_Bool mbRadioCheck;
- sal_Bool mbStateChanged;
+ sal_Bool mbChecked;
+ sal_Bool mbSaveValue;
+ sal_Bool mbRadioCheck;
+ sal_Bool mbStateChanged;
Link maToggleHdl;
// when mbLegacyNoTextAlign is set then the old behaviour where
// the WB_LEFT, WB_RIGHT & WB_CENTER affect the image placement
@@ -316,6 +317,8 @@ private:
SAL_DLLPRIVATE RadioButton& operator= (const RadioButton &);
protected:
+ boost::shared_ptr< std::set<RadioButton*> > m_xGroup;
+
using Control::ImplInitSettings;
using Window::ImplInit;
SAL_DLLPRIVATE void ImplInit( Window* pParent, WinBits nStyle );
@@ -400,6 +403,7 @@ public:
void GetRadioButtonGroup( std::vector<RadioButton*>& io_rGroup, bool bIncludeThis ) const;
virtual bool set_property(const rtl::OString &rKey, const rtl::OString &rValue);
+ void group(RadioButton &rOther);
};
// ------------
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index ea1900142e0a..93b4065a3e5e 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -2291,13 +2291,51 @@ void RadioButton::ImplDrawRadioButton( bool bLayout )
}
}
-// -----------------------------------------------------------------------
+void RadioButton::group(RadioButton &rOther)
+{
+ if (!m_xGroup)
+ {
+ m_xGroup.reset(new std::set<RadioButton*>);
+ m_xGroup->insert(this);
+ }
+
+ if (rOther.m_xGroup)
+ {
+ for (std::set<RadioButton*>::iterator aI = rOther.m_xGroup->begin(), aEnd = rOther.m_xGroup->end(); aI != aEnd; ++aI)
+ m_xGroup->insert(*aI);
+ }
+
+ m_xGroup->insert(&rOther);
+
+ rOther.m_xGroup = m_xGroup;
+
+ //if this one is checked, uncheck all the others
+ if (mbChecked)
+ ImplUncheckAllOther();
+}
+
+// .-----------------------------------------------------------------------
void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const
{
// empty the list
io_rGroup.clear();
+ if (m_xGroup)
+ {
+ for (std::set<RadioButton*>::iterator aI = m_xGroup->begin(), aEnd = m_xGroup->end(); aI != aEnd; ++aI)
+ {
+ RadioButton *pRadioButton = *aI;
+ if (pRadioButton == this)
+ continue;
+ io_rGroup.push_back(pRadioButton);
+ }
+ return;
+ }
+
+ //old-school
+ SAL_WARN("vcl", "No group set on radiobutton");
+
// go back to first in group;
Window* pFirst = const_cast<RadioButton*>(this);
while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
@@ -2416,6 +2454,8 @@ void RadioButton::ImplLoadRes( const ResId& rResId )
RadioButton::~RadioButton()
{
+ if (m_xGroup)
+ m_xGroup->erase(this);
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 2a1edca0a07f..183b7180ba11 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -39,11 +39,24 @@ VclBuilder::VclBuilder(Window *pParent, rtl::OUString sUri, rtl::OString sID)
: m_sID(sID)
, m_pParent(pParent)
{
- fprintf(stderr, "now trying %s\n", rtl::OUStringToOString(sUri, RTL_TEXTENCODING_UTF8).getStr());
xmlreader::XmlReader reader(sUri);
handleChild(pParent, reader);
+ //Set radiobutton groups when everything has been imported
+ for (std::vector<RadioButtonGroupMap>::iterator aI = m_aGroups.begin(),
+ aEnd = m_aGroups.end(); aI != aEnd; ++aI)
+ {
+ RadioButton *pOne = static_cast<RadioButton*>(get_by_name(aI->m_sID));
+ RadioButton *pOther = static_cast<RadioButton*>(get_by_name(aI->m_sGroup));
+ SAL_WARN_IF(!pOne || !pOther, "vcl", "missing member of radiobutton group");
+ if (pOne && pOther)
+ pOne->group(*pOther);
+ }
+ //drop maps now
+ std::vector<RadioButtonGroupMap>().swap(m_aGroups);
+
+ //auto-show (really necessary ?, maybe drop it when complete)
for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
aEnd = m_aChildren.end(); aI != aEnd; ++aI)
{
@@ -119,7 +132,19 @@ namespace
}
}
-Window *VclBuilder::makeObject(Window *pParent, const rtl::OString &name, stringmap &rMap)
+bool VclBuilder::extractGroup(const rtl::OString &id, stringmap &rMap)
+{
+ VclBuilder::stringmap::iterator aFind = rMap.find(rtl::OString(RTL_CONSTASCII_STRINGPARAM("group")));
+ if (aFind != rMap.end())
+ {
+ m_aGroups.push_back(RadioButtonGroupMap(id, aFind->second));
+ rMap.erase(aFind);
+ return true;
+ }
+ return false;
+}
+
+Window *VclBuilder::makeObject(Window *pParent, const rtl::OString &name, const rtl::OString &id, stringmap &rMap)
{
Window *pWindow = NULL;
if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkDialog")))
@@ -147,7 +172,10 @@ Window *VclBuilder::makeObject(Window *pParent, const rtl::OString &name, string
else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkButton")))
pWindow = extractStockAndBuildButton(pParent, rMap);
else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkRadioButton")))
+ {
+ extractGroup(id, rMap);
pWindow = new RadioButton(pParent, WB_CENTER|WB_VCENTER|WB_3DLOOK);
+ }
else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkCheckButton")))
pWindow = new CheckBox(pParent, WB_CENTER|WB_VCENTER|WB_3DLOOK);
else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkSpinButton")))
@@ -171,17 +199,13 @@ Window *VclBuilder::insertObject(Window *pParent, const rtl::OString &rClass, co
if (!m_sID.isEmpty() && rID.equals(m_sID))
{
pCurrentChild = m_pParent;
- fprintf(stderr, "inserting into parent dialog\n");
//toplevels default to resizable
if (pCurrentChild->IsDialog())
- {
- fprintf(stderr, "forcing resizable\n");
pCurrentChild->SetStyle(pCurrentChild->GetStyle() | WB_SIZEMOVE);
- }
}
else
{
- pCurrentChild = makeObject(pParent, rClass, rMap);
+ pCurrentChild = makeObject(pParent, rClass, rID, rMap);
if (!pCurrentChild)
fprintf(stderr, "missing object!\n");
else
@@ -429,7 +453,13 @@ void VclBuilder::collectProperty(xmlreader::XmlReader &reader, stringmap &rMap)
reader.nextItem(
xmlreader::XmlReader::TEXT_NORMALIZED, &name, &nsId);
rtl::OString sValue(name.begin, name.length);
- rMap[sProperty] = sValue.replace('_', '-');
+ //replace '_' with '-' except for property values that
+ //refer to widget ids themselves. TO-DO, drop conversion
+ //and just use foo_bar properties throughout
+ if (sProperty.equalsL(RTL_CONSTASCII_STRINGPARAM("group")))
+ rMap[sProperty] = sValue;
+ else
+ rMap[sProperty] = sValue.replace('_', '-');
}
}
}