diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-04-30 10:19:19 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-09-28 08:48:18 +0100 |
commit | 8f256819b14044afce7e8cf44fbecbe1cb8cb4cf (patch) | |
tree | ad2e593ff37101618789bf9eca4b08e1b4e1d253 | |
parent | d3f29153feb273e2e14375045323356bd550abb7 (diff) |
implement RadioButton groups
-rw-r--r-- | vcl/inc/vcl/builder.hxx | 16 | ||||
-rw-r--r-- | vcl/inc/vcl/button.hxx | 12 | ||||
-rw-r--r-- | vcl/source/control/button.cxx | 42 | ||||
-rw-r--r-- | vcl/source/window/builder.cxx | 46 |
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('_', '-'); } } } |