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]

Reply via email to