Reacting to a user write

Example module: helloedit.

Two settings control what happens when a client writes a value to an element:

  • directedit (per element, default false): if false, an SV send (writing a single element) on this element is refused — only an SA send (grouped write of the whole property) can modify it.
  • autoupdate (per element and per property, default true at the property level, false at the element level): if the element or its property has autoupdate:true, the framework applies the written value to the datastore itself, before the module is even notified.
"hello": {
  "permission": 2,
  "devcat": "", "group": "",
  "autoupdate": false,
  "e": {
    "autoname": {
      "type": "string", "directedit": true, "autoupdate": true
    },
    "manualname": {
      "type": "string", "directedit": true, "autoupdate": false
    }
  }
}

With this declaration, writing to autoname is reflected immediately, with no code at all: the framework applies the value by itself.

autoupdate is set at two levels — it’s a logical OR

If the property itself doesn’t set autoupdate (or sets it to true), it stays at its default of true — and an element with autoupdate:false will still be auto-applied, because element.autoupdate() || property.autoupdate() is true as soon as either one is. For an element to truly escape automatic application, its property too must have autoupdate:false explicitly, as above.

Extracting a non-auto-applied value

For manualname (both element and property autoupdate:false), nothing is applied automatically: onExternalEvent() must itself extract the raw value written by the client, then apply it (possibly after transforming it):

void HelloEdit::onExternalEvent(OST::ExtEvent event)
{
    // autoname : rien à faire, déjà appliqué par le framework.

    if (event.ev == OST::ExtEvType::SV && event.prpkey == "hello" && event.eltkey == "manualname")
    {
        QJsonObject o = event.data["m"].toObject()[getModuleName()].toObject();
        QJsonObject e = o["p"].toObject()["hello"].toObject()["e"].toObject();
        QString written = e["manualname"].toVariant().toString();

        getEltString("hello", "manualname")->setValue(written.toUpper(), true);
    }
}

Modifying a value from the module’s own code (getEltXxx(...)->setValue(..., true)) never goes through the permission/directedit checks: those only apply to writes coming from the client. This is what makes it possible here to transform the value (uppercasing it) before actually applying it.

Accessor catalog

Two families, depending on whether you want the element itself (to call setValue(), disable()…) or just its value:

TypegetElt...()direct value
stringgetEltString()getString()
intgetEltInt()getInt()
floatgetEltFloat()getFloat()
boolgetEltBool()getBool()
dategetEltDate()getDate()
timegetEltTime()getTime()
lightgetEltLight()—
imagegetEltImg()—
videogetEltVideo()—
progressgetEltPrg()—

All of them take (property, element). The direct-value accessors (getString/getInt/getFloat/getBool/getDate/getTime) have a (property, element, row) overload to read a given row of a grid — see Grids.