On Wed, 2008-05-21 at 16:19 +0200, Frank Schönheit - Sun Microsystems
Germany wrote:
> + In your current patch, both the toolkit controls and the form controls
>   declare a GroupName property, which leads to ambiguities at runtime.

Fixed.  Though one thing I don't quite understand is why
ORadioButtonModel::_propertyChanged() can't call
OReferenceValueComponent::_propertyChanged() when the
PROPERTY_GROUP_NAME property is changed.  If I do call the
OReferenceValueComponent version, I get a spew of warnings beginning
with:

        Error:
        File 
/home/jon/Development/OpenOffice.org/dev300-m10/forms/source/component/FormComponent.cxx,
 Line 1404: OBoundControlModel::_propertyChanged: where did this come from (1)?

> - in toolkit/source/controls/dialogcontrol.cxx:
>     const ::rtl::OUString GROUP_NAME (::rtl::OUString::createFromAscii(
>       "GroupName" ) );
>   Just a side note here: Those should usually be written as
>     const ::rtl::OUString GROUP_NAME ( RTL_CONSTASCII_USTRINGPARAM(
>       "GroupName" ) );
>   , as this is more efficient. It doesn't really matter here, it's just
>   a question of being used to it when it actually does matter.

Fixed.

> - UnoControlDialogModel::AddRadioButtonToGroup
>   - pGroups is superfluous
>   + the method name is misleading - it suggests the radio button is
>     actually added, which is not the case.
>   - pNamedGroups and pCurGroup should be reference parameters, not
>     pointers, since they cannot be NULL

Fixed?  It's a large-ish refactor, so opinions may vary.

> - the below code in implUpdateGroupStructure
>     if        (  (( nThisModelStep == nCurrentGroupStep )
>         ||    ( 0 == nThisModelStep ))
>         && sGroupName == sCurGroup
>         )
>   has a weird indention after your changes: Both || and && are at the
>   same level, though they don't have the same priority/level. Putting an
>   IF-clause in multiple lines as in thise case has the reason to allow
>   to see the levels *without* actually examing the brackets.
>   (Well, at least for people being used to read multi-line IFs with this
>   pattern, the changed version is misleading.)

As part of above refactor, this was move dinto a ::AddRadioButtonGroup()
method, and the indenting changed for clarity.

> - the loop at the end of UnoControlDialogModel::implUpdateGroupStructure
>   could be written with some ::std::copy / std::insert_iterator
>   (which would make it easier to understand as "it's a copy operation",
>   though not necessarily shorter to write)

I couldn't immediately figure out how to get i->second inserted as part
of the ::std::copy(), so this will have to wait for later.

> + there's stil no code for *reading* the GroupName property of a radio
>   button in a form

Is this the "need to save/load the GroupName form property into the ODF
file" issue?  As this still needs to be implemented...

Improved patch attached.

Thanks,
 - Jon

Index: extensions/inc/extensio.hrc
===================================================================
RCS file: /cvs/util/extensions/inc/extensio.hrc,v
retrieving revision 1.34
diff -u -p -r1.34 extensio.hrc
--- extensions/inc/extensio.hrc	11 Apr 2008 09:15:58 -0000	1.34
+++ extensions/inc/extensio.hrc	6 Jun 2008 20:18:38 -0000
@@ -157,7 +157,7 @@
 
 //-----------------------------------------------------------------------
     // FREE
-    // FREE
+#define HID_PROP_GROUP_NAME                     (HID_FORMS_START +   1)
 #define HID_PROP_GROUPBOX						(HID_FORMS_START +   2)
 #define HID_PROP_CONTROLSOURCE					(HID_FORMS_START +   3)
 #define HID_PROP_NAME							(HID_FORMS_START +   4)
Index: extensions/source/propctrlr/formmetadata.hxx
===================================================================
RCS file: /cvs/util/extensions/source/propctrlr/formmetadata.hxx,v
retrieving revision 1.35
diff -u -p -r1.35 formmetadata.hxx
--- extensions/source/propctrlr/formmetadata.hxx	11 Apr 2008 10:58:41 -0000	1.35
+++ extensions/source/propctrlr/formmetadata.hxx	6 Jun 2008 20:18:39 -0000
@@ -166,6 +166,7 @@ namespace pcr
 	#define PROPERTY_ID_ALLOWADDITIONS		 20
 	#define PROPERTY_ID_ALLOWEDITS			 21
 	#define PROPERTY_ID_ALLOWDELETIONS		 22
+	#define PROPERTY_ID_GROUP_NAME    		 23
 	#define PROPERTY_ID_NAVIGATION			 24
 	#define PROPERTY_ID_CYCLE				 25
 	#define PROPERTY_ID_HIDDEN_VALUE		 26
Index: extensions/source/propctrlr/formmetadata.cxx
===================================================================
RCS file: /cvs/util/extensions/source/propctrlr/formmetadata.cxx,v
retrieving revision 1.50
diff -u -p -r1.50 formmetadata.cxx
--- extensions/source/propctrlr/formmetadata.cxx	11 Apr 2008 10:58:09 -0000	1.50
+++ extensions/source/propctrlr/formmetadata.cxx	6 Jun 2008 20:18:42 -0000
@@ -142,6 +142,7 @@ namespace pcr
         DEF_INFO_2( TITLE,             TITLE,              TITLE,             FORM_VISIBLE, DIALOG_VISIBLE ),
         DEF_INFO_3( LABEL,             LABEL,              LABEL,             FORM_VISIBLE, DIALOG_VISIBLE, COMPOSEABLE ),
         DEF_INFO_2( CONTROLLABEL,      LABELCONTROL,       CONTROLLABEL,      FORM_VISIBLE, COMPOSEABLE ),
+        DEF_INFO_3( GROUP_NAME,        GROUP_NAME,         GROUP_NAME,        FORM_VISIBLE, DIALOG_VISIBLE, COMPOSEABLE ),
         DEF_INFO_2( TEXT,              TEXT,               TEXT,              DIALOG_VISIBLE, COMPOSEABLE ),
         DEF_INFO_3( MAXTEXTLEN,        MAXTEXTLEN,         MAXTEXTLEN,        FORM_VISIBLE, DIALOG_VISIBLE, COMPOSEABLE ),
         DEF_INFO_3( EDITMASK,          EDITMASK,           EDITMASK,          FORM_VISIBLE, DIALOG_VISIBLE, COMPOSEABLE ),
Index: extensions/source/propctrlr/formstrings.hxx
===================================================================
RCS file: /cvs/util/extensions/source/propctrlr/formstrings.hxx,v
retrieving revision 1.39
diff -u -p -r1.39 formstrings.hxx
--- extensions/source/propctrlr/formstrings.hxx	11 Apr 2008 11:01:21 -0000	1.39
+++ extensions/source/propctrlr/formstrings.hxx	6 Jun 2008 20:18:45 -0000
@@ -50,6 +50,7 @@ namespace pcr
 	PCR_CONSTASCII_STRING( PROPERTY_TABINDEX,				"TabIndex");
 	PCR_CONSTASCII_STRING( PROPERTY_TAG,					"Tag");
 	PCR_CONSTASCII_STRING( PROPERTY_NAME,					"Name");
+	PCR_CONSTASCII_STRING( PROPERTY_GROUP_NAME,             "GroupName");
 	PCR_CONSTASCII_STRING( PROPERTY_VALUE,					"Value");
 	PCR_CONSTASCII_STRING( PROPERTY_TEXT,					"Text");
 	PCR_CONSTASCII_STRING( PROPERTY_NAVIGATION,				"NavigationBarMode");
Index: extensions/source/propctrlr/formresid.hrc
===================================================================
RCS file: /cvs/util/extensions/source/propctrlr/formresid.hrc,v
retrieving revision 1.37
diff -u -p -r1.37 formresid.hrc
--- extensions/source/propctrlr/formresid.hrc	11 Apr 2008 11:00:24 -0000	1.37
+++ extensions/source/propctrlr/formresid.hrc	6 Jun 2008 20:18:46 -0000
@@ -147,7 +147,7 @@
 #define RID_STR_TAG							( RID_FORMBROWSER_START + 116 )
 #define RID_STR_HELPTEXT					( RID_FORMBROWSER_START + 117 )
 #define RID_STR_HELPURL						( RID_FORMBROWSER_START + 118 )
-    // FREE
+#define RID_STR_GROUP_NAME                  ( RID_FORMBROWSER_START + 119 )
 #define RID_STR_UNCHECKEDREFVALUE           ( RID_FORMBROWSER_START + 120 )
 #define RID_STR_CURSOR_TYPE					( RID_FORMBROWSER_START + 121 )
     // FREE
Index: extensions/source/propctrlr/formres.src
===================================================================
RCS file: /cvs/util/extensions/source/propctrlr/formres.src,v
retrieving revision 1.82
diff -u -p -r1.82 formres.src
--- extensions/source/propctrlr/formres.src	11 Apr 2008 10:59:33 -0000	1.82
+++ extensions/source/propctrlr/formres.src	6 Jun 2008 20:18:47 -0000
@@ -230,6 +230,10 @@ String RID_STR_NAME
 {
 	Text [ en-US ] = "Name" ;
 };
+String RID_STR_GROUP_NAME
+{
+	Text [ en-US ] = "Group name" ;
+};
 String RID_STR_TABINDEX
 {
 	Text [ en-US ] = "Tab order" ;
Index: extensions/util/hidother.src
===================================================================
RCS file: /cvs/util/extensions/util/hidother.src,v
retrieving revision 1.21
diff -u -p -r1.21 hidother.src
--- extensions/util/hidother.src	11 Apr 2008 12:12:27 -0000	1.21
+++ extensions/util/hidother.src	6 Jun 2008 20:18:48 -0000
@@ -306,3 +306,4 @@ hidspecial HID_CHECK_FOR_UPD_STATUS     
 hidspecial HID_CHECK_FOR_UPD_DESCRIPTION        { HelpId = HID_CHECK_FOR_UPD_DESCRIPTION; }
 hidspecial HID_CHECK_FOR_UPD_CANCEL             { HelpId = HID_CHECK_FOR_UPD_CANCEL; }
 hidspecial HID_PROP_NOLABEL                     { HelpId = HID_PROP_NOLABEL; }
+hidspecial HID_PROP_GROUP_NAME                  { HelpId = HID_PROP_GROUP_NAME; }
Index: forms/source/component/GroupManager.hxx
===================================================================
RCS file: /cvs/gsl/forms/source/component/GroupManager.hxx,v
retrieving revision 1.12
diff -u -p -r1.12 GroupManager.hxx
--- forms/source/component/GroupManager.hxx	11 Apr 2008 08:15:27 -0000	1.12
+++ forms/source/component/GroupManager.hxx	6 Jun 2008 20:18:49 -0000
@@ -220,6 +220,8 @@ public:
 	void getGroup(sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup, ::rtl::OUString& Name);
 	void getGroupByName(const ::rtl::OUString& Name, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup);
 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> > getControlModels();
+
+	static ::rtl::OUString GetGroupName( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xComponent );
 };
 
 
Index: forms/source/component/GroupManager.cxx
===================================================================
RCS file: /cvs/gsl/forms/source/component/GroupManager.cxx,v
retrieving revision 1.18
diff -u -p -r1.18 GroupManager.cxx
--- forms/source/component/GroupManager.cxx	11 Apr 2008 08:15:07 -0000	1.18
+++ forms/source/component/GroupManager.cxx	6 Jun 2008 20:18:50 -0000
@@ -127,14 +127,13 @@ OGroupComp::OGroupComp(const Reference<X
     ,m_xControlModel(rxSet,UNO_QUERY)
     ,m_nPos( nInsertPos )
     ,m_nTabIndex(0)
+    ,m_aName( OGroupManager::GetGroupName( rxSet ) )
 {
 	if (m_xComponent.is())
 	{
 		if (hasProperty( PROPERTY_TABINDEX, m_xComponent ) )
 			// Indices kleiner 0 werden wie 0 behandelt
 			m_nTabIndex = Max(getINT16(m_xComponent->getPropertyValue( PROPERTY_TABINDEX )) , sal_Int16(0));
-
-		m_xComponent->getPropertyValue( PROPERTY_NAME ) >>= m_aName;
 	}
 }
 
@@ -321,7 +320,8 @@ void OGroupManager::removeFromGroupMap(c
 		aFind->second.RemoveComponent( _xSet );
 
 		// Wenn Anzahl der Gruppenelemente == 1 ist, Gruppe deaktivieren
-		if ( aFind->second.Count() == 1 )
+		sal_Int32 nCount = aFind->second.Count();
+		if ( nCount == 1 || nCount == 0 )
 		{
 			OActiveGroups::iterator aActiveFind = ::std::find(
                 m_aActiveGroupMap.begin(),
@@ -332,7 +332,7 @@ void OGroupManager::removeFromGroupMap(c
             {
                 // the group is active. Deactivate it if the remaining component
                 // is *no* radio button
-                if ( !isRadioButton( aFind->second.GetObject( 0 ) ) )
+                if ( nCount == 0 || !isRadioButton( aFind->second.GetObject( 0 ) ) )
 				    m_aActiveGroupMap.erase( aActiveFind );
             }
 		}
@@ -341,6 +341,8 @@ void OGroupManager::removeFromGroupMap(c
 
 	// Bei Component als PropertyChangeListener abmelden
 	_xSet->removePropertyChangeListener( PROPERTY_NAME, this );
+	if (hasProperty(PROPERTY_GROUP_NAME, _xSet))
+		_xSet->removePropertyChangeListener( PROPERTY_GROUP_NAME, this );
 	if (hasProperty(PROPERTY_TABINDEX, _xSet))
 		_xSet->removePropertyChangeListener( PROPERTY_TABINDEX, this );
 }
@@ -351,10 +353,23 @@ void SAL_CALL OGroupManager::propertyCha
 
 	// Component aus Gruppe entfernen
 	::rtl::OUString		sGroupName;
-	if (evt.PropertyName == PROPERTY_NAME)
+	if (hasProperty( PROPERTY_GROUP_NAME, xSet ))
+		xSet->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
+	if (evt.PropertyName == PROPERTY_NAME) {
+		if (sGroupName.getLength() > 0)
+			return; // group hasn't changed; ignore this name change.
+		// no GroupName; use Name as GroupNme
+		evt.OldValue >>= sGroupName;
+	}
+	else if (evt.PropertyName == PROPERTY_GROUP_NAME) {
 		evt.OldValue >>= sGroupName;
+		if (sGroupName.getLength() == 0) {
+			// No prior GroupName; fallback to Nme
+			xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+		}
+	}
 	else
-		xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+		sGroupName = GetGroupName( xSet );
 
 	removeFromGroupMap(sGroupName,xSet);
 
@@ -437,8 +452,7 @@ void OGroupManager::InsertElement( const
 	m_pCompGroup->InsertComponent( xSet );
 
 	// Component in Gruppe aufnehmen
-	::rtl::OUString sGroupName;
-	xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+	::rtl::OUString sGroupName( GetGroupName( xSet ) );
 
 	OGroupArr::iterator aFind = m_aGroupArr.find(sGroupName);
 
@@ -476,6 +490,8 @@ void OGroupManager::InsertElement( const
 
 	// Bei Component als PropertyChangeListener anmelden
 	xSet->addPropertyChangeListener( PROPERTY_NAME, this );
+	if (hasProperty(PROPERTY_GROUP_NAME, xSet))
+		xSet->addPropertyChangeListener( PROPERTY_GROUP_NAME, this );
 
     // Tabindex muss nicht jeder unterstuetzen
 	if (hasProperty(PROPERTY_TABINDEX, xSet))
@@ -492,12 +508,26 @@ void OGroupManager::RemoveElement( const
 		return;
 
 	// Component aus Gruppe entfernen
-	::rtl::OUString		sGroupName;
-	xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+	::rtl::OUString		sGroupName( GetGroupName( xSet ) );
 
 	removeFromGroupMap(sGroupName,xSet);
 }
 
+::rtl::OUString OGroupManager::GetGroupName( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xComponent )
+{
+    if (!xComponent.is())
+        return ::rtl::OUString();
+    ::rtl::OUString sGroupName;
+    if (hasProperty( PROPERTY_GROUP_NAME, xComponent )) {
+        xComponent->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
+        if (sGroupName.getLength() == 0)
+            xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+    }
+    else
+        xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+    return sGroupName;
+}
+
 //.........................................................................
 }	// namespace frm
 //.........................................................................
Index: forms/source/component/RadioButton.hxx
===================================================================
RCS file: /cvs/gsl/forms/source/component/RadioButton.hxx,v
retrieving revision 1.12
diff -u -p -r1.12 RadioButton.hxx
--- forms/source/component/RadioButton.hxx	11 Apr 2008 08:19:23 -0000	1.12
+++ forms/source/component/RadioButton.hxx	6 Jun 2008 20:44:00 -0000
@@ -87,6 +87,8 @@ private:
             our mutex is aquired exactly once
     */
     void    setNewAggregateState( const ::com::sun::star::uno::Any& _rValue );
+
+    void setControlSource();
 };
 
 //==================================================================
Index: forms/source/component/RadioButton.cxx
===================================================================
RCS file: /cvs/gsl/forms/source/component/RadioButton.cxx,v
retrieving revision 1.22
diff -u -p -r1.22 RadioButton.cxx
--- forms/source/component/RadioButton.cxx	11 Apr 2008 08:19:08 -0000	1.22
+++ forms/source/component/RadioButton.cxx	6 Jun 2008 20:18:51 -0000
@@ -31,6 +31,7 @@
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_forms.hxx"
 #include "RadioButton.hxx"
+#include "GroupManager.hxx"
 #include "property.hxx"
 #ifndef _FRM_PROPERTY_HRC_
 #include "property.hrc"
@@ -122,6 +123,7 @@ ORadioButtonModel::ORadioButtonModel(con
 	m_nClassId = FormComponentType::RADIOBUTTON;
 	m_aLabelServiceName = FRM_SUN_COMPONENT_GROUPBOX;
 	initValueProperty( PROPERTY_STATE, PROPERTY_ID_STATE );
+	startAggregatePropertyListening( PROPERTY_GROUP_NAME );
 }
 
 //------------------------------------------------------------------
@@ -169,7 +171,11 @@ StringSequence SAL_CALL	ORadioButtonMode
 void ORadioButtonModel::SetSiblingPropsTo(const ::rtl::OUString& rPropName, const Any& rValue)
 {
 	// mein Name
-	::rtl::OUString sMyName(m_aName);
+    ::rtl::OUString sMyGroup;
+    if (hasProperty(PROPERTY_GROUP_NAME, this))
+        this->getPropertyValue(PROPERTY_GROUP_NAME) >>= sMyGroup;
+    if (sMyGroup.getLength() == 0)
+        sMyGroup = m_aName;
 
 	// meine Siblings durchiterieren
 	Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
@@ -177,8 +183,9 @@ void ORadioButtonModel::SetSiblingPropsT
 	{
 		Reference<XPropertySet> xMyProps;
 		query_interface(static_cast<XWeak*>(this), xMyProps);
-		::rtl::OUString	sCurrentName;
-		for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
+		::rtl::OUString	sCurrentGroup;
+		sal_Int32 nNumSiblings = xIndexAccess->getCount();
+		for (sal_Int32 i=0; i<nNumSiblings; ++i)
 		{
 			Reference<XPropertySet>	xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
 			if (!xSiblingProperties.is())
@@ -195,8 +202,8 @@ void ORadioButtonModel::SetSiblingPropsT
 				continue;
 
 			// das 'zur selben Gruppe gehoeren' wird am Namen festgemacht
-			xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sCurrentName;
-			if (sCurrentName == sMyName)
+			sCurrentGroup = OGroupManager::GetGroupName( xSiblingProperties );
+			if (sCurrentGroup == sMyGroup)
 				xSiblingProperties->setPropertyValue(rPropName, rValue);
 		}
 	}
@@ -223,40 +230,7 @@ void ORadioButtonModel::setFastPropertyV
 	// die andere Richtung : wenn sich mein Name aendert ...
 	if (nHandle == PROPERTY_ID_NAME)
 	{
-		// ... muss ich testen, ob ich Siblings mit dem selben Namen habe, damit ich deren ControlSource uebernehmen kann
-		Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
-		if (xIndexAccess.is())
-		{
-			::rtl::OUString			sName;
-			::rtl::OUString			sControlSource;
-
-			Reference<XPropertySet> xMyProps;
-			query_interface(static_cast<XWeak*>(this), xMyProps);
-			for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
-			{
-				Reference<XPropertySet>	xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
-				if (!xSiblingProperties.is())
-					continue;
-
-				if (xMyProps == xSiblingProperties)
-					// nur wenn ich nicht mich selber gefunden habe
-					continue;
-
-				sal_Int16 nType = 0;
-				xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
-				if (nType != FormComponentType::RADIOBUTTON)
-					// nur Radio-Buttons
-					continue;
-
-				xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sName;
-				// Control, das zur gleichen Gruppe gehoert ?
-				if (rValue == sName)
-				{
-					setPropertyValue(PROPERTY_CONTROLSOURCE, xSiblingProperties->getPropertyValue(PROPERTY_CONTROLSOURCE));
-					break;
-				}
-			}
-		}
+        setControlSource();
 	}
 
 	if (nHandle == PROPERTY_ID_DEFAULTCHECKED)
@@ -274,6 +248,52 @@ void ORadioButtonModel::setFastPropertyV
 	}
 }
 
+void ORadioButtonModel::setControlSource()
+{
+    Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
+    if (xIndexAccess.is())
+    {
+        ::rtl::OUString sName, sGroupName;
+
+        if (hasProperty(PROPERTY_GROUP_NAME, this))
+            this->getPropertyValue(PROPERTY_GROUP_NAME) >>= sGroupName;
+        this->getPropertyValue(PROPERTY_NAME) >>= sName;
+
+        Reference<XPropertySet> xMyProps;
+        query_interface(static_cast<XWeak*>(this), xMyProps);
+        for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
+        {
+            Reference<XPropertySet>	xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
+            if (!xSiblingProperties.is())
+                continue;
+
+            if (xMyProps == xSiblingProperties)
+                // nur wenn ich nicht mich selber gefunden habe
+                continue;
+
+            sal_Int16 nType = 0;
+            xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
+            if (nType != FormComponentType::RADIOBUTTON)
+                // nur Radio-Buttons
+                continue;
+
+            ::rtl::OUString sSiblingName, sSiblingGroupName;
+            if (hasProperty(PROPERTY_GROUP_NAME, xSiblingProperties))
+                xSiblingProperties->getPropertyValue(PROPERTY_GROUP_NAME) >>= sSiblingGroupName;
+            xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sSiblingName;
+
+            if ((sGroupName.getLength() == 0 && sSiblingGroupName.getLength() == 0 &&   // (no group name
+                 sName == sSiblingName) ||                                              //  names match) or
+                (sGroupName.getLength() != 0 && sSiblingGroupName.getLength() != 0 &&   // (have group name
+                 sGroupName == sSiblingGroupName))                                      //  they match)
+            {
+                setPropertyValue(PROPERTY_CONTROLSOURCE, xSiblingProperties->getPropertyValue(PROPERTY_CONTROLSOURCE));
+                break;
+            }
+        }
+    }
+}
+
 //------------------------------------------------------------------------------
 void ORadioButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
 {
@@ -363,6 +383,13 @@ void ORadioButtonModel::_propertyChanged
 			SetSiblingPropsTo( PROPERTY_STATE, aZero );
 		}
 	}
+    else if ( _rEvent.PropertyName.equals( PROPERTY_GROUP_NAME ) )
+    {
+        setControlSource();
+        // Can't call OReferenceValueComponent::_propertyChanged(), as it
+        // doesn't know what to do with the GroupName property.
+        return;
+    }
 
     OReferenceValueComponent::_propertyChanged( _rEvent );
 }
Index: forms/source/inc/frm_strings.hxx
===================================================================
RCS file: /cvs/gsl/forms/source/inc/frm_strings.hxx,v
retrieving revision 1.17
diff -u -p -r1.17 frm_strings.hxx
--- forms/source/inc/frm_strings.hxx	11 Apr 2008 08:34:01 -0000	1.17
+++ forms/source/inc/frm_strings.hxx	6 Jun 2008 20:18:54 -0000
@@ -100,6 +100,7 @@ namespace frm
     FORMS_CONSTASCII_STRING( PROPERTY_TABINDEX,                 "TabIndex" );
     FORMS_CONSTASCII_STRING( PROPERTY_TAG,                      "Tag" );
     FORMS_CONSTASCII_STRING( PROPERTY_NAME,                     "Name" );
+    FORMS_CONSTASCII_STRING( PROPERTY_GROUP_NAME,               "GroupName" );
     FORMS_CONSTASCII_STRING( PROPERTY_CLASSID,                  "ClassId" );
     FORMS_CONSTASCII_STRING( PROPERTY_FETCHSIZE,                "FetchSize" );
     FORMS_CONSTASCII_STRING( PROPERTY_VALUE,                    "Value" );
Index: forms/source/inc/property.hrc
===================================================================
RCS file: /cvs/gsl/forms/source/inc/property.hrc,v
retrieving revision 1.21
diff -u -p -r1.21 property.hrc
--- forms/source/inc/property.hrc	11 Apr 2008 08:35:13 -0000	1.21
+++ forms/source/inc/property.hrc	6 Jun 2008 20:18:56 -0000
@@ -60,7 +60,7 @@ namespace frm
 #define PROPERTY_ID_ALLOWEDITS          (PROPERTY_ID_START + 16)
 #define PROPERTY_ID_ALLOWDELETIONS      (PROPERTY_ID_START + 17)
 #define PROPERTY_ID_NATIVE_LOOK         (PROPERTY_ID_START + 18)
-    // free
+#define PROPERTY_ID_GROUP_NAME          (PROPERTY_ID_START + 19)
     // free
     // free
     // free
Index: xmloff/source/forms/formattributes.hxx
===================================================================
RCS file: /cvs/xml/xmloff/source/forms/formattributes.hxx,v
retrieving revision 1.14
diff -u -p -r1.14 formattributes.hxx
--- xmloff/source/forms/formattributes.hxx	10 Apr 2008 22:03:59 -0000	1.14
+++ xmloff/source/forms/formattributes.hxx	6 Jun 2008 20:18:57 -0000
@@ -124,6 +125,7 @@ namespace xmloff
 	#define SCA_MAX_VALUE				0x00000002
 	#define SCA_MIN_VALUE				0x00000004
 	#define SCA_VALIDATION				0x00000008
+    #define SCA_GROUP_NAME              0x00000010
 	#define SCA_MULTI_LINE				0x00000020
 	#define SCA_AUTOMATIC_COMPLETION	0x00000080
 	#define SCA_MULTIPLE				0x00000100
Index: xmloff/source/forms/formattributes.cxx
===================================================================
RCS file: /cvs/xml/xmloff/source/forms/formattributes.cxx,v
retrieving revision 1.21
diff -u -p -r1.21 formattributes.cxx
--- xmloff/source/forms/formattributes.cxx	10 Apr 2008 22:03:42 -0000	1.21
+++ xmloff/source/forms/formattributes.cxx	6 Jun 2008 20:18:58 -0000
@@ -193,6 +194,7 @@ namespace xmloff
 			case SCA_MAX_VALUE:				return "max-value";
 			case SCA_MIN_VALUE:				return "min-value";
 			case SCA_VALIDATION:			return "validation";
+            case SCA_GROUP_NAME:            return "group-name";
 			case SCA_MULTI_LINE:			return "multi-line";
 			case SCA_AUTOMATIC_COMPLETION:	return "auto-complete";
 			case SCA_MULTIPLE: 				return "multiple";
Index: xmloff/source/forms/strings.hxx
===================================================================
RCS file: /cvs/xml/xmloff/source/forms/strings.hxx,v
retrieving revision 1.18
diff -u -p -r1.18 strings.hxx
--- xmloff/source/forms/strings.hxx	10 Apr 2008 22:12:05 -0000	1.18
+++ xmloff/source/forms/strings.hxx	6 Jun 2008 20:18:59 -0000
@@ -204,6 +205,7 @@ namespace xmloff
     XMLFORM_CONSTASCII_STRING( PROPERTY_VISUAL_EFFECT,      "VisualEffect");
     XMLFORM_CONSTASCII_STRING( PROPERTY_IMAGE_POSITION,     "ImagePosition");
     XMLFORM_CONSTASCII_STRING( PROPERTY_IMAGE_ALIGN,        "ImageAlign");
+    XMLFORM_CONSTASCII_STRING( PROPERTY_GROUP_NAME,         "GroupName");
 
     XMLFORM_CONSTASCII_STRING( PROPERTY_BOUND_CELL,		    "BoundCell");
     XMLFORM_CONSTASCII_STRING( PROPERTY_LIST_CELL_RANGE,    "CellRange");
Index: xmloff/source/forms/elementexport.cxx
===================================================================
RCS file: /cvs/xml/xmloff/source/forms/elementexport.cxx,v
retrieving revision 1.48
diff -u -p -r1.48 elementexport.cxx
--- xmloff/source/forms/elementexport.cxx	10 Apr 2008 22:00:18 -0000	1.48
+++ xmloff/source/forms/elementexport.cxx	6 Jun 2008 20:19:00 -0000
@@ -1110,6 +1110,39 @@ namespace xmloff
 		}
 
 		// ----------------------------------
+		// the string properties
+		{
+			static sal_Int32 nStringPropertyAttributeIds[] =
+			{	// attribute flags
+				SCA_GROUP_NAME
+			};
+			static const ::rtl::OUString* pStringPropertyNames[] =
+			{	// property names
+				&PROPERTY_GROUP_NAME
+			};
+
+			sal_Int32 nIdCount = sizeof( nStringPropertyAttributeIds ) / sizeof( nStringPropertyAttributeIds[0] );
+		#if OSL_DEBUG_LEVEL > 0
+			sal_Int32 nNameCount = sizeof( pStringPropertyNames ) / sizeof( pStringPropertyNames[0] );
+			OSL_ENSURE( ( nIdCount == nNameCount ),
+				"OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
+		#endif
+			for ( i = 0; i < nIdCount; ++i )
+				if ( nStringPropertyAttributeIds[i] & m_nIncludeSpecial )
+				{
+					exportStringPropertyAttribute(
+						OAttributeMetaData::getSpecialAttributeNamespace( nStringPropertyAttributeIds[i] ),
+						OAttributeMetaData::getSpecialAttributeName( nStringPropertyAttributeIds[i] ),
+						*( pStringPropertyNames[i] )
+					);
+			#if OSL_DEBUG_LEVEL > 0
+				//  reset the bit for later checking
+				m_nIncludeSpecial = m_nIncludeSpecial & ~nStringPropertyAttributeIds[i];
+			#endif
+				}
+		}
+
+		// ----------------------------------
 		if ((SCA_MIN_VALUE | SCA_MAX_VALUE) & m_nIncludeSpecial)
 		{
 			// need to export the min value and the max value as attributes
@@ -1569,6 +1602,8 @@ namespace xmloff
 				}
                 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_IMAGE_POSITION ) )
                     m_nIncludeSpecial |= SCA_IMAGE_POSITION;
+                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_GROUP_NAME ) )
+                    m_nIncludeSpecial |= SCA_GROUP_NAME;
 				m_nIncludeDatabase = DA_DATA_FIELD;
 				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE;
 				break;
Index: svx/source/msfilter/msocximex.cxx
===================================================================
RCS file: /cvs/graphics/svx/source/msfilter/msocximex.cxx,v
retrieving revision 1.37
diff -u -p -r1.37 msocximex.cxx
--- svx/source/msfilter/msocximex.cxx	11 Apr 2008 02:06:31 -0000	1.37
+++ svx/source/msfilter/msocximex.cxx	6 Jun 2008 20:19:02 -0000
@@ -1701,6 +1701,12 @@ sal_Bool OCX_OptionButton::Import(com::s
     aTmp <<= ::com::sun::star::style::VerticalAlignment_MIDDLE;
     rPropSet->setPropertyValue( WW8_ASCII2STR("VerticalAlign"), aTmp );
 
+    if ( pGroupName )
+    {
+        aTmp <<= lclCreateOUString( pGroupName, nGroupNameLen );
+        rPropSet->setPropertyValue( WW8_ASCII2STR("GroupName"), aTmp);
+    }
+
 	aFontData.Import(rPropSet);
 	return sal_True;
 }
diff --git toolkit/inc/toolkit/helper/property.hxx toolkit/inc/toolkit/helper/property.hxx
index f257f5c..3577148 100644
--- toolkit/inc/toolkit/helper/property.hxx
+++ toolkit/inc/toolkit/helper/property.hxx
@@ -192,6 +192,7 @@ namespace rtl {
 #define BASEPROPERTY_UNIT                           135  // ::awt::FieldUnit
 #define BASEPROPERTY_CUSTOMUNITTEXT                 136  // ::rtl::OUString
 #define BASEPROPERTY_ENABLEVISIBLE                  137  // sal_Bool
+#define BASEPROPERTY_GROUPNAME                      138  // ::rtl::OUString
 
 // Keine gebundenen Properties, werden immer aus der Property BASEPROPERTY_FONTDESCRIPTOR entnommen.
 #define BASEPROPERTY_FONTDESCRIPTORPART_START			1000
Index: toolkit/source/helper/property.cxx
===================================================================
RCS file: /cvs/gsl/toolkit/source/helper/property.cxx,v
retrieving revision 1.42
diff -u -p -r1.42 property.cxx
--- toolkit/source/helper/property.cxx	11 Apr 2008 09:36:59 -0000	1.42
+++ toolkit/source/helper/property.cxx	6 Jun 2008 20:19:03 -0000
@@ -179,6 +179,7 @@ ImplPropertyInfo* ImplGetPropertyInfos( 
             DECL_PROP_3     ( "FormatsSupplier",        FORMATSSUPPLIER,    Reference< ::com::sun::star::util::XNumberFormatsSupplier >, BOUND, MAYBEVOID, TRANSIENT ),
 
             DECL_PROP_2     ( "Graphic",                GRAPHIC,            Reference< ::com::sun::star::graphic::XGraphic >, BOUND, TRANSIENT ),
+            DECL_PROP_2     ( "GroupName",              GROUPNAME,          ::rtl::OUString,    BOUND, MAYBEDEFAULT ),
             DECL_PROP_2     ( "HelpText",               HELPTEXT,           ::rtl::OUString,    BOUND, MAYBEDEFAULT ),
             DECL_PROP_2     ( "HelpURL",                HELPURL,            ::rtl::OUString,    BOUND, MAYBEDEFAULT ),
             DECL_PROP_2     ( "HideInactiveSelection",  HIDEINACTIVESELECTION, bool,            BOUND, MAYBEDEFAULT ),
Index: toolkit/source/awt/vclxwindows.cxx
===================================================================
RCS file: /cvs/gsl/toolkit/source/awt/vclxwindows.cxx,v
retrieving revision 1.68
diff -u -p -r1.68 vclxwindows.cxx
--- toolkit/source/awt/vclxwindows.cxx	11 Apr 2008 09:22:58 -0000	1.68
+++ toolkit/source/awt/vclxwindows.cxx	6 Jun 2008 20:19:05 -0000
@@ -1079,6 +1079,7 @@ void VCLXRadioButton::ImplGetPropertyIds
                      BASEPROPERTY_BACKGROUNDCOLOR,
                      BASEPROPERTY_ALIGN,
                      BASEPROPERTY_VERTICALALIGN,
+                     BASEPROPERTY_GROUPNAME,
                      0);
     VCLXImageConsumer::ImplGetPropertyIds( rIds );
 }
Index: toolkit/inc/toolkit/controls/dialogcontrol.hxx
===================================================================
RCS file: /cvs/gsl/toolkit/inc/toolkit/controls/dialogcontrol.hxx,v
retrieving revision 1.9
diff -u -p -r1.9 dialogcontrol.hxx
--- toolkit/inc/toolkit/controls/dialogcontrol.hxx	11 Apr 2008 08:52:41 -0000	1.9
+++ toolkit/inc/toolkit/controls/dialogcontrol.hxx	6 Jun 2008 20:19:06 -0000
@@ -51,6 +51,7 @@
 #include <cppuhelper/propshlp.hxx>
 #include <cppuhelper/basemutex.hxx>
 #include <list>
+#include <map>
 
 //	----------------------------------------------------
 //	class UnoControlDialogModel
@@ -182,6 +183,14 @@ protected:
 	void implNotifyTabModelChange( const ::rtl::OUString& _rAccessor );
 
 	void implUpdateGroupStructure();
+private:
+    void AddRadioButtonToGroup (
+            const ::com::sun::star::uno::Reference< XControlModel >& rControlModel,
+            const ::rtl::OUString& rPropertyName,
+            ::std::map< ::rtl::OUString, ModelGroup >& pNamedGroups,
+            ModelGroup*& rpCurrentGroup );
+    void AddRadioButtonGroup (
+            ::std::map< ::rtl::OUString, ModelGroup >& pNamedGroups );
 };
 
 //	----------------------------------------------------
Index: toolkit/source/controls/dialogcontrol.cxx
===================================================================
RCS file: /cvs/gsl/toolkit/source/controls/dialogcontrol.cxx,v
retrieving revision 1.27
diff -u -p -r1.27 dialogcontrol.cxx
--- toolkit/source/controls/dialogcontrol.cxx	11 Apr 2008 09:24:40 -0000	1.27
+++ toolkit/source/controls/dialogcontrol.cxx	6 Jun 2008 20:19:08 -0000
@@ -142,6 +142,18 @@ namespace
         return xGraphic;
     }
 
+    static ::rtl::OUString lcl_GetStringProperty( const ::rtl::OUString& sProperty, const Reference< XPropertySet >& xSet )
+    {
+        ::rtl::OUString sValue;
+        Reference< XPropertySetInfo > xPSI;
+        if (xSet.is() && (xPSI = xSet->getPropertySetInfo()).is() && 
+                xPSI->hasPropertyByName( sProperty ) )
+        {
+            xSet->getPropertyValue( sProperty ) >>= sValue;
+        }
+        return sValue;
+    }
+
 }
 
 // ----------------------------------------------------------------------------
@@ -897,6 +909,63 @@ void UnoControlDialogModel::implNotifyTa
 	}
 }
 
+// ----------------------------------------------------------------------------
+void UnoControlDialogModel::AddRadioButtonGroup ( 
+        ::std::map< ::rtl::OUString, ModelGroup >& rNamedGroups )
+{
+    if ( rNamedGroups.size() == 0 )
+        return;
+
+    size_t nGroups = maGroups.size();
+    maGroups.reserve( nGroups + rNamedGroups.size() );
+    ::std::map< ::rtl::OUString, ModelGroup >::const_iterator i = rNamedGroups.begin(), e = rNamedGroups.end();
+    for( ; i != e; ++i)
+    {
+            maGroups.push_back( i->second );
+    }
+
+    rNamedGroups.clear();
+}
+
+void UnoControlDialogModel::AddRadioButtonToGroup ( 
+        const Reference< XControlModel >& rControlModel,
+        const ::rtl::OUString& rPropertyName,
+        ::std::map< ::rtl::OUString, ModelGroup >& rNamedGroups,
+        ModelGroup*& rpCurrentGroup )
+{
+    Reference< XPropertySet > xCurProps( rControlModel, UNO_QUERY );
+    ::rtl::OUString sGroup = lcl_GetStringProperty( rPropertyName, xCurProps );
+    const sal_Int32 nControlModelStep = lcl_getDialogStep( rControlModel );
+
+    if ( sGroup.getLength() == 0 )
+    {
+        // Create a new group if:
+        if ( maGroups.size() == 0 ||                // no groups
+                rpCurrentGroup == NULL ||           // previous group was closed
+                (nControlModelStep != 0 &&          // control step matches current group
+                 maGroups.back().size() > 0 &&      //  (group 0 == display everywhere)
+                 nControlModelStep != lcl_getDialogStep( maGroups.back().back() ) ) )
+        {
+            size_t nGroups = maGroups.size();
+            maGroups.resize( nGroups + 1 );
+        }
+        rpCurrentGroup = &maGroups.back();
+    }
+    else
+    {
+        // Different steps get different sets of named groups
+        if ( rNamedGroups.size() > 0 &&
+                rNamedGroups.begin()->second.size() > 0 )
+        {
+            const sal_Int32 nPrevStep = lcl_getDialogStep( rNamedGroups.begin()->second.front() );
+            if ( nControlModelStep != nPrevStep )
+                AddRadioButtonGroup( rNamedGroups );
+        }
+
+        rpCurrentGroup = &rNamedGroups[ sGroup ];
+    }
+    rpCurrentGroup->push_back( rControlModel );
+}
 
 // ----------------------------------------------------------------------------
 void UnoControlDialogModel::implUpdateGroupStructure()
@@ -921,10 +990,13 @@ void UnoControlDialogModel::implUpdateGr
 
 	GroupingMachineState eState = eLookingForGroup;		// the current state of our machine
 	Reference< XServiceInfo > xModelSI;					// for checking for a radion button
-	AllGroups::iterator aCurrentGroup = maGroups.end();	// the group which we're currently building
-	sal_Int32	nCurrentGroupStep = -1;					// the step which all controls of the current group belong to
+	ModelGroup* aCurrentGroup = NULL;                   // the group which we're currently building
 	sal_Bool	bIsRadioButton;							// is it a radio button?
 
+    const ::rtl::OUString GROUP_NAME( RTL_CONSTASCII_USTRINGPARAM( "GroupName" ) );
+
+    ::std::map< ::rtl::OUString, ModelGroup > aNamedGroups;
+
 #if OSL_DEBUG_LEVEL > 1
 	::std::vector< ::rtl::OUString > aCurrentGroupLabels;
 #endif
@@ -945,14 +1017,8 @@ void UnoControlDialogModel::implUpdateGr
 				// the current model is a radio button
 				// -> we found the beginning of a new group
 				// create the place for this group
-				size_t nGroups = maGroups.size();
-				maGroups.resize( nGroups + 1 );
-				aCurrentGroup = maGroups.begin() + nGroups;
-				// and add the (only, til now) member
-				aCurrentGroup->push_back( *pControlModels );
+                AddRadioButtonToGroup( *pControlModels, GROUP_NAME, aNamedGroups, aCurrentGroup );
 
-				// get the step which all controls of this group now have to belong to
-				nCurrentGroupStep = lcl_getDialogStep( *pControlModels );
 				// new state: looking for further members
 				eState = eExpandingGroup;
 
@@ -970,7 +1036,7 @@ void UnoControlDialogModel::implUpdateGr
 			{
 				if ( !bIsRadioButton )
 				{	// no radio button -> the group is done
-					aCurrentGroup = maGroups.end();
+					aCurrentGroup = NULL;
 					eState = eLookingForGroup;
 #if OSL_DEBUG_LEVEL > 1
 					aCurrentGroupLabels.clear();
@@ -978,48 +1044,9 @@ void UnoControlDialogModel::implUpdateGr
 					continue;
 				}
 
-				// it is a radio button - is it on the proper page?
-				const sal_Int32 nThisModelStep = lcl_getDialogStep( *pControlModels );
-				if	(	( nThisModelStep == nCurrentGroupStep )	// the current button is on the same dialog page
-					||	( 0 == nThisModelStep )					// the current button appears on all pages
-					)
-				{
-					// -> it belongs to the same group
-					aCurrentGroup->push_back( *pControlModels );
-					// state still is eExpandingGroup - we're looking for further elements
-					eState = eExpandingGroup;
+                AddRadioButtonToGroup( *pControlModels, GROUP_NAME, aNamedGroups, aCurrentGroup );
 
 #if OSL_DEBUG_LEVEL > 1
-					Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
-					::rtl::OUString sLabel;
-					if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
-						xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
-					aCurrentGroupLabels.push_back( sLabel );
-#endif
-					continue;
-				}
-
-				// it's a radio button, but on a different page
-				// -> we open a new group for it
-
-				// close the old group
-				aCurrentGroup = maGroups.end();
-#if OSL_DEBUG_LEVEL > 1
-				aCurrentGroupLabels.clear();
-#endif
-
-				// open a new group
-				size_t nGroups = maGroups.size();
-				maGroups.resize( nGroups + 1 );
-				aCurrentGroup = maGroups.begin() + nGroups;
-				// and add the (only, til now) member
-				aCurrentGroup->push_back( *pControlModels );
-
-				nCurrentGroupStep = nThisModelStep;
-
-				// state is the same: we still are looking for further elements of the current group
-				eState = eExpandingGroup;
-#if OSL_DEBUG_LEVEL > 1
 				Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
 				::rtl::OUString sLabel;
 				if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
@@ -1031,6 +1058,7 @@ void UnoControlDialogModel::implUpdateGr
 		}
 	}
 
+    AddRadioButtonGroup( aNamedGroups );
 	mbGroupsUpToDate = sal_True;
 }
 
diff --git toolkit/source/controls/unocontrolmodel.cxx toolkit/source/controls/unocontrolmodel.cxx
index 25573a4..8768094 100644
--- toolkit/source/controls/unocontrolmodel.cxx
+++ toolkit/source/controls/unocontrolmodel.cxx
@@ -341,6 +341,7 @@ void UnoControlModel::ImplPropertyChanged( sal_uInt16 )
             case BASEPROPERTY_VISIBLE:
             case BASEPROPERTY_DECORATION:           aDefault <<= (sal_Bool) sal_True; break;
 
+            case BASEPROPERTY_GROUPNAME:
             case BASEPROPERTY_HELPTEXT:
             case BASEPROPERTY_HELPURL:
 	        case BASEPROPERTY_IMAGEURL:

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to