Hello Jonathan, > One oddity I encountered is that > ORadioButtonModel::setFastPropertyValue_NoBroadcast() must call > OReferenceValueComponent::setFastPropertyValue_NoBroadcast() or things > break (I forget the specifics of how things broke, but it didn't behave > properly),
Actually, the current version of setFast... does not *set* (i.e. remember) the new property values - that's why you need to (continue to) call the base class. All which this method currently (before your changes) does is to keep certain properties in sync for all radio buttons of a group: - If the LabelControl or the DataField values change, this new value is propagated to all siblings, i.e. all radio buttons in the same group. This is done in SetSiblingPropsTo - which implies you also need to adjust this method, since the definition of "sibling" changes with your implementation - If the name of the radio button changes, then this means it is moved to another group. In this case, setFast... look for other controls in this new group, and adopts their DataField property value (strictly, it would also have to adopt their LabelControl property) - Finally, if the DefaultState property of the radio button just changed to 1, then the DefaultState of all group siblings is reset to 0 (again using SetSiblingPropsTo), since there can be only one radio button with default state "checked" in a given group. > BUT if I call the base class version for > PROPERTY_ID_GROUP_NAME I'd get a debug message > OControlModel::setFastPropertyValue_NoBroadcast() saying "unknown > handle". which says that you asked the OControlModel implementation to remember a value for a property which this class does not know / cannot handle. > I'm not sure what the correct thing to do for this, so for now I'm only > calling OReferenceValueComponent::setFastPropertyValue_NoBroadcast() if > nHandle isn't PROPERTY_ID_GROUP_NAME. Which is the correct solution. > I have it partially working, which is why I'm replying, because it's > starting to confuse me. I feared that. Actually, the GroupManager (and frieds) implementation(s) confuse me, too, every time I have to look at it (which isn't too often, fortunately). I once did some slight re-factoring some years ago (basically STLizing it), but besides this, the code is in the very same shape it was 12 years or so ago - an nobody is there anymore to ask about it :-\ > First, an aside: it looks like OGroupManager::removeFromGroupMap() has a > bug where if a _sGroupName group has only one element in it, the group > is NOT removed from m_aActiveGroupMap. This seems wrong; what's doubly > confusing is that the only time m_aActiveGroupMap.erase() is executed is > if there's at least one element within the group, _after_ we removed the > radio button. I can't see how groups are ever removed from this map. Perhaps let's talk about the definition of "groups" in this context, first (That might be only for myself - please keep in mind all I write here is from examining the source code here and now - I am not the original author of that, I rarely touched it, so I just need to learn myself :). A "group" is a set of controls where only the whole set, but not single controls, can be reached with the TAB key. That is, if you would have two buttons in a document which both have the same name, then you would not be able to TAB to the second button. In a first approximation, the group manager simply classifies all controls by their name, and puts controls into a same group if and only if they have the same name. One step further, the group manager has the concept of "active group" (which sounds like an unfortunate name to me). That is, only groups which contain more than one element are reported to the outside. I suppose this is an optimization, originally. I even suppose we could get rid of this "active group" thingie, and simply report all groups, even the one with one element only. However, I am absolutely unsure about this, so let's not do it right now :) The next approximation step: Groups of radio buttons are always considered active, even if there is only one element. The reason is the following scenario: Consider a document with 3 radio buttons *only*, all having different names, which results in 3 different and all-active groups. Without this, the VCL runtime would implicitly put the three radio buttons into one group, and you would not be able to select them independently. (Note the integration tests I referred you too also check this scenario.) I'd appreciate if you could tell whether this is also your understanding of the code. Having said this, it looks to me as if your change to removeFromGroupMap in fact corrects it behavior so that now, also radio button groups are "deactivated" - previously, they never were, as you correctly stated. (side note: I would prefer you either removing the old comments around the changed code, which do not apply anymore, or (better :) write new comments explaining what's going on. As you probably noticed, the whole group manager code is not-completely-easy to read and understand, and having no or even misleading comments doesn't make this any better.) > Back to my problem: if each radio button has a different name, then the > new GroupName property controls grouping. If the GroupName property is > empty, then the Name property controls grouping. So far so good. > > Where it goes south is the "migration" scenario: assume you have 4 radio > buttons, each with the same name. If you try to split them into groups > using GroupName _without_ changing the Name, then the Name property > seems to be the controlling factor, e.g. > > RadioButton 1; Name=OptionButton; GroupName=A > RadioButton 2; Name=OptionButton; GroupName=A > RadioButton 3; Name=OptionButton; GroupName=B > RadioButton 4; Name=OptionButton; GroupName=B > > What confuses me is that OGroup::GetControlModels() behaves "properly" > -- it either returns the GroupName=A controls or the GroupName=B > controls (except for the AllComponentGroup group, which returns > everything, but we'll ignore that). > > So as far as I can tell, I'm doing the right thing here, with GroupName > overriding Name to control which groups the controls are placed in. > > Yet I can't have two buttons selected (one from A, one from B), but only > one. > > Doubly odd is that if I change the name of one of the controls, e.g. > change RadioButton 3 to have Name=OptionButton3, then RadioButton 4 is > part of *both* groups -- I can have RadioButtons 1 and 3 active > concurrently, but selecting RadioButton 4 will result in RadioButton 4 > being the only button active. > > I'm getting the feeling that OGroupManager isn't the only controlling > factor, and that something somewhere isn't following the grouping > information set by OGroupManager. > > Or I'm missing something in my OGroupManager updates. > > Any suggestions on where to look? Strange ideed. I applied your patches, but need some time to dive into the code myself. Since I am offline for nearly the complete rest of the week, I just try to throw a few pointers at you, for the moment: toolkit/source/controls/stdtabcontroller.cxx, method activateTabOrder: This is the point where the model's grouping data es examined, translated into controls (as opposed to control models), and forwarded to the Control Container. The interesting implementation here is VCLXContainer::setGroup in toolkit/source/awt/vclxcontainer.cxx. Here, the grouped controls are translated into setting the WB_GROUP win bit at the respective VCL window. As a general idea, when you look onto all involved VCL widows (4, in your example), then all controls in one group need to be consecutive, with respect to their Z-Order. So, in your AA/BB example, I would expect the following Z-Order/win bits: OptionButton/A/WB_GROUP OptionButton/A OptionButton/B/WB_GROUP OptionButton/B Try debugging the activateTabOrder/setGroup methods, and see where they fail to create this situation. I'll try to have a look into this, too, but this won't be before next week, sorry. > Attached is my current patch...which is (sadly) full of debug spew. Know OSL_TRACE? It is a macro which, when built with debug info, effectively expands to printf, and to no-op in release builds. So, you can have debug output which you don't need to remove finally. Also note that dbg_dump from sal does what your CHART_POINTER macro accomplishes. Some more things I noticed, which you should address at some stage (not necessarily now): - m_sGroupName must also be initialized in the "cloning" ctor of ORadioButtonModel - don't rely on the GroupName property being present, check for existence in every place where you use it - ::propertyChange: when the Name changes, but the GroupName is not empty, then nothing should be done at all ... shouldn't it? - persistence seems to be a problem, in the scenario you describe above (4 buttons all with the same name, but different group names), the group names are improperly written to the file. Sounds a little bit like the code in xmloff/source/forms somewhere uses the (ambiguous) getByName to retrieve the to-be-written radio buttons. Other than that - let me say that this looks promising, I am really looking forward to get this feature (grouping by name is an awkward historical burden, it'd be great to be relieve from it). Thanks & Ciao Frank -- - Frank Schönheit, Software Engineer [EMAIL PROTECTED] - - Sun Microsystems http://www.sun.com/staroffice - - OpenOffice.org Base http://dba.openoffice.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]