1 /* $XConsortium: VolSelect.c /main/5 1996/08/28 16:48:11 drk $ */
2 /************************************<+>*************************************
3 ****************************************************************************
9 ** Description: Displays and manages a dialog to select volumes
11 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
12 ** (c) Copyright 1993, 1994 International Business Machines Corp.
13 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
14 ** (c) Copyright 1993, 1994 Novell, Inc.
17 ****************************************************************************
18 ************************************<+>*************************************/
30 #include <X11/Intrinsic.h>
31 #include <X11/Xresource.h>
33 #include <Xm/MwmUtil.h> /* for MWM_ consts */
34 #include <Xm/Protocols.h>
36 #include <Xm/BulletinB.h>
37 #include <Xm/DialogS.h>
39 #include <Xm/LabelG.h>
42 #include <Xm/PushBG.h>
43 #include <Xm/SelectioB.h>
44 #include <Xm/SeparatoG.h>
52 #include "HelposI.h" /* DTGETMESSAGE */
53 #include "HelpDialogP.h"
54 #include "HelpAccessI.h"
55 #include "FileListUtilsI.h"
56 #include "FileUtilsI.h"
57 #include "HelpUtilI.h"
58 #include "VolSelectI.h"
63 /******** constants *********/
65 /* message catalog set for VolSelect.c */
67 /******** types *********/
68 typedef struct FLSelDlgRec
70 _DtHelpFileList fileList;
72 _DtHelpFileDlgChildren dlgWidgets;
75 /******** variables *********/
76 /* Setup for the Retrun Translation set for the text field */
77 /* static char defaultTranslations[] = "<Key>Return: Activate()"; */
79 /******** functions *********/
81 /*****************************************************************************
82 * Function: void DestroyDialogCB(Widget w,
83 * XtPointer clientData,
84 * XtPointer callData);
92 * Purpose: Free selection dialog memory
94 *****************************************************************************/
95 static void DestroyDialogCB(
100 FLSelDlgRec * selDlgData = (FLSelDlgRec *) clientData;
102 /* recall that the file list is not owned by the dialog */
103 XtFree((String)selDlgData);
107 /*****************************************************************************
108 * Function: void CloseDialogCB(Widget w,
109 * XtPointer clientData,
110 * XtPointer callData);
116 * Return Value: Void.
118 * Purpose: Closes the dialog
120 *****************************************************************************/
121 static void CloseDialogCB(
123 XtPointer clientData,
126 FLSelDlgRec * selDlgData = (FLSelDlgRec *) clientData;
128 /* unmanage the dialog; cause the close dialog callbacks to be called */
129 XtUnmanageChild(selDlgData->dlgWidgets.form);
134 /*****************************************************************************
135 * Function: void SetSelectionCB(Widget w,
136 * XtPointer clientData,
137 * XtPointer callData);
143 * Return Value: Void.
145 * Purpose: Set the selections in the file list
147 *****************************************************************************/
148 static void SetSelectionCB(
150 XtPointer clientData,
153 FLSelDlgRec * selDlgData = (FLSelDlgRec *) clientData;
154 int * selList = NULL;
158 Boolean freeMem = True;
159 _DtHelpFileEntry file;
163 /* get the list of selected list items */
164 XmListGetSelectedPos(selDlgData->dlgWidgets.list, &selList,&selCnt);
166 { /* no more items selected ==> deselected last item */
167 selCnt = 0; /* 0 < 1, which is minimum pos */
169 freeMem = False; /* not owned by me */
173 for ( file = selDlgData->fileList, pos = 1, setCnt = 0;
174 NULL != file && NULL != selList && setCnt <= selCnt;
175 file = _DtHelpFileListGetNext(NULL,file), pos++ )
177 if ( setCnt < selCnt /* fixes bug due to valid value at selList[selCnt] */
178 && pos == selList[setCnt] )
180 file->fileSelected = True;
185 file->fileSelected = False;
189 if (freeMem) XtFree((String)selList);
194 /*****************************************************************************
195 * Function: Widget CreateFileSelDialog()
198 * Return Value: dialog widget
200 * Purpose: Create and display an instance of a file sel dialog.
202 *****************************************************************************/
203 static Widget CreateFileSelDialog(
204 DtHelpDialogWidget hw,
208 _DtHelpFileList in_out_list,
209 _DtHelpFileDlgChildren * out_struct)
211 FLSelDlgRec * selDlgData; /* selection Dialog Data */
212 XmString labelString;
213 DtHelpListStruct *pHelpInfo;
217 #define FSWIDGETS selDlgData->dlgWidgets /* short hand */
219 /* create and init the dlg data */
220 selDlgData = (FLSelDlgRec *) XtCalloc(1,sizeof(FLSelDlgRec));
221 if (NULL == selDlgData) return NULL;
222 selDlgData->fileList = in_out_list;
223 selDlgData->modalDialog = modalDialog;
225 /* Create the shell and form used for the dialog. */
226 if (NULL == dlgTitle)
227 dlgTitle = (char *)_DTGETMESSAGE (FUSET, 1, "Help - Volume Selection");
229 dlgTitle = XtNewString(dlgTitle);
231 XtSetArg (args[n], XmNtitle, dlgTitle); n++;
232 XtSetArg (args[n], XmNallowShellResize, TRUE); n++;
233 FSWIDGETS.shell = (Widget) XmCreateDialogShell(parent, "fileSelectShell", args, n);
235 XtAddCallback(FSWIDGETS.shell, XmNdestroyCallback,
236 DestroyDialogCB,(XtPointer)selDlgData);
238 /* Set the useAsyncGeo on the shell */
240 XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
241 XtSetValues (XtParent(FSWIDGETS.shell), args, n);
243 /* put the form in the shell */
245 XtSetArg (args[n], XmNmarginWidth, 1); n++;
246 XtSetArg (args[n], XmNmarginHeight, 1); n++;
247 XtSetArg (args[n], XmNshadowThickness, 1); n++;
248 XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT); n++;
249 XtSetArg (args[n], XmNautoUnmanage, False); n++;
250 XtSetArg (args[n], XmNuserData, selDlgData); n++;
251 /* XtSetArg (args[n], XmNdialogStyle, (modalDialog ?
252 XmDIALOG_PRIMARY_APPLICATION_MODAL : XmDIALOG_MODELESS)); n++;*/
253 FSWIDGETS.form = (Widget) XmCreateForm (FSWIDGETS.shell, "selectForm", args, n);
255 /* put the list label in the form */
256 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
257 (FUSET, 2,"Help Volumes")));
259 XtSetArg (args[n], XmNlabelString, labelString); n++;
260 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
261 XtSetArg (args[n], XmNleftOffset, 5); n++;
262 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
263 XtSetArg (args[n], XmNtopOffset, 10); n++;
264 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
265 XtSetArg (args[n], XmNrightOffset, 5); n++;
266 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
267 FSWIDGETS.label = (Widget)
268 XmCreateLabelGadget (FSWIDGETS.form, "listLabel", args, n);
269 XtManageChild (FSWIDGETS.label);
270 XmStringFree (labelString);
272 /* Create the select scrolled list */
274 XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
275 XtSetArg (args[n], XmNselectionPolicy, XmMULTIPLE_SELECT); n++;
276 XtSetArg (args[n], XmNdoubleClickInterval, 10);/*basically disables*/n++;
277 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
278 FSWIDGETS.list = (Widget) XmCreateScrolledList (FSWIDGETS.form, "selList", args, n);
279 XtManageChild(FSWIDGETS.list);
281 XtAddCallback(FSWIDGETS.list, XmNsingleSelectionCallback,
282 SetSelectionCB,(XtPointer) selDlgData);
283 XtAddCallback(FSWIDGETS.list, XmNmultipleSelectionCallback,
284 SetSelectionCB,(XtPointer) selDlgData);
285 XtAddCallback(FSWIDGETS.list, XmNextendedSelectionCallback,
286 SetSelectionCB,(XtPointer) selDlgData);
287 /* XtAddCallback(FSWIDGETS.list, XmNdefaultActionCallback,
288 SetSelectionCB, (XtPointer) selDlgData);*/
290 /* Set the constraints on our scrolled list */
292 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
293 XtSetArg (args[n], XmNtopWidget, FSWIDGETS.label); n++;
294 XtSetArg (args[n], XmNtopOffset, 5); n++;
295 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
296 XtSetArg (args[n], XmNleftOffset, 10); n++;
297 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
298 XtSetArg (args[n], XmNrightOffset, 10); n++;
299 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
300 XtSetArg (args[n], XmNbottomOffset, 100); n++;
301 /* 100 is just a rough guess of the one that we'll calc & install later */
302 XtSetValues (XtParent (FSWIDGETS.list), args, n);
304 /* put the prompt label in the form */
305 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
306 (FUSET, 3,"Select one or more help volumes")));
308 XtSetArg (args[n], XmNlabelString, labelString); n++;
309 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
310 XtSetArg (args[n], XmNleftOffset, 20); n++;
311 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
312 XtSetArg (args[n], XmNrightOffset, 20); n++;
313 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
314 XtSetArg (args[n], XmNtopWidget, XtParent(FSWIDGETS.list)); n++;
315 XtSetArg (args[n], XmNtopOffset, 5); n++;
316 FSWIDGETS.prompt =(Widget)
317 XmCreateLabelGadget (FSWIDGETS.form, "prompt", args, n);
318 XtManageChild (FSWIDGETS.prompt);
319 XmStringFree (labelString);
321 /* Create a separator between the buttons */
323 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
324 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
325 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
326 XtSetArg (args[n], XmNtopWidget,FSWIDGETS.prompt); n++;
327 XtSetArg (args[n], XmNtopOffset, 5); n++;
328 FSWIDGETS.separator = (Widget) XmCreateSeparatorGadget (
329 FSWIDGETS.form, "separator", args, n);
330 XtManageChild (FSWIDGETS.separator);
332 /** Create the action buttons along the bottom **/
334 /* Create the close button */
335 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
336 (FUSET, 4,"Close")));
338 XtSetArg (args[n], XmNlabelString, labelString); n++;
339 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
340 XtSetArg (args[n], XmNleftPosition, 10); n++;
341 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
342 XtSetArg (args[n], XmNrightPosition, 35); n++;
343 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
344 XtSetArg (args[n], XmNtopWidget, FSWIDGETS.separator); n++;
345 XtSetArg (args[n], XmNtopOffset, 4); n++;
346 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
347 XtSetArg (args[n], XmNbottomOffset, 4); n++;
348 XtSetArg (args[n], XmNmarginHeight, 3); n++;
349 FSWIDGETS.closeBtn = (Widget) XmCreatePushButtonGadget (
350 FSWIDGETS.form, "closeBtn", args, n);
351 XtManageChild (FSWIDGETS.closeBtn);
352 XmStringFree (labelString);
354 XtAddCallback(FSWIDGETS.closeBtn, XmNactivateCallback,
355 (XtCallbackProc)CloseDialogCB, (XtPointer) selDlgData);
357 /* Build the Help button */
358 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
361 XtSetArg (args[n], XmNlabelString, labelString); n++;
362 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
363 XtSetArg (args[n], XmNleftPosition, 65); n++;
364 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
365 XtSetArg (args[n], XmNrightPosition, 90); n++;
366 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
367 XtSetArg (args[n], XmNtopWidget, FSWIDGETS.separator); n++;
368 XtSetArg (args[n], XmNtopOffset, 4); n++;
369 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
370 XtSetArg (args[n], XmNbottomOffset, 4); n++;
371 XtSetArg (args[n], XmNmarginHeight, 3); n++;
372 FSWIDGETS.helpBtn = (Widget) XmCreatePushButtonGadget (
373 FSWIDGETS.form, "helpBtn", args, n);
374 XtManageChild (FSWIDGETS.helpBtn);
375 XmStringFree (labelString);
377 pHelpInfo = _DtHelpListAdd(DtHELP_volSelectHelpBtn_STR,
378 (Widget) hw, &hw->help_dialog.help,
379 &hw->help_dialog.help.pHelpListHead);
380 XtAddCallback(FSWIDGETS.helpBtn, XmNactivateCallback,
381 _DtHelpCB, (XtPointer) pHelpInfo);
383 /* set the forms default and cancel button (for KCancel) */
385 XtSetArg (args[n], XmNcancelButton, FSWIDGETS.closeBtn); n++;
386 XtSetArg (args[n], XmNdefaultButton, FSWIDGETS.closeBtn); n++;
387 XtSetValues (FSWIDGETS.form, args, n);
389 /* Set the traversal rules */
390 XtSetArg (args[0], XmNnavigationType, XmSTICKY_TAB_GROUP); /* tab */
391 XtSetValues(FSWIDGETS.list,args,1);
392 XtSetValues(FSWIDGETS.closeBtn,args,1);
393 XtSetValues(FSWIDGETS.helpBtn,args,1);
395 /* set initial focus to list */
396 XmProcessTraversal(FSWIDGETS.list,XmTRAVERSE_CURRENT);
399 /* Adjust the decorations for the dialog shell of the dialog */
401 XtSetArg(args[n], XmNmwmFunctions, MWM_FUNC_MOVE); n++;
402 XtSetArg(args[n], XmNmwmDecorations,
403 MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
404 XtSetValues (FSWIDGETS.shell, args, n);
407 { /* set the proper offset between the bottom of the list
408 and the bottom of the form to maintain a constant sized
411 Dimension widgetBorderHeight = 0;
412 Dimension widgetHeight = 0;
414 /* first calc offset of list to form bottom based on earlier sizes */
415 #define KNOWN_OFFSETS_BELOW_LIST 24 /* 2*(4+3) + 2*5 */
416 offset = KNOWN_OFFSETS_BELOW_LIST;
418 XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
419 XtSetArg(args[n], XmNheight, &widgetHeight); n++;
420 XtGetValues(FSWIDGETS.closeBtn, args, n);
421 offset += widgetHeight + 2 * widgetBorderHeight;
422 XtGetValues(FSWIDGETS.separator, args, n);
423 offset += widgetHeight + 2 * widgetBorderHeight;
424 XtGetValues(FSWIDGETS.prompt, args, n);
425 offset += widgetHeight + 2 * widgetBorderHeight;
426 XtGetValues(XtParent(FSWIDGETS.list), args, 1); /* get only first arg */
427 offset += widgetBorderHeight;
429 /* then set the offset */
431 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
432 XtSetArg (args[n], XmNbottomOffset, offset); n++;
433 XtSetValues (XtParent (FSWIDGETS.list), args, n);
436 /* Add the popup position callback to our select dialog */
437 XtAddCallback (FSWIDGETS.shell, XmNpopupCallback,
438 (XtCallbackProc)_DtHelpMapCB, (XtPointer) XtParent(parent));
440 /* Add our help callback to the form of the dialog */
441 pHelpInfo = _DtHelpListAdd(DtHELP_volSelectShell_STR,
442 (Widget) hw, &hw->help_dialog.help,
443 &hw->help_dialog.help.pHelpListHead);
444 XtAddCallback(FSWIDGETS.form, XmNhelpCallback,
445 _DtHelpCB, (XtPointer) pHelpInfo);
447 if (out_struct) *out_struct = FSWIDGETS;
448 return FSWIDGETS.form;
453 /*****************************************************************************
454 * Function: void _DtHelpFileListCreateSelectionDialog()
457 * Parameters: parent Specifies the parent widget
458 * modelDialog should the dialog be modal or not
459 * fileList list of files from which to select
461 * Return Value: widget for the modal dialog box
463 * Purpose: Setup the selection dialog,
464 * displays the dialog, allow user selection, and return.
466 *****************************************************************************/
467 Widget _DtHelpFileListCreateSelectionDialog (
468 DtHelpDialogWidget hw,
472 XmFontList * io_titlesFontList,
473 _DtHelpFileList in_out_list,
474 _DtHelpFileDlgChildren * out_widgets)
476 Widget selDlg; /* selection dialog */
477 _DtHelpFileDlgChildren widgets;
479 _DtHelpFileEntry file;
482 /* create the dialog */
483 selDlg = CreateFileSelDialog(hw, parent, modalDialog,
484 dlgTitle, in_out_list, &widgets);
486 /* put the fonts and files in it */
487 /** Set the fontlist of our scrolled list **/
488 /* first get the font list */
489 XtSetArg (args[0], XmNfontList, &fontList);
490 XtGetValues (widgets.list, args, 1);
492 /* merge with font list of volume titles */
493 /* do this by stepping through the fontList's entries and
494 appending them to the volume title's font list */
496 XmFontContext context;
498 if ( (NULL != io_titlesFontList)
499 && XmFontListInitFontContext(&context,fontList) == True)
501 XmFontListEntry entry;
502 for ( entry = XmFontListNextEntry(context) ;
504 entry = XmFontListNextEntry(context) )
507 XmFontListAppendEntry(*io_titlesFontList,entry);
509 XmFontListFreeFontContext(context);
510 fontList = *io_titlesFontList;
512 /* and install in place */
513 XtSetArg (args[0], XmNfontList, fontList);
514 XtSetValues (widgets.list, args, 1);
518 /* populate the list with volumes */
519 for ( file = in_out_list;
521 file = _DtHelpFileListGetNext(NULL,file) )
523 XmListAddItem(widgets.list,file->fileTitleXmStr,0);
525 /* select item if file is selected */
526 if (file->fileSelected) XmListSelectPos(widgets.list,0,False);
529 /* manage the dialog and map it */
530 XtManageChild(selDlg);
532 /* pass widgets back to caller */
533 if (out_widgets) *out_widgets = widgets;