5.6 Data Functions
Functions that are declared as data functions in the dialog description must be declared in C as follows:
DM_Boolean DML_default DML_CALLBACK <function name> (DM_DataArgs *args);
if the function is defined as
{ export | reexport } function datafunc <function name> ();
in the dialog script
or as
DM_Boolean DML_c DML_CALLBACK <function name> (DM_DataArgs *args);
if the function is defined as
{ export | reexport } function c datafunc <function name> ();
in the dialog script.
The parameter of this function is predefined by the ISA Dialog Manager and cannot be changed. It represents a Data Model (Model component) that provides the presentation objects (View component) with data values or stores and manages them.
This function is called when a synchronization between View and Model components is required. This may either happen automatically, according to the control options in the .dataoptions[]attribute of the involved components. The call can also be triggered by explicit invocation of the :collect(), :propagate(), :apply() and :represent() methods. For each Model attribute there is a separate call.
dialog D
function datafunc FuncData();
function void Reverse(integer Idx);
window Wi
{
.title "Datafunc demo";
.width 200; .height 300;
edittext Et
{
.datamodel FuncData;
.dataget .text;
.dataset .text;
.xauto 0;
.xright 80;
}
pushbutton PbAdd
{
.text "Add";
.xauto -1;
.width 80;
on select
{
this.window:apply();
}
}
listbox Lb
{
.xauto 0; .yauto 0;
.ytop 30; .ybottom 30;
.datamodel FuncData;
.dataget .content;
on select
{
PbReverse.sensitive := true;
}
}
pushbutton PbReverse
{
.xauto 0; .yauto -1;
.text "Reverse element";
.sensitive false;
on select
{
Reverse(Lb.activeitem);
}
}
on close { exit(); }
}
#ifdef VMS
# define EXITOK 1
# define EXITERROR 0
#else
# define EXITOK 0
# define EXITERROR 1
#endif
#include <IDMuser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "datafuncfm.h"
#define DIALOGFILE "~:datafunc.dlg"
static DM_ID data_id = (DM_ID)0;
static DM_Value data_vec;
static DM_String data_str;
void DML_default DM_CALLBACK FuncData __1((DM_DataArgs *, args))
{
if (!data_id)
data_id = args->object;
switch (args->task)
{
case MT_get:
switch(args->attribute)
{
case AT_text:
args->retval.type = DT_string;
args->retval.value.string = data_str;
break;
case AT_content:
if (args->index.type == DT_void)
{
args->retval = data_vec;
}
else if (args->index.type == DT_integer)
{
DM_ValueGet(&data_vec, &args->index, &args->retval, 0);
}
break;
default:
break;
}
break;
case MT_set:
switch(args->attribute)
{
case AT_text:
if (args->data.type == DT_string)
{
if (DM_ValueChange(&data_vec, NULL, &args->data, DMF_AppendValue))
DM_DataChanged(data_id, AT_content, NULL, DMF_Verbose);
}
break;
default:
break;
}
break;
default:
break;
}
}
void DML_default DM_ENTRY Reverse __1((DM_Integer, Idx))
{
DM_Value index, data;
char *cp, ch;
size_t len, i;
DM_ValueInit(&data, DT_void, NULL, 0);
index.type = DT_integer;
index.value.integer = Idx;
if (DM_ValueGet(&data_vec, &index, &data, 0) && data.type == DT_string)
{
if (DM_StringChange(&data_str, data.value.string, 0))
DM_DataChanged(data_id, AT_text, NULL, DMF_Verbose);
/* reverse the string */
cp = data.value.string;
if (cp)
{
len = strlen(cp);
if (len>2)
{
len--;
for (i=0; len>0 && i<len/2; i++)
{
ch = cp[i];
cp[i] = cp[len-i];
cp[len-i] = ch;
}
}
}
if (DM_ValueChange(&data_vec, &index, &data, 0) && data_id)
DM_DataChanged(data_id, AT_content, &index, DMF_Verbose);
}
}
int DML_c AppMain __2((int, argc), (char **,argv))
{
DM_ID dialogID;
DM_Value data;
/* initialize the Dialog Manager */
if (!DM_Initialize (&argc, argv, 0))
{
DM_TraceMessage("Could not initialize.", 0);
return (1);
}
/* load the dialog file */
switch(argc)
{
case 1:
dialogID = DM_LoadDialog (DIALOGFILE,0);
break;
case 2:
dialogID = DM_LoadDialog (argv[1],0);
break;
default:
DM_TraceMessage("Too many arguments.", 0);
return(EXITERROR);
break;
}
if (!dialogID)
{
DM_TraceMessage("Could not load dialog.", 0);
return(EXITERROR);
}
data.type = DT_type;
data.value.type = DT_string;
DM_ValueInit(&data_vec, DT_vector, &data, DMF_StaticValue);
data.type = DT_string;
data.value.string = "^ Enter a string";
DM_ValueChange(&data_vec, NULL, &data, DMF_AppendValue);
data.value.string = "and press 'Add'";
DM_ValueChange(&data_vec, NULL, &data, DMF_AppendValue);
DM_StringInit(&data_str, DMF_StaticValue);
DM_StringChange(&data_str, "Change me!", 0);
/* install table of application functions */
if (!BindFunctions_D (dialogID, dialogID, 0))
DM_TraceMessage ("There are some functions missing.", 0);
/* start the dialog and enter event loop */
if (DM_StartDialog (dialogID, 0))
DM_EventLoop (0);
else
return (EXITERROR);
return (EXITOK);
}
See also
Function DM_DataChanged