For more information on actions and how you create them, see Chapter 9, "Accessing the Data-Typing Database," in this manual, and the following chapters in the CDE Advanced User's and System Administrator's Guide:
The advantages of using the action invocation API include:
Returning to invocation, suppose your application manages data files in several different formats (text and graphics) and needs to provide a way for the user to edit and display these files. To implement this feature without using actions, you would probably use one of the following mechanisms:
DtInitialize(*display,widget,*name,*tool_class)
DtAppInitialize(app_context,*display,widget,*name, tool_class)
if (DtInitialize(XtDisplay(shell), shell, argv[0],ApplicationClass)==False) {
/* DtInitialize() has already logged an appropriate error msg */
exit(-1);
}
DtDbLoad(void)
/* Notice changes to the database without needing to restart application */
DtDbReloadNotify(DbReloadCallbackProc, callback_proc, XTPointer, client_data);
For example, the action definition for the Calculator looks like this:ACTION action_name { ... }
The action name for the Calculator action is Dtcalc.ACTION Dtcalc { LABEL Calculator ICON Dtcalc ARG_COUNT 0 TYPE COMMAND WINDOW_TYPE NO_STDIO EXEC_STRING /usr/dt/bin/dtcalc DESCRIPTION The Calculator (Dtcalc) action runs the \ desktop Calculator application. }
When an executable file has a file name that matches an action name in the existing database, that file is an action file--a representation for the underlying action. The information about the icon and label for that file are stored in the database.
DtActionExists(*name)
DtActionIcon(char *action_name)
DtActionIcon() returns a character string containing the value of the icon image field. If the action definition does not contain an icon field, the function returns the value of the default action icon image, Dtactn.ACTION action_name
{ ICON icon_image_base_name ... }
You then need to determine the location of the icon, and the size you want to use. Icons can exist in four sizes and are available in bitmap or pixmap form. For example, you can find the base name of the icon file from the action definition for the Calculator. You then use the base name coupled with the information given in Table 8-1 and knowledge of the location of all the icons to find the specific icon file you want.
The icon name for the calculator action is Dtcalc, but that is not the entire file name. Icon file names are based on the size of the icon. Table 8-1 shows the sizes and file-naming conventions for the desktop icons.
Table 8-1 Icon Sizes and File Names
For bitmaps, there is an additional file that is used as a mask, and its extension ends with _m.bm. Thus, there can be a total of three files for each size icon. Here are the icon files for the calculator:
Dtcalc.t.bm Dtcalc.t.pm Dtcalc.t_m.bm Dtcalc.m.bm Dtcalc.m.pm Dtcalc.m_m.bm Dtcalc.l.bm Dtcalc.l.pm Dtcalc.l_m.bm
DtActionIcon() returns only a base name; for the Calculator it is Dtcalc. You must choose the type (pixmap or bitmap) and size (tiny, small, medium, or large) and append the applicable extension to the base name. In addition, you must know where the file resides.
char *DtActionLabel(char *actionName)
This label is used in graphical components (such as File Manager and the Application Manager) to label the action's icon. If an action definition does not include a label_text field, the action_name is used.ACTION action_name { LABEL label_text ... }
The value of label_text string should be used by all interface components to identify the action to the end user.
The DtActionLabel() function returns the value of the label_text field in the action definition of the action named actionName. If the label_text field does not exist, the function returns the actionName.
DtActionInvokeID (widget, action, args, argCount, termOpts, execHost,
contexDir, useIndicator, statusUpdateCb, client_data)
/* * (c) Copyright 1993, 1994 Hewlett-Packard Company * (c) Copyright 1993, 1994 International Business Machines Corp. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. * (c) Copyright 1993, 1994 Novell, Inc. */
#include <Xm/XmAll.h> #include <Dt/Dt.h> #include <Dt/Action.h>
#define ApplicationClass "Dtaction"
static Widget shell; static XtAppContext appContext; static Widget actionText; static Widget fileText;
static void CreateWidgets(Widget); static void InvokeActionCb(Widget, XtPointer, XtPointer); static void InvokeAction(char*, char*); static void DbReloadProc(XtPointer);
void main(int argc, char **argv) { Arg args[20]; int n=0; int numArgs = 0;
shell = XtAppInitialize(&appContext , ApplicationClass, NULL, 0, &argc, argv, NULL, args, n);
CreateWidgets(shell);
if (DtInitialize(XtDisplay(shell), shell, argv[0], ApplicationClass)==False) { /* DtInitialize() has already logged an appropriate error msg */ exit(-1);
}
/* Load the filetype/action databases */ DtDbLoad();
/* Notice changes to the database without needing to restart application */ DtDbReloadNotify(DbReloadProc, NULL);
XtRealizeWidget(shell); XmProcessTraversal(actionText, XmTRAVERSE_CURRENT);
XtAppMainLoop(appContext);
}
static void CreateWidgets(Widget shell) { Widget messageBox, workArea, w; Arg args[20]; int n; XmString labelString;
labelString = XmStringCreateLocalized("Invoke");
n = 0; XtSetArg(args[n], XmNdialogType, XmDIALOG_TEMPLATE); n++; XtSetArg(args[n], XmNokLabelString, labelString); n++; messageBox = XmCreateMessageBox(shell, "messageBox", args, n); XtManageChild(messageBox); XmStringFree(labelString); XtAddCallback(messageBox, XmNokCallback, InvokeActionCb, NULL);
n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++; XtSetArg(args[n], XmNnumColumns, 2); n++; XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_END); n++; workArea = XmCreateWorkArea(messageBox, "workArea", args, n); XtManageChild(workArea);
labelString = XmStringCreateLocalized("Invoke Action:"); n = 0; XtSetArg(args[n], XmNlabelString, labelString); n++; w = XmCreateLabel(workArea, "actionLabel", args, n); XtManageChild(w); XmStringFree(labelString);
labelString = XmStringCreateLocalized("On File:"); n = 0; XtSetArg(args[n], XmNlabelString, labelString); n++; w = XmCreateLabel(workArea, "fileLabel", args, n); XtManageChild(w); XmStringFree(labelString);
n = 0; XtSetArg(args[n], XmNcolumns, 12); n++; actionText = XmCreateTextField(workArea, "actionText", args, n); XtManageChild(actionText);
n = 0; XtSetArg(args[n], XmNcolumns, 12); n++; fileText = XmCreateTextField(workArea, "fileText", args, n); XtManageChild(fileText);
}
static void DbReloadProc(XtPointer cd) {
/* Pick up any dynamic changes to the database files */ DtDbLoad();
}
static void InvokeActionCb(Widget w, XtPointer cd, XtPointer cb) { char *action; char *file;
action = XmTextFieldGetString(actionText);
if (action == NULL) return; if (strlen(action) == 0) { XtFree(action); return; }
file = XmTextFieldGetString(fileText);
InvokeAction(action, file);
XtFree(action); XtFree(file);
XmTextFieldSetString(actionText, ""); XmTextFieldSetString(fileText, "");
XmProcessTraversal(actionText, XmTRAVERSE_CURRENT);
}
static void InvokeAction(char *action, char *file) { DtActionArg *ap = NULL;
int nap = 0; DtActionInvocationID actionId;
/* If a file was specified, build the file argument list */
printf("%s(%s)\n",action,file); if (file != NULL && strlen(file) != 0) { ap = (DtActionArg*) XtCalloc(1, sizeof(DtActionArg)); ap[0].argClass = DtACTION_FILE; ap[0].u.file.name = file; nap = 1; }
/* Invoke the specified action */
actionId = DtActionInvoke(shell,action,ap,nap,NULL,NULL,NULL,True,NULL,NULL);
}