Any widget that displays a primary block of text should install the XmQTaccessTextual trait. On the other hand, if the text in your widget is playing a supporting role, then you should not install the XmQTaccessTextual trait. For example, if the only text in your widget is a pixmap caption, then you would not install this trait on the widget. Furthermore, if the widget displays multiple blocks of text (such as the XmList widget does), then such a widget would not install this trait.
Table 9-1 suggests that this trait is extensively used inside the standard
widget set.
Table 19. XmQTaccessTextual Access and Use in the Motif Toolkit
Widget | Installs | Accesses | Usage Notes |
XmComboBox | No | Yes | Calls the getValue and setValue trait methods |
XmLabel | Yes | No | Provides all three trait methods |
XmLabelGadget | Yes | No | Provides all three trait methods |
XmNotebook | No | Yes | Does not call a particular trait method; just examines its children to see if they have this trait installed |
XmSelectionBox | No | Yes | Calls the getValue and setValue trait methods |
XmSpinBox | No | Yes | Calls the setValue trait methods |
XmText | Yes | No | Provides all three trait methods |
XmTextField | Yes | No | Provides all three trait methods |
The XmQTaccessTextual trait provides three methods. These trait methods are called by another widget, typically by the parent of a widget holding the XmQTaccessTextual widget. For example, the parent calls the setValue trait method to set the primary text block of its child. The parent calls the getValue trait method to find out what primary text block its child is displaying. Finally, the parent can call the preferredFormat trait method to find out what text format the child prefers to store its text in.
Different textual widgets hold their text in different formats. Currently, Motif supports three different text formats:
The ExmString widget installs the XmQTaccessTextual trait and defines all three trait methods. The following subsections examine these trait methods.
The getValue trait method returns a copy of the text currently held by the XmQTaccessTextual widget. Typically, this value will be held inside a resource. For example, the ExmString widget holds its text value inside the ExmNcompoundString resource. Therefore, the current text value of the ExmString widget is easily obtained through the following call:
XtVaGetValues(w, ExmNcompoundString, &value, NULL);
The current text value is now stored in compound string format inside the value variable.
The widget that calls getValue must specify the string format in which it expects to receive the returned value. Therefore, most of the code inside the getValue trait method converts the text from its native format (in this case, XmFORMAT_XmSTRING) to one of the two other supported formats. Converting from XmString format to multibyte or wide-character string format requires a call to XmStringUnparse.
(See the code for ExmString for complete details.)
The setValue trait method changes the text and/or text format of a widget's primary text block. The setValue trait method takes three arguments:
If the new text has the same format as the widget's native format, no conversions are necessary. For example, the native format of the ExmString widget is XmFORMAT_XmSTRING. Therefore, if the caller passes the new text in the XmFORMAT_XmSTRING format, the setValue trait method merely needs to assign the text to the ExmNcompoundString resource. On the other hand, if the caller passes the new text in XmFORMAT_MBYTE (multibyte text) format, setValue must convert the new text from XmString format to XmFORMAT_MBYTE format.
Following is the complete setValue trait method of the ExmString widget:
StringSetValue( Widget w, XtPointer string, int format) { Arg args[1]; XmString temp; Boolean freetemp; int length; char *str; wchar_t *str2; /* The caller will pass a new value for ExmNcompoundString. This new value will be passed in the "string" argument. However, there is no guarantee that the input "string" will be passed in XmString format. If the input "string" is passed in WCS or MULTIBYTE format, then we must convert the "string" into XmString format. Once the "string" is in XmString format, we can use it as the new value of ExmNcompoundString. */ switch (format) { case XmFORMAT_XmSTRING: temp = (XmString) string; freetemp = False; break; case XmFORMAT_WCS: str2 = (wchar_t *) string; /* How long is str2? */ length = 0; while (str2[length] != 0) length++; /* malloc enough space to hold str */ str = (char*) XtMalloc(MB_CUR_MAX * (length+1)); wcstombs(str, str2, MB_CUR_MAX * (length+1)); XtFree((char*)string); string = str; /* Falling through to XmFORMAT_MBYTE */ case XmFORMAT_MBYTE: temp = XmStringCreateLocalized(string); freetemp = True; break; default: XmeWarning((Widget)w, UNSUPPORTED_FORMAT); return; } /* Assign the new string to ExmNcompoundString. */ XtSetArg(args[0], ExmNcompoundString, temp); XtSetValues(w, args, 1); if (freetemp) XmStringFree(temp); }
Every textual widget has some native format in which it
stores the text itself. The preferredFormat trait method returns
the name of this native format. For example, Table 9-2 shows the native format
of the XmQTaccessTextual widgets in the standard Motif widget set.
Table 20. Native Format of XmQTaccessTextual Widgets
Widget | Native Format |
XmLabel | XmFORMAT_XmSTRING |
XmLabelGadget | XmFORMAT_XmSTRING |
XmText | XmFORMAT_MBYTE |
XmTextField | XmFORMAT_MBYTE |
The native format of ExmString is XmFORMAT_XmSTRING. Therefore, the entire preferredFormat trait method is simply as follows:
static int StringPreferredFormat( Widget w) { return(XmFORMAT_XmSTRING); }
If the calling widget knows the textual widget's native format prior to calling getValue or setValue, then needless conversions can be avoided.