Value of a ListBox, FMC paradigm for Form elements (controls)
Lionel Elie Mamane
lionel at mamane.lu
Sat Apr 20 14:34:10 PDT 2013
On Thu, Apr 18, 2013 at 08:12:43AM +0200, Lionel Elie Mamane wrote:
> Context: (Data)Forms and their elements (controls).
> PROBLEM 2: Frame-Controller-Model paradigm as applied to Form elements
> ======================================================================
> Frame elements seem to have a b0rken implementation of the
> Frame-Controller-Model paradigm.
I now understand the system, more or less. Actually, they implement a
*different* paradigm, the "Model / View" paradigm, described at
http://wiki.openoffice.org/wiki/Documentation/DevGuide/Forms/Models_and_Views_for_Form_Controls
But the code (and some of the documentation) confusingly calls the
View only "Control".
> It has a getModel() that returns a frm::OListBoxModel. That in itself
> makes sense, *but*:
> 1) frm::OListBoxModel has no method/API to get back the corresponding
> frm::OListBoxControl
The model does not know its views, *but* the upper level document (the
SwXTextView) has an API that takes a model and returns the
corresponding view (control); see
http://wiki.openoffice.org/wiki/Documentation/DevGuide/Forms/Form_Layer_Views#Locating_Controls
So, well, it is workable after all. The link was not where I was
looking for it (in an interface of the model), but there is a path. So
let's say nothing to fix there.
The "funny" thing is that the same property in the view and in the
model has different values (index within the list vs display value),
but that sort of makes sense...
> When I bind a macro to an event of a ListBox, Event.Source is a
> frm::OListBoxControl (see forms/source/component/ListBox.hxx).
Actually, it depends what event. The pattern seems that data-related
events have the Model as source, and interaction-related events have
the view (control) as source. Which makes sense.
> PROBLEM 1: value of a ListBox
> =============================
> Currently, the "CurrentValue" pseudo-property (getCurrentValue()
> method) of a ListBox returns the current *display* value, not the
> *storage* value. To me, this is a bug or (serious) misdesign.
> I have a patch ready to change it, but... incompatible behaviour
> change... Basically, my question to you is: what should I do? Just
> change it, or introduce a new getCurrentBoundValue() to disambiguate,
> and leave getCurrentValue() alone?
> More generally, the *storage* values are *not* exposed at all by the
> UNO API. IMO this needs to change.
I was wrong... The property ValueItemList contains the storage
values... but in some cases (which cover my test cases...) it was not
populated (which explains why I did not find it...). I'm fixing that
bug.
Which makes it even *more* weird that getCurrentValue is not an item
of ValueItemList, but of "StringItemList" (the property that contains
the display values).
So, we discussed the "just correct it or leave getCurrentValue alone"
question during the ESC call. Some more data, some more issues and
what I plan to do.
I've now read
http://wiki.openoffice.org/wiki/Documentation/DevGuide/Forms/Validation
getCurrentValue is part of interface
com.sun.star.form.validation.XValidatableFormComponent
(that is, it was introduced for the use of validators, callback
procedures that say "accept this input from the user" or "reject
it").
It is described as "retrieves the current value of the component" and
"Again, this is a convenience method". I understand "convenience
method" as:
It is equivalent to retrieving the 'content property' of the
control.
This is exemplified by this text in the documentation:
For example, for a ::com::sun::star::form::component::FormattedField,
calling this method is equivalent to retrieving the
::com::sun::star::awt::UnoControlFormattedFieldModel::EffectiveValue.
(http://wiki.openoffice.org/wiki/Documentation/DevGuide/Forms/Control_Models_as_Bound_Components
introduces the notion of content property.)
For a ListBox, the 'content property', which the code calls "Value
Property" (!) is currently SelectedItems, which is the array of
*indexes* of the selected items in the list, and not the values in the
bound column.
Up to now, it is coherent. Where it is not coherent anymore, is that
the *same* content property is supposed to be the one that is written
to the database:
A data-aware control model bound to a data column uses its content
property to exchange data with this column. As soon as the column
value changes, the model forwards the new value to its content
property, and notifies its listeners. One of these listeners is the
control that updates its display
So, the natural idea would be to change the content property to one
that contains the *storage* values corresponding to what is currently
selected in the list. On the one hand, this would make everything
coherent and improve our similarity to / compatibility with Microsoft
Office, *but*:
On the other hand, it introduces a difference with all other controls,
and implementation-wise it is much easier / faster to have the "value"
or "content" of the ListBox (as in the property that code can *set* to
change the selection in the listbox) be indices in the list(s), and
make the lookup in the storage value list at the time that the storage
value is exported to the database (or otherwise queried): faster
because no need to search in the list, and easier because it does not
raise questions what like to do with values that appear multiple times
in the storage value list, ...
So I'm tempted to just leave it as it is... And add a "SelectedValues"
property for easy access to the selected storage values, but not make
it the "content property" of the listbox.
I'll consider the "content property" an internal implementation detail
(not part of the interface), but support setting/reading the
"SelectedValues" directly *also*. In this scenario, I have to make up
my opinion on what a validator should get... indices or storage
values... (Validators are used at only one place in the codebae.)
Again, my first gut feeling is "storage value".
On another note, an "External Value Supplier"
http://wiki.openoffice.org/wiki/Documentation/DevGuide/Forms/External_Value_Suppliers
currently gets display values, which is inconsistent with Database
field (that the External Value supplier is supposed to
extend...). Gonna fix this and change to storage values.
Well, writing this summary has helped me organise my thoughts :) I'll
sleep on it and hopefully I can finish up the implementation
tomorrow.
One last question: where can I edit the help to document a new feature
I'm introducing (namely, the option that the storage value is the
index in the list)? I grepped for a string that appears in the right
help page, but no result. In particular, I did not find it in the
"helpcontent2" directory. Also, do we have our fork of the
OpenOffice.org Developer's Guide?
--
Lionel
More information about the LibreOffice
mailing list