#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include "XmI.h"
#include "MessagesI.h"
#include <Xm/MultiListP.h>
#include <Xm/Ext18List.h>
#include <Xm/Ext18ListP.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/ScrollBar.h>
#include <Xm/TextF.h>
#include <Xm/VaSimpleP.h>
#include <Xm/ExtP.h>
/************************************************************
* TYPEDEFS AND DEFINES
*************************************************************/
#define BUG_FIX_1385 1
#define H_MARGIN 5
#define V_MARGIN 5
#define FIND_STRING _XmMMsgResource_0013
extern XmMultiListRowInfo \
*XmI18ListFindRow(Widget, String, int *, Boolean, Boolean);
extern int *XmI18ListGetSelectedRowArray(XmI18ListWidget, int *);
extern void XmI18ListMakeRowVisible(XmI18ListWidget, int);
extern void XmI18ListDeselectRow(XmI18ListWidget, int);
extern void XmI18ListSelectRow(XmI18ListWidget, int, Boolean);
extern void XmI18ListSelectAllItems(XmI18ListWidget, Boolean);
extern void XmI18ListDeselectItems(XmI18ListWidget, XmString, int);
extern void XmI18ListSelectItems(XmI18ListWidget, XmString, int, Boolean);
static Widget CreateTitle(Widget, XmString, ArgList, Cardinal);
static Widget CreateScrollbar(Widget, Boolean, ArgList, Cardinal);
static Widget CreateFindButton(Widget, ArgList, Cardinal);
static Widget CreateFindText(Widget, ArgList, Cardinal);
static Widget CreateFrame(Widget, ArgList, Cardinal);
static void ActivateTextSearch(Widget, XtPointer, XtPointer);
static void LayoutChildren(Widget), ChangeManaged(Widget);
static void PositionFindAndFindText(Widget);
static void ClassInitialize();
static void Initialize(Widget, Widget, ArgList, Cardinal *);
static void ClassPartInitialize(WidgetClass w_class);
static void Resize(Widget), Destroy(Widget w);
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
static void GetValuesHook(Widget, ArgList, Cardinal *);
static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *,
XtWidgetGeometry *);
static XtResource resources[] =
{
{
XmNwidth, XmCWidth, XmRHorizontalDimension,
sizeof(Dimension), XtOffsetOf(CoreRec, core.width),
XmRImmediate, (XtPointer) 0
},
{
XmNheight, XmCHeight, XmRVerticalDimension,
sizeof(Dimension), XtOffsetOf(CoreRec, core.height),
XmRImmediate, (XtPointer) 0
},
{
XmNtitle, XmCTitle, XmRXmString,
sizeof(XmString), XtOffsetOf(XmMultiListRec, ext_list.title),
XmRImmediate, (XtPointer) NULL
},
{
XmNtitleString, XmCTitleString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmMultiListRec, ext_list.title_string),
XmRImmediate, (XtPointer) NULL
},
{
XmNdoubleClickCallback, XmCCallback, XmRCallback,
sizeof(XtCallbackList), XtOffsetOf(XmMultiListRec, ext_list.double_click),
XmRImmediate, (XtPointer) NULL
},
{
"pri.vate", "Pri.vate", XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmMultiListRec, ext_list.check_set_select_callback),
XmRImmediate, (XtPointer) False
},
{
XmNselectCallback, XmCCallback, XmRCallback,
sizeof(XtCallbackList), XtOffsetOf(XmMultiListRec, ext_list.single_select),
XmRImmediate, (XtPointer) NULL
},
/* this is the old name for the above */
{
XmNsingleSelectionCallback, XmCCallback, XmRCallback,
sizeof(XtCallbackList), XtOffsetOf(XmMultiListRec, ext_list.single_select),
XmRImmediate, (XtPointer) NULL
},
{
XmNshowFind, XmCShowFind, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmMultiListRec, ext_list.show_find),
XmRImmediate, (XtPointer) True
},
{
XmNfindLabel, XmCFindLabel, XmRXmString,
sizeof(XmString), XtOffsetOf(XmMultiListRec, ext_list.find_label),
XmRImmediate, (XtPointer) NULL
},
{
XmNitemNotFoundCallback, XmCCallback, XmRCallback,
sizeof(XtCallbackList), XtOffsetOf(XmMultiListRec, ext_list.not_found),
XmRImmediate, (XtPointer) NULL
},
{
XmNitemFoundCallback, XmCCallback, XmRCallback,
sizeof(XtCallbackList), XtOffsetOf(XmMultiListRec, ext_list.item_found),
XmRImmediate, (XtPointer) NULL
},
{
XmNvisibleItemCount, XmCVisibleItemCount, XmRInt,
sizeof(int), XtOffsetOf(XmMultiListRec, ext_list.visible_rows),
XmRImmediate, (XtPointer) XmMultiList_DEFAULT_VISIBLE_COUNT
},
#ifndef BUG_FIX_1385
{
XmNnumColumns, XmCNumColumns, XmRShort,
sizeof(short), 0,
NULL, (XtPointer) NULL
},
{
XmNnumRows, XmCNumRows, XmRShort,
sizeof(short), 0,
NULL, (XtPointer) NULL
},
{
XmNselectedColumn, XmCSelectedColumn, XmRShort,
sizeof(short), 0,
NULL, (XtPointer) NULL
},
{
XmNcolumnTitles, XmCColumnTitles, XmRXmStringTable,
sizeof(XmString *), 0,
NULL, (XtPointer) NULL
},
{
XmNentryData, XmCEntryData, XmRPointer,
sizeof(XtPointer), 0,
NULL, (XtPointer) NULL
},
{
XmNentryBackground, XmCBackground, XtRPixel,
sizeof(Pixel), 0,
NULL, (XtPointer) NULL
},
{
XmNfirstColumnPixmaps, XmCFirstColumnPixmaps, XmRBoolean,
sizeof(Boolean), 0,
NULL, (XtPointer) NULL
},
{
XmNfontList, XmCFontList, XmRFontList,
sizeof(XmFontList), 0,
NULL, (XtPointer) NULL
},
{
XmNrenderTable, XmCRenderTable, XmRRenderTable,
sizeof(XmRenderTable), 0,
NULL, (XtPointer) NULL
},
{
XmNverticalScrollBar, XmCScrollBar, XmRWidget,
sizeof(Widget), 0,
NULL, (XtPointer) NULL
},
{
XmNhorizontalScrollBar, XmCScrollBar, XmRWidget,
sizeof(Widget), 0,
NULL, (XtPointer) NULL
},
{
XmNfirstRow, XmCFirstLocation, XmRShort,
sizeof(short), 0,
NULL, (XtPointer) NULL
},
{
XmNfirstColumn, XmCFirstLocation, XmRShort,
sizeof(short), 0,
NULL, (XtPointer) NULL
},
{
XmNsortFunctions, XmCFunction, XmRFunction,
sizeof(Xm18SortFunction **), 0,
NULL, (XtPointer) NULL
},
{
XmNselectionPolicy, XmCSelectionPolicy, XmRSelectionPolicy,
sizeof(unsigned char), 0,
NULL, (XtPointer) NULL
}
#endif
};
static XmSyntheticResource syn_resources[] =
{
{
XmNwidth,
sizeof (Dimension), XtOffsetOf(CoreRec, core.width),
XmeFromHorizontalPixels, XmeToHorizontalPixels
},
{
XmNheight,
sizeof (Dimension), XtOffsetOf(CoreRec, core.height),
XmeFromVerticalPixels, XmeToVerticalPixels
}
};
XmMultiListClassRec xmMultiListClassRec = {
{ /* core fields */
/* superclass */ (WidgetClass)&xmManagerClassRec,
/* class_name */ "XmMultiList",
/* widget_size */ sizeof(XmMultiListRec),
/* class_initialize */ ClassInitialize,
/* class_part_initialize */ ClassPartInitialize,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ NULL,
/* num_actions */ (Cardinal)0,
/* resources */ (XtResource*)resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ NULL,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ GetValuesHook,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ XtInheritTranslations,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator */ XtInheritDisplayAccelerator,
/* extension */ NULL
},
{ /* composite_class fields */
/* geometry_manager */ GeometryManager,
/* change_managed */ ChangeManaged,
/* insert_child */ XtInheritInsertChild,
/* delete_child */ XtInheritDeleteChild,
/* extension */ NULL,
},
{ /* constraint_class fields */
/* resource list */ NULL,
/* num resources */ 0,
/* constraint size */ 0,
/* destroy proc */ NULL,
/* init proc */ NULL,
/* set values proc */ NULL,
/* extension */ NULL,
},
{ /* manager_class fields */
/* default translations */ XtInheritTranslations,
/* syn_resources */ syn_resources,
/* num_syn_resources */ XtNumber(syn_resources),
/* syn_cont_resources */ NULL,
/* num_syn_cont_resources */ 0,
/* parent_process */ NULL,
/* extension */ NULL,
},
{ /* Extended List fields */
NULL /* extension */
}
};
WidgetClass xmMultiListWidgetClass = (WidgetClass)&xmMultiListClassRec;
/* Function Name: ClassInitialize
* Description: Initializes class-specific data (offsets)
* Arguments: none
* Returns: nothing
*/
static void
ClassInitialize()
{
/* do nothing */
}
/* Function Name: Initialize
* Description: Called to initialize information specific
* to this widget.
* Arguments: req - what was originally requested.
* set - what will be created (our superclassed have
* already mucked with this)
* args, num_args - The arguments passed to
* the creation call.
* Returns: none.
*/
/*ARGSUSED*/
static void Initialize(Widget req, Widget set,
ArgList args, Cardinal * num_args)
{
ArgList f_args;
Cardinal f_num_args;
XmMultiListWidget elist = (XmMultiListWidget) set;
/*
* Pass filtered setvalues requests down to all children.
*/
_XmFilterArgs(args, *num_args, xm_std_filter, &f_args, &f_num_args);
XmMultiList_last_search(elist) = NULL;
XmMultiList_ilist(elist) = NULL;
if (XmMultiList_title(elist) != NULL)
XmMultiList_title(elist) = XmStringCopy(XmMultiList_title(elist));
if (XmMultiList_title_string(elist) != NULL)
XmMultiList_title_string(elist) =
XmStringCopy(XmMultiList_title_string(elist));
if (XmMultiList_find_label(elist) != NULL)
XmMultiList_find_label(elist) = XmStringCopy(XmMultiList_find_label(elist));
else
XmMultiList_find_label(elist) =
XmStringGenerate(FIND_STRING, NULL, XmCHARSET_TEXT, NULL);
XmMultiList_title_wid(elist) = CreateTitle(set,
(XmMultiList_title_string(elist) ?
XmMultiList_title_string(elist) :
XmMultiList_title(elist)),
f_args, f_num_args);
XmMultiList_v_bar(elist) = CreateScrollbar(set, True, f_args, f_num_args);
XmMultiList_h_bar(elist) = CreateScrollbar(set, False, f_args, f_num_args);
/*
* Scrollbars must be created before the frame.
*/
XmMultiList_frame(elist) = CreateFrame(set, f_args, f_num_args);
XmMultiList_find(elist) = CreateFindButton(set, f_args, f_num_args);
XmMultiList_find_text(elist) = CreateFindText(set, f_args, f_num_args);
/* Compute our initial height & width if unset... */
if (XtHeight(req) == 0)
{
int title_height = 0;
if (XmMultiList_title(elist) || XmMultiList_title_string(elist))
title_height = XmMultiList_title_wid(elist)->core.height + 2 *
(XmMultiList_title_wid(elist)->core.border_width + V_MARGIN);
if (XmMultiList_show_find(elist))
XtHeight(set) = XmMultiList_h_bar(elist)->core.height +
XmMultiList_frame(elist)->core.height + title_height +
XmMultiList_find(elist)->core.height + 2 *
(V_MARGIN + elist->core.border_width +
XmMultiList_h_bar(elist)->core.border_width +
XmMultiList_frame(elist)->core.border_width +
XmMultiList_find(elist)->core.border_width);
else
XtHeight(set) = XmMultiList_title_wid(elist)->core.height +
XmMultiList_h_bar(elist)->core.height + title_height +
XmMultiList_frame(elist)->core.height + 2 *
(V_MARGIN + elist->core.border_width +
XmMultiList_h_bar(elist)->core.border_width +
XmMultiList_frame(elist)->core.border_width);
}
if (XtWidth(req) == 0)
{
XtWidth(set) = XmMultiList_ilist(elist)->core.width +
XmMultiList_v_bar(elist)->core.width + (5 * H_MARGIN) +
(2 * elist->core.border_width);
}
XtFree((XtPointer) f_args);
}
/*
* ClassPartInitialize sets up the fast subclassing for the widget.
*/
static void
ClassPartInitialize(WidgetClass w_class)
{
_XmFastSubclassInit (w_class, XmEXT18LIST_BIT);
}
/* Function Name: Destroy
* Description: Cleans up after the widget.
* Arguments: w - the widget.
* Returns: none.
*/
static void
Destroy(Widget w)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
XmStringFree(XmMultiList_title(elist));
XmStringFree(XmMultiList_title_string(elist));
XmStringFree(XmMultiList_find_label(elist));
XtRemoveAllCallbacks(w, XmNsingleSelectionCallback);
}
/* Function Name: Resize
* Description: Called when this widget has been resized.
* Arguments: w - Extended List Widget to realize.
* Returns: none.
*/
static void
Resize(Widget w)
{
LayoutChildren(w);
}
/* Function Name: ChangeManaged
* Description: when a management change has occurred.
* Arguments: w - the Ext List widget.
* Returns: none.
*/
/* ARGSUSED */
static void
ChangeManaged(Widget w)
{
LayoutChildren(w);
XmeNavigChangeManaged((Widget)w); /* for Motif navigation */
}
/* Function Name: GetValuesHook
* Description: Called to retrieve resource values from either
* the extended list or the interal list
* Arguments: w - the extended list widget.
* args, num_args - the argument list.
* Returns: none
*
* Added: 04/09/92 beth
*/
/*ARGSUSED*/
static void
GetValuesHook(Widget w, ArgList args, Cardinal *num_args)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
register Cardinal i, num=0, j = *num_args;
Arg i_args[15];
/*
* Get the correct args to pass to the I18List widget
*/
for (i=0; i < j; i++) {
if (streq(args[i].name, XmNnumColumns) ||
streq(args[i].name, XmNnumRows) ||
streq(args[i].name, XmNselectedColumn) ||
streq(args[i].name, XmNcolumnTitles) ||
streq(args[i].name, XmNentryData) ||
streq(args[i].name, XmNentryBackground) ||
streq(args[i].name, XmNfirstColumnPixmaps) ||
streq(args[i].name, XmNfontList) ||
streq(args[i].name, XmNrenderTable) ||
streq(args[i].name, XmNverticalScrollBar) ||
streq(args[i].name, XmNhorizontalScrollBar) ||
streq(args[i].name, XmNfirstRow) ||
streq(args[i].name, XmNfirstColumn) ||
streq(args[i].name, XmNsortFunctions) ||
streq(args[i].name, XmNselectionPolicy)) {
XtSetArg(i_args[num], args[i].name, args[i].value);
num++;
}
else if (streq(args[i].name, XmNtitle))
*(XmString*)args[i].value = XmStringCopy(XmMultiList_title(elist));
else if (streq(args[i].name, XmNtitleString))
*(XmString*)args[i].value = XmStringCopy(XmMultiList_title_string(elist));
else if (streq(args[i].name, XmNfindLabel))
*(XmString*)args[i].value = XmStringCopy(XmMultiList_find_label(elist));
}
/*
* Pass argument list through to the IList widget.
*/
if (num > 0)
XtGetValues(XmMultiList_ilist(elist), i_args, num);
}
/* Function Name: SetValues
* Description: Called when some widget data needs to be modified on-
* the-fly.
* Arguments: current - the current (old) widget values.
* request - before superclassed have changed things.
* set - what will acutally be the new values.
* args, num_args - the arguments in the list.
* Returns: none
*/
#define NUM_FIND_WIDGETS 2
/*ARGSUSED*/
static Boolean
SetValues(Widget current, Widget request, Widget set,
ArgList args, Cardinal * num_args)
{
XmMultiListWidget e_old = (XmMultiListWidget) current;
XmMultiListWidget e_set = (XmMultiListWidget) set;
ArgList f_args;
Cardinal f_num_args;
Boolean redisplay = False;
/*
* Pass the SetValues request through to all children.
*/
_XmFilterArgs(args, *num_args, xm_std_filter, &f_args, &f_num_args);
_XmSetValuesOnChildren((Widget) e_set, f_args, f_num_args);
XtFree((XtPointer) f_args);
if (XmMultiList_visible_rows(e_old) != XmMultiList_visible_rows(e_set))
{
if (XmMultiList_visible_rows(e_set) < 1)
XmMultiList_visible_rows(e_set) = 1; /* reset values less than 1 */
}
if (XmMultiList_show_find(e_old) != XmMultiList_show_find(e_set))
{
Widget find_widgets[NUM_FIND_WIDGETS];
find_widgets[0] = XmMultiList_find(e_set);
find_widgets[1] = XmMultiList_find_text(e_set);
if (XmMultiList_show_find(e_set))
XtManageChildren(find_widgets, NUM_FIND_WIDGETS);
else
XtUnmanageChildren(find_widgets, NUM_FIND_WIDGETS);
}
/*
* This check may return, so it must be last.
*/
if (XmMultiList_find_label(e_old) != XmMultiList_find_label(e_set))
{
Arg args[1];
redisplay = True;
XmStringFree(XmMultiList_find_label(e_old));
if (XmMultiList_find_label(e_set) != NULL)
XmMultiList_find_label(e_set) =
XmStringCopy(XmMultiList_find_label(e_set));
else
XmMultiList_find_label(e_set) =
XmStringCreateLocalized(FIND_STRING);
XtSetArg(args[0], XmNlabelString, XmMultiList_find_label(e_set));
XtSetValues(XmMultiList_find(e_set), args, 1);
}
/*
* MultiList supports both XmNtitle (for backwards compatibility) and
* XmNtitleString resources, so we must check for changes to both here
*/
if ((XmMultiList_title(e_old) != XmMultiList_title(e_set)) ||
(XmMultiList_title_string(e_old) != XmMultiList_title_string(e_set)))
{
XmString *title, old_title;
/* note: fails if both are set at the same time */
if (XmMultiList_title_string(e_old) != XmMultiList_title_string(e_set))
{
title = &XmMultiList_title_string(e_set);
old_title = XmMultiList_title_string(e_old);
}
else
{
title = &XmMultiList_title(e_set);
old_title = XmMultiList_title(e_old);
}
if ((*title == NULL) || (old_title == NULL))
{
LayoutChildren(set);
}
if (*title != NULL)
{
Arg zargs[2];
Cardinal znum_args = 0;
*title = XmStringCopy(*title);
XtSetArg(zargs[znum_args], XmNlabelString, *title); znum_args++;
XtSetValues(XmMultiList_title_wid(e_set), zargs, znum_args);
}
XmStringFree(old_title);
}
return(redisplay);
}
/* Function Name: GeometryManager
* Description: handles requests from children for a size change.
* Arguments: child - the child to change.
* request - the geometry that the child wants.
* return - what we will allow if this is an almost.
* Returns: status.
*
* This function will allow any width or height request on the label,
* find button, or frame. Any other widget will have its request
* disallowed.
*/
/*ARGSUSED*/
static XtGeometryResult
GeometryManager(Widget w, XtWidgetGeometry * request,
XtWidgetGeometry * result)
{
XmMultiListWidget elist = (XmMultiListWidget) XtParent(w);
XtGeometryResult answer = XtGeometryYes;
if (!(request->request_mode & (CWWidth | CWHeight | CWBorderWidth)))
return(XtGeometryNo);
/*
* Only these three widgets are ever allowed to initiate a resize
* request: Frame (parent of I18List), Title Widget, Find Button
*
* The scrollbars should be allowed to be thicker, and the text area
* should be able to ask to resize the window wider if necessary...
*/
if ((w != XmMultiList_title_wid(elist)) && (w != XmMultiList_find(elist)) &&
(w != XmMultiList_frame(elist)))
return(XtGeometryNo);
/*
* Handle the request from the I18List (frame & ilist) child to resize...
*/
if ((w == XmMultiList_frame(elist)) &&
((request->request_mode & CWWidth) ||
(request->request_mode & CWWidth)))
{
Widget parent = XtParent(XtParent(w));
XtWidgetGeometry ext_request, ext_reply;
ext_request.request_mode = 0;
if (request->request_mode & CWWidth)
{
ext_request.width = elist->core.width -
(w->core.width - request->width);
ext_request.request_mode |= CWWidth;
}
if (request->request_mode & CWHeight)
{
ext_request.height = elist->core.height -
(w->core.height - request->height);
ext_request.request_mode |= CWHeight;
}
answer = XtMakeGeometryRequest(parent, &ext_request, &ext_reply);
if (answer == XtGeometryYes)
{
if (request->request_mode & CWHeight)
elist->core.height = ext_request.height;
if (request->request_mode & CWWidth)
elist->core.width = ext_request.width;
}
else if (answer == XtGeometryAlmost)
{
if (request->request_mode & CWHeight)
elist->core.height = ext_reply.height;
if (request->request_mode & CWWidth)
elist->core.width = ext_reply.width;
}
}
if (!(request->request_mode & CWWidth))
request->width = w->core.width;
if (!(request->request_mode & CWHeight))
request->height = w->core.height;
if (!(request->request_mode & CWBorderWidth))
request->border_width = w->core.border_width;
*result = *request;
if (request->request_mode & (CWX | CWY | CWStackMode | CWSibling)) {
return(XtGeometryAlmost);
}
if (request->request_mode & XtCWQueryOnly)
return(XtGeometryYes);
/*
* A real allowed request, set the new dimensions
*/
w->core.width = result->width;
w->core.height = result->height;
LayoutChildren((Widget) elist);
return(answer);
}
/************************************************************
*
* Actions and Callbacks (More entry points into the widget code).
*
************************************************************/
/*ARGSUSED*/
static void
ActivateTextSearch(Widget w, XtPointer elist_ptr, XtPointer client)
{
XmMultiListWidget elist = (XmMultiListWidget) elist_ptr;
XmMultiListCallbackStruct find_info;
XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *) client;
Boolean reset = True;
XmMultiListRowInfo *match;
char * ptr;
wchar_t *wc_string;
if (!XmMultiList_show_find(elist))
return;
ptr = XmTextFieldGetString(XmMultiList_find_text(elist));
wc_string = XmTextFieldGetStringWcs(XmMultiList_find_text(elist));
if (XmMultiList_last_search(elist))
reset = !streq(ptr, XmMultiList_last_search(elist));
/* Last parameter tells search proc to highlight a matching row... */
match = XmI18ListFindRow(XmMultiList_ilist(elist), ptr,
&find_info.column, reset, True);
find_info.event = cbs->event;
find_info.string = ptr;
find_info.wc_string = wc_string;
find_info.row = match;
if (!match)
{
XBell(XtDisplay(w), 0);
find_info.reason = XmMULTILIST_NOT_FOUND;
XtCallCallbackList((Widget) elist, XmMultiList_not_found(elist),
(XtPointer) &find_info);
}
else
{
find_info.reason = XmMULTILIST_FOUND;
XtCallCallbackList((Widget) elist, XmMultiList_item_found(elist),
(XtPointer) &find_info);
}
XtFree((XtPointer)wc_string);
XtFree(XmMultiList_last_search(elist));
XmMultiList_last_search(elist) = ptr;
}
/************************************************************
* LOCAL CODE
*************************************************************/
/* Function Name: LayoutChildren
* Description: Lays out the "child" widgets in the Ext List widget.
* Arguments: w - the ext list widget.
* Returns: none.
*/
static void LayoutChildren(Widget w)
{
Arg args[1];
XmMultiListWidget elist = (XmMultiListWidget) w;
Widget t_wid = XmMultiList_title_wid(elist);
Widget frame = XmMultiList_frame(elist);
Widget find_text = XmMultiList_find_text(elist);
Widget vbar = XmMultiList_v_bar(elist);
Widget hbar = XmMultiList_h_bar(elist);
Dimension title_height, h_thick, v_thick, temp_val;
Position scroll_top, scroll_bottom, scroll_left, scroll_right;
Dimension height = elist->core.height;
Dimension width = elist->core.width;
/*
* Put Find and Find Text along the bottom
*/
PositionFindAndFindText(w);
if ((XmMultiList_title(elist) == NULL) &&
(XmMultiList_title_string(elist) == NULL))
{
scroll_top = V_MARGIN;
XtSetArg(args[0], XmNmappedWhenManaged, False);
XtSetValues(t_wid, args, (Cardinal) 1);
}
else
{
/*
* Put the title widget in the top left corner
*/
if (LayoutIsRtoLM(w))
_XmMoveWidget(t_wid, (Position)(width - H_MARGIN - XtWidth(t_wid)),
(Position) V_MARGIN);
else
_XmMoveWidget(t_wid, (Position) H_MARGIN, (Position) V_MARGIN);
XtSetArg(args[0], XmNmappedWhenManaged, True);
XtSetValues(t_wid, args, (Cardinal) 1);
title_height = t_wid->core.height + 2 * t_wid->core.border_width;
scroll_top = title_height + 2 * V_MARGIN;
}
v_thick = vbar->core.width + 2 * vbar->core.border_width;
h_thick = hbar->core.height + 2 * vbar->core.border_width;
if (XmMultiList_show_find(elist))
scroll_bottom = find_text->core.y - find_text->core.border_width - V_MARGIN;
else
scroll_bottom = height - V_MARGIN;
scroll_left = H_MARGIN;
scroll_right = width - H_MARGIN;
/*
* Place the frame.
*
* NOTE: I am reusing "width" and "height" for the size of the widget
* that I am about to configure.
*/
temp_val = v_thick + scroll_left + H_MARGIN;
if ((int)temp_val >= (int)scroll_right)
width = 1;
else
width = scroll_right - temp_val;
temp_val = h_thick + scroll_top + V_MARGIN;
if ( (Position) temp_val >= scroll_bottom )
height = 1;
else
height = scroll_bottom - temp_val;
_XmConfigureWidget(frame, scroll_left, scroll_top, width, height,
frame->core.border_width);
/*
* Place the scrollbars.
*/
_XmConfigureWidget(hbar, scroll_left, scroll_bottom - (Position) h_thick,
width, hbar->core.height, hbar->core.border_width);
temp_val = h_thick + scroll_top + V_MARGIN;
if ( (Position) temp_val >= scroll_bottom)
height = 1;
else
height = scroll_bottom - temp_val;
_XmConfigureWidget(vbar, scroll_right - v_thick, scroll_top,
vbar->core.width, height, vbar->core.border_width);
}
/* Function Name: PositionFindAndFindText
* Description: Positions the find and find text widgets.
* Arguments: parent - the parent of the find and find text- the EList
* Returns: none.
*/
static void PositionFindAndFindText(Widget w)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
Widget find = XmMultiList_find(elist);
Widget find_text = XmMultiList_find_text(elist);
Dimension find_height, max_child_height, find_width;
Dimension height = elist->core.height;
Dimension width = elist->core.width;
Position find_x, find_y;
if (!XmMultiList_show_find(elist))
return;
find_height = find->core.height + 2 * find->core.border_width;
find_width = find->core.width + 2 * find->core.border_width;
max_child_height = find_text->core.height + 2*find_text->core.border_width;
if (find_height > max_child_height)
max_child_height = find_height;
/*
* Put the Find widget in the lower left corner.
*/
if (LayoutIsRtoLM(w))
find_x = width - H_MARGIN - find_width;
else
find_x = H_MARGIN;
find_y = (Position) height -
(Position) ((int)(max_child_height + find_height)/2 + V_MARGIN);
_XmMoveWidget(find, find_x, find_y);
/*
* Put the Find Text widget next to the find widget,
* and resize it to fill the entire bottom width.
*/
{
Dimension text_width, temp_val;
Position x, y;
if (LayoutIsRtoLM(w))
x = H_MARGIN;
else
x = (Dimension) find_x + find_width + H_MARGIN;
y = find_y - (int)(max_child_height - find_height)/2;
temp_val = x + H_MARGIN;
if (temp_val >= width)
text_width = 1;
else
if (LayoutIsRtoLM(w))
text_width = width - find_width - temp_val;
else
text_width = width - temp_val;
_XmConfigureWidget(find_text, x, y, text_width, find_text->core.height,
find_text->core.border_width);
}
}
/************************************************************
*
* Functions that Create Widgets.
*
************************************************************/
/* Function Name: CreateTitle
* Description: Creates the Title widget.
* Arguments: parent - parent of the title widget.
* label - The label string.
* args, num_args - arguments used to create ext list.
* Returns: the title widget.
*/
static Widget
CreateTitle(Widget parent, XmString label, ArgList args, Cardinal num_args)
{
Widget w;
Arg *new_args, largs[5];
Cardinal num_largs;
num_largs = 0;
if (label != NULL) {
XtSetArg(largs[num_largs], XmNlabelString, label); num_largs++;
}
new_args = XtMergeArgLists(args, num_args, largs, num_largs);
w = XtCreateManagedWidget("title", xmLabelWidgetClass, parent,
new_args, num_largs + num_args);
XtFree((XtPointer) new_args);
return(w);
}
/* Function Name: CreateScrollbar
* Description: Creates a vert or horizontal scrollbar.
* Arguments: parent - parent of the scrollbar widget.
* is_vert - if true then create a vertical scrollbar,
* else, create a horiz one.
* args, num_args - arguments used to create ext list.
* Returns: none
*/
static Widget
CreateScrollbar(Widget parent, Boolean is_vert,ArgList args, Cardinal num_args)
{
Widget w;
Arg *new_args, largs[5];
Cardinal num_largs = 0;
String name;
if (is_vert) {
XtSetArg(largs[num_largs], XmNorientation, XmVERTICAL);
name = "vertBar";
}
else {
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL);
name = "horizBar";
}
num_largs++;
new_args = XtMergeArgLists(args, num_args, largs, num_largs);
w = XtCreateManagedWidget(name, xmScrollBarWidgetClass, parent,
new_args, num_args + num_largs);
XtFree((XtPointer) new_args);
return(w);
}
static Widget
CreateFindButton(Widget parent, ArgList args, Cardinal num_args)
{
Widget w;
Arg *new_args, largs[5];
Cardinal num_largs = 0;
XmMultiListWidget elist = (XmMultiListWidget) parent;
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, XmMultiList_find_label(elist));
num_largs++;
new_args = XtMergeArgLists(args, num_args, largs, num_largs);
w = XtCreateWidget("find", xmPushButtonWidgetClass, parent,
new_args, num_largs + num_args);
XtAddCallback(w, XmNactivateCallback, ActivateTextSearch, parent);
if (XmMultiList_show_find(elist))
XtManageChild(w);
XtFree((XtPointer) new_args);
return(w);
}
/* Function Name: CreateFindText
* Description: Creates the find text.
* Arguments: parent - parent of the find text widget.
* args, num_args - arguments used to create ext list.
* Returns: the find text widget.
*/
static Widget
CreateFindText(Widget parent, ArgList args, Cardinal num_args)
{
Widget w;
XmMultiListWidget elist = (XmMultiListWidget) parent;
w = XtCreateWidget("findText", xmTextFieldWidgetClass,
parent, args, num_args);
XtAddCallback(w, XmNactivateCallback, ActivateTextSearch, parent);
if (XmMultiList_show_find(elist))
XtManageChild(w);
return(w);
}
/* Function Name: CreateFrame
* Description: Creates the frame to contain the list region
* Arguments: parent - parent of the frame.
* args, num_args - arguments used to create ext list.
* Returns: none
*/
static Widget
CreateFrame(Widget parent, ArgList args, Cardinal num_args)
{
XmMultiListWidget elist = (XmMultiListWidget) parent;
Widget w;
Arg largs[2], * new_args;
Cardinal num_largs;
num_largs = 0;
XtSetArg(largs[num_largs], XmNshadowType, XmSHADOW_IN); num_largs++;
new_args = XtMergeArgLists(args, num_args, largs, num_largs);
w = XtCreateWidget("frame", xmFrameWidgetClass, parent,
new_args, num_args + num_largs);
XtFree((XtPointer) new_args);
num_largs = 0;
XtSetArg(largs[num_largs], XmNverticalScrollBar, XmMultiList_v_bar(elist));
num_largs++;
XtSetArg(largs[num_largs], XmNhorizontalScrollBar, XmMultiList_h_bar(elist));
num_largs++;
new_args = XtMergeArgLists(args, num_args, largs, num_largs);
XmMultiList_ilist(elist) = XtCreateManagedWidget("list", xmI18ListWidgetClass,
w, new_args,
num_args + num_largs);
XtFree((XtPointer) new_args);
/* PWC - Note...
*
* Required to force geometry of frame here (it won't inherit child's size)
*/
w->core.width = XmMultiList_ilist(elist)->core.width +
2 * w->core.border_width;
w->core.height = XmMultiList_ilist(elist)->core.height +
2 * w->core.border_width;
XtManageChild(w);
return(w);
}
/************************************************************
*
* Public Functions.
*
************************************************************/
/* -kat 1/18/91
* Function Name: XmMultiListGetSelectedRows
* Description: Takes an Extended List and returns a NULL terminated array
* of pointers to selected rows from the internal list
* Arguments: w - the extended list widget
* Returns: XmMultiListRowInfo **
*/
XmMultiListRowInfo **
XmMultiListGetSelectedRows(Widget w)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
XmMultiListRowInfo **ret_rows = NULL;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_rows = XmI18ListGetSelectedRows(XmMultiList_ilist(elist));
_XmAppUnlock(app);
return ret_rows;
}
/* Function Name: XmCreateMultiList
* Description: Creation Routine for UIL and ADA.
* Arguments: parent - the parent widget.
* name - the name of the widget.
* args, num_args - the number and list of args.
* Returns: The created widget.
*/
Widget
XmCreateMultiList(Widget parent, String name,
ArgList args, Cardinal num_args)
{
return (XtCreateWidget(name, xmMultiListWidgetClass,
parent, args, num_args));
}
Widget
XmVaCreateMultiList(
Widget parent,
char *name,
...)
{
register Widget w;
va_list var;
int count;
Va_start(var,name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmMultiListWidgetClass,
parent, False,
var, count);
va_end(var);
return w;
}
Widget
XmVaCreateManagedMultiList(
Widget parent,
char *name,
...)
{
Widget w = NULL;
va_list var;
int count;
Va_start(var, name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmMultiListWidgetClass,
parent, True,
var, count);
va_end(var);
return w;
}
/* Function Name: XmMultiListUnselectAllItems
* Description: Unselects all rows
* Arguments: w - the ilist widget.
* Returns: none
*/
void
XmMultiListUnselectAllItems(Widget w)
{
XmMultiListWidget elist = (XmMultiListWidget)w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
Xm18IListUnselectAllItems( XmMultiList_ilist(elist) );
_XmAppUnlock(app);
}
/* Function Name: XmMultiListUnselectItem
* Description: Unselects the row passed in
* Arguments: w - the ilist widget.
* row_info - ptr to the row passed in
* Returns: none
*/
void
XmMultiListUnselectItem(Widget w, XmMultiListRowInfo *row_info)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
Xm18IListUnselectItem( XmMultiList_ilist(elist), row_info );
_XmAppUnlock(app);
}
/* Function Name: XmMultiListToggleRow
* Description: Toggles the selection state of a specified row
* Arguments: w - the extended list widget
* Returns: none
*/
void
XmMultiListToggleRow(Widget w, short row)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListToggleRow(XmMultiList_ilist(elist), row);
_XmAppUnlock(app);
}
/* Function Name: XmMultiListSelectItems
* Description: Set selection state by matching column entries to XmString
* Arguments: w - the extended list widget
* item - XmString to use as selection key
* notify - if True, call XmNsingleSelectionCallback
* column - column number (0 - N) to match (or XmANY_COLUMN)
* Returns: none
*/
void XmMultiListSelectItems(Widget w, XmString item,
int column, Boolean notify)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListSelectItems((XmI18ListWidget)XmMultiList_ilist(elist),
item, column, notify);
_XmAppUnlock(app);
}
/* Function Name: XmMultiListDeselectItems
* Description: Set selection state by matching column entries to XmString
* Arguments: w - the extended list widget
* item - XmString to use as selection key
* column - column number (0 - N) to match (or XmANY_COLUMN)
* Returns: none
*/
void
XmMultiListDeselectItems(Widget w, XmString item, int column)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListDeselectItems((XmI18ListWidget)XmMultiList_ilist(elist),
item, column);
_XmAppUnlock(app);
}
/* Function Name: XmMultiListSelectAllItems
* Description: Set selection state of all rows
* Arguments: w - the extended list widget
* notify - if True, call XmNsingleSelectionCallback
* Returns: none
*/
void XmMultiListSelectAllItems(Widget w, Boolean notify)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListSelectAllItems((XmI18ListWidget)XmMultiList_ilist(elist), notify);
_XmAppUnlock(app);
}
/* Function Name: XmMultiListSelectRow
* Description: Set selection state on all rows
* Arguments: w - the extended list widget
* row - the row to select
* notify - if True, call XmNsingleSelectionCallback
* Returns: none
*/
void
XmMultiListSelectRow(Widget w, int row, Boolean notify)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListSelectRow((XmI18ListWidget)XmMultiList_ilist(elist), row, notify);
_XmAppUnlock(app);
}
/* Function Name: XmMultiListDeselectRow
* Description: Set selection state on all rows
* Arguments: w - the extended list widget
* row - the row to select
* Returns: none
*/
void
XmMultiListDeselectRow(Widget w, int row)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListDeselectRow((XmI18ListWidget)XmMultiList_ilist(elist), row);
_XmAppUnlock(app);
}
/* Function Name: XmMultiGetSelectedRowArray
* Description: Creates an array of integers which are selected row #'s
* Arguments: w - the extended list widget
* rows - pointer to the array of selected row #'s
* num_rows - pointer to the number of selected rows
* Returns: selected rows array
*/
int *
XmMultiListGetSelectedRowArray(Widget w, int *num_rows)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
int *ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmI18ListGetSelectedRowArray(
(XmI18ListWidget)XmMultiList_ilist(elist),
num_rows);
_XmAppUnlock(app);
return ret_val;
}
/* Function Name: XmMultiListMakeRowVisible
* Description: Shifts the visible extended list rows as desired
* Arguments: w - the extended list widget
* row - the row number wished to be made visible
* Returns: none
*/
void
XmMultiListMakeRowVisible(Widget w, int row)
{
XmMultiListWidget elist = (XmMultiListWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmI18ListMakeRowVisible((XmI18ListWidget)XmMultiList_ilist(elist), row);
_XmAppUnlock(app);
}
/* aliases of deprecated functiosn of XmExt18List */
extern WidgetClass xmExt18ListWidgetClass XM_ALIAS(xmMultiListWidgetClass);
XmMultiListRowInfo ** XmExt18ListGetSelectedRows(Widget) XM_ALIAS(XmMultiListGetSelectedRows);
Widget XmCreateExtended18List(Widget, String, ArgList, Cardinal) XM_ALIAS(XmCreateMultiList);
Widget XmCreateExt18List(Widget, String, ArgList, Cardinal) XM_ALIAS(XmCreateMultiList);
Widget XmVaCreateExt18List(Widget, char *, ...) XM_ALIAS(XmVaCreateMultiList);
Widget XmVaCreateManagedExt18List(Widget, char *, ...) XM_ALIAS(XmVaCreateManagedMultiList);
void XmExt18ListUnselectAllItems(Widget) XM_ALIAS(XmMultiListUnselectAllItems);
void XmExt18ListUnselectItem(Widget, XmMultiListRowInfo*) XM_ALIAS(XmMultiListUnselectItem);
void XmExt18ListToggleRow(Widget, short) XM_ALIAS(XmMultiListToggleRow);
void XmExt18ListSelectItems(Widget, XmString, int, Boolean) XM_ALIAS(XmMultiListSelectItems);
void XmExt18ListDeselectItems(Widget, XmString, int) XM_ALIAS(XmMultiListDeselectItems);
void XmExt18ListSelectAllItems(Widget, Boolean) XM_ALIAS(XmMultiListSelectAllItems);
void XmExt18ListSelectRow(Widget, int, Boolean) XM_ALIAS(XmMultiListSelectRow);
void XmExt18ListDeselectRow(Widget, int) XM_ALIAS(XmMultiListDeselectRow);
int *XmExt18ListGetSelectedRowArray(Widget, int *) XM_ALIAS(XmMultiListGetSelectedRowArray);
void XmExt18ListMakeRowVisible(Widget, int) XM_ALIAS(XmMultiListMakeRowVisible);
extern XmMultiListClassRec xmExt18ListClassRec XM_ALIAS(xmMultiListClassRec);