2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: History.c /main/10 1996/11/22 12:25:49 cde-hp $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: Cache Creek (Rivers) Project
31 ** Description: Creates an instance of a Cache Creek History Dialog.
34 ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
36 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
37 ** (c) Copyright 1993, 1994 International Business Machines Corp.
38 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
39 ** (c) Copyright 1993, 1994 Novell, Inc.
42 ****************************************************************************
43 ************************************<+>*************************************/
44 #include <sys/param.h>
48 #include <X11/Intrinsic.h>
49 #include <X11/Shell.h>
50 #include <X11/Xutil.h>
51 #include <X11/keysymdef.h>
53 /* These includes work in R4 and R5 */
54 #include <Xm/MwmUtil.h>
55 #include <Xm/Protocols.h>
61 #include <Xm/LabelG.h>
62 #include <Xm/ScrolledW.h>
63 #include <Xm/SeparatoG.h>
64 #include <Xm/PushBG.h>
66 #include <Xm/DialogS.h>
73 #include "DisplayAreaI.h"
74 #include "StringFuncsI.h"
77 #include "HelpDialogI.h"
78 #include "HelpDialogP.h"
79 #include "HelpUtilI.h"
80 #include "HelpAccessI.h"
89 static void CloseHistoryCB (
91 XtPointer client_data,
93 static void ProcessTopicSelectionCB(
95 XtPointer client_data,
97 static void ProcessVolumeSelectionCB(
99 XtPointer client_data,
100 XtPointer call_data);
101 static void CreateHistoryDialog(
103 static DtHistoryListStruct *AddItemToHistoryList(
104 DtHistoryListStruct **pHead,
107 Boolean *duplicateItem);
108 static DtTopicListStruct *PullTopicListFromSelVolumeList(
110 static void UpdateTopicList(
111 DtHistoryListStruct *pHistoryList,
114 static Boolean IsTopicInHistoryList(
115 DtTopicListStruct *pTopicList,
116 XmString topicTitle);
118 /************************************************************************
119 * Function: CloseHistoryCB()
121 * Close the History Dialog
123 ************************************************************************/
124 static void CloseHistoryCB (
126 XtPointer client_data,
129 DtHelpDialogWidget hw = (DtHelpDialogWidget) client_data;
131 /* We unmap the history dialog */
132 XtUnmanageChild(hw->help_dialog.history.historyWidget);
134 /* Re-sensatize the search button so the user can select it agan */
135 XtSetSensitive(hw->help_dialog.menu.historyBtn, TRUE);
136 XtSetSensitive(hw->help_dialog.browser.btnBoxHistoryBtn, TRUE);
140 /*****************************************************************************
141 * Function: Boolean _DtHelpDisplayHistoryInfo(Widget nw);
144 * Parameters: nw Specifies the name of the current help dialog
149 * Purpose: Displays the pre-created history dialog.
151 *****************************************************************************/
152 void _DtHelpDisplayHistoryInfo(
156 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw;
158 if (hw->help_dialog.history.historyWidget == NULL)
159 CreateHistoryDialog((Widget) hw);
161 /* if its not managed, manage it */
162 if ( XtIsManaged(hw->help_dialog.history.historyWidget) == False )
164 /* manage and map the History Dialog */
165 XtManageChild(hw->help_dialog.history.historyWidget);
166 XtMapWidget(XtParent((Widget)hw->help_dialog.history.historyWidget));
168 else /* if it is managed, bring it forward */
170 Widget parent = XtParent(hw->help_dialog.history.historyWidget);
171 XRaiseWindow ( XtDisplay(parent), XtWindow(parent) );
177 /*****************************************************************************
178 * Function: Boolean IsTopicInHistoryList(nw)
181 * Parameters: nw Specifies the name of the current help dialog
186 * Purpose: checks the current topic list for a matching value, and
187 * returns true if found, false if not.
189 *****************************************************************************/
190 static Boolean IsTopicInHistoryList(
191 DtTopicListStruct *pTopicList,
197 while (!done && (pTopicList != NULL))
199 if (XmStringCompare (topicTitle, pTopicList->topicTitleLbl) == True)
201 pTopicList = pTopicList->pNext;
209 /*****************************************************************************
210 * Function: void UpdateTopicList(
211 * DtHistoryListStruct *pTopics,
218 * Return Value: Void.
220 * Purpose: Cleans and recreates a new topic list
222 *****************************************************************************/
223 static void UpdateTopicList(
224 DtHistoryListStruct *pHistoryList,
231 XmString labelString;
233 DtTopicListStruct *pTopicList=NULL;
234 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw;
237 /* Flush the current history topic list */
238 XmListDeselectAllItems(hw->help_dialog.history.topicList);
239 XmListDeleteAllItems(hw->help_dialog.history.topicList);
241 /* Grab the top of our current topic list from our history list struct */
242 pTopicList = pHistoryList->pTopicHead;
244 /* Loop through and build up a new visible topics list */
245 items = (XmString *) XtMalloc(sizeof(XmString) * pHistoryList->totalNodes);
246 for (i = 0; i < pHistoryList->totalNodes; i++)
248 items[i] = pTopicList->topicTitleLbl;
249 pTopicList = pTopicList->pNext;
252 XtSetArg(args[0], XmNitems,items);
253 XtSetArg(args[1], XmNitemCount, pHistoryList->totalNodes);
254 XtSetValues(hw->help_dialog.history.topicList, args, 2);
256 XtFree((char *)items);
258 /* Now, modify the label if we need to */
262 case DtHELP_TYPE_TOPIC:
263 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
264 (3, 8,"Help Topics Visited:")));
268 case DtHELP_TYPE_FILE:
269 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
270 (3, 9,"Help Files Visited:")));
274 case DtHELP_TYPE_MAN_PAGE:
275 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
276 (3, 10,"Man Pages Visited:")));
280 case DtHELP_TYPE_STRING:
281 case DtHELP_TYPE_DYNAMIC_STRING:
282 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
283 (3, 11,"Help Messages Visited:")));
287 /* Bogus type, how did we ever get here ??? */
290 } /* End Switch Statement */
293 XtSetArg (args[n], XmNlabelString, labelString); n++;
294 XtSetValues (hw->help_dialog.history.topicsListLabel, args, n);
295 XmStringFree(labelString);
301 /*****************************************************************************
302 * Function: void ProcessVolumeSelectionCB(Widget w,
303 * XtPointer client_data,
304 * XtPointer call_data);
310 * Return Value: Void.
312 * Purpose: Process user selection of an item in the Volume List
313 * of the history dialo.
315 *****************************************************************************/
316 static void ProcessVolumeSelectionCB(
318 XtPointer client_data,
321 XmListCallbackStruct *selectedItem = (XmListCallbackStruct *) call_data;
322 DtHelpDialogWidget hw = (DtHelpDialogWidget) client_data;
323 DtHistoryListStruct *pTemp= NULL;
326 XmString labelString;
327 int * topicPosList = NULL;
333 /* Determin the item selected in the volume list */
334 topicPosition = selectedItem->item_position;
336 /* To fix the bug of having no volume selected, check
337 whether user clicked again on the currently selected item,
338 deselecting it and leaving no other selected, and just
339 reselect that item and do nothing else */
340 /* for reasons unknown, selectedItem->selected_item_positions
341 doesnt seem properly initialized and leads to a core dump;
342 so use XmListGetSelectedPos() instead */
343 if ( False == XmListGetSelectedPos(w, &topicPosList, &topicCnt)
344 && NULL == topicPosList )
346 XmListSelectPos(w,topicPosition,False); /* False=dont notify */
349 XtFree((char *)topicPosList);
351 /* and find that item in our list */
352 pTemp = hw->help_dialog.history.pHistoryListHead;
353 for (i=1;i < topicPosition; i++)
354 pTemp = pTemp->pNext;
357 UpdateTopicList(pTemp, (Widget)hw, pTemp->topicType);
359 /* Look to see if we have the current visible topic matches something in
360 * in the topic list. If so, highlight the item in the topic list
362 XtSetArg(args[0], XmNfontList, &fontList);
363 XtGetValues(hw->help_dialog.history.topicList, args, 1);
365 if ( _DtHelpFormatTopicTitle (hw->help_dialog.help.pDisplayArea,
366 hw->help_dialog.display.volumeHandle,
367 hw->help_dialog.display.locationId,
368 &labelString, &fontList, &mod) != 0
369 || NULL == labelString)
371 labelString = XmStringCreateLocalized(hw->help_dialog.display.locationId);
376 /* must set the fontlist, otherwise this will cause a dangle later. */
377 XtSetArg(args[0], XmNfontList, fontList);
378 XtSetValues(hw->help_dialog.history.topicList, args, 1);
379 XmFontListFree(fontList);
382 XmListSelectItem(hw->help_dialog.history.topicList,labelString, FALSE);
383 XmListSetBottomItem(hw->help_dialog.history.topicList,labelString);
384 XmStringFree(labelString);
391 /*****************************************************************************
392 * Function: void ProcessTopicSelectionCB(Widget w,
393 * XtPointer client_data,
394 * XtPointer call_data);
400 * Return Value: Void.
402 * Purpose: Process user selection of an item in the History List.
404 *****************************************************************************/
405 static void ProcessTopicSelectionCB(
407 XtPointer client_data,
410 XmListCallbackStruct *selectedItem = (XmListCallbackStruct *) call_data;
411 DtHelpDialogWidget hw = (DtHelpDialogWidget) client_data;
413 DtTopicListStruct *pTemp= NULL;
418 /* First, find out what item is currently selected in our
419 * volume list. From this, we can get the proper topic list to
423 pTemp = PullTopicListFromSelVolumeList((Widget)hw);
427 /*FIX: We have a problem, this should never happen; decide what to do*/
432 /* Determin the item selected and find that item in our list */
433 topicPosition = selectedItem->item_position;
435 for (i=1;i < topicPosition; i++)
436 pTemp = pTemp->pNext;
438 hw->help_dialog.display.helpType = pTemp->topicType;
440 if (hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC)
442 if (hw->help_dialog.display.topicTitleLbl != NULL)
443 XmStringFree(hw->help_dialog.display.topicTitleLbl);
444 hw->help_dialog.display.topicTitleLbl =
445 XmStringCopy(pTemp->topicTitleLbl);
449 switch (pTemp->topicType)
451 case DtHELP_TYPE_TOPIC:
452 /* Look and see if we need to update our helpVolue to a new value */
453 if ( pTemp->helpVolume != NULL
454 && ( hw->help_dialog.display.helpVolume == NULL
455 || strcmp(hw->help_dialog.display.helpVolume,pTemp->helpVolume) != 0))
457 XtFree(hw->help_dialog.display.helpVolume);
458 hw->help_dialog.display.helpVolume = XtNewString(pTemp->helpVolume);
460 /* Set our help volume flag so we open the proper volume */
461 hw->help_dialog.ghelp.volumeFlag = FALSE;
464 XtFree(hw->help_dialog.display.locationId);
465 hw->help_dialog.display.locationId = XtNewString(pTemp->locationId);
467 /* set the topicType flag to process correctly */
468 hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
472 case DtHELP_TYPE_STRING:
473 XtFree(hw->help_dialog.display.stringData);
474 hw->help_dialog.display.stringData = XtNewString(pTemp->locationId);
476 /* set the topicType flag to process correctly */
477 hw->help_dialog.display.helpType = DtHELP_TYPE_STRING;
481 case DtHELP_TYPE_DYNAMIC_STRING:
482 XtFree(hw->help_dialog.display.stringData);
483 hw->help_dialog.display.stringData = XtNewString(pTemp->locationId);
485 /* set the topicType flag to process correctly */
486 hw->help_dialog.display.helpType = DtHELP_TYPE_DYNAMIC_STRING;
490 case DtHELP_TYPE_MAN_PAGE:
491 XtFree(hw->help_dialog.display.manPage);
492 hw->help_dialog.display.manPage = XtNewString(pTemp->locationId);
494 /* set the topicType flag to process correctly */
495 hw->help_dialog.display.helpType = DtHELP_TYPE_MAN_PAGE;
499 case DtHELP_TYPE_FILE:
500 XtFree(hw->help_dialog.display.helpFile);
501 hw->help_dialog.display.helpFile = XtNewString(pTemp->locationId);
503 /* set the topicType flag to process correctly */
504 hw->help_dialog.display.helpType = DtHELP_TYPE_FILE;
511 /* We should never get here, because we using the proper types */
514 } /* End Switch Statement */
516 _DtHelpSetupDisplayType(hw, FALSE, DtHISTORY_AND_JUMP);
524 /*****************************************************************************
525 * Function: void CreateHistoryDialog(
529 * Parameters: helpDialogWidget Specifies the current Help Dialog to
530 * create the history dialog for.
535 * Purpose: Create and display an instance of a history dialog.
537 *****************************************************************************/
538 static void CreateHistoryDialog(
542 Widget volumeListLabel;
544 Widget cancelBtn, helpBtn;
548 XmString labelString;
552 DtHelpListStruct *pHelpInfo;
554 Dimension btnHeight=0;
555 Dimension widgetBorderHeight=0;
557 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw ;
559 /* Create the shell and form used for the dialog. */
561 title = XtNewString(((char *)_DTGETMESSAGE(3, 1,"Help - History Browser")));
563 XtSetArg (args[n], XmNtitle, title); n++;
564 XtSetArg (args[n], XmNallowShellResize, TRUE); n++;
565 historyShell = XmCreateDialogShell((Widget) hw, "historyShell", args, n);
568 /* Set the useAsyncGeo on the shell */
570 XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
571 XtSetValues (XtParent(historyShell), args, n);
575 XtSetArg (args[n], XmNmarginWidth, 1); n++;
576 XtSetArg (args[n], XmNmarginHeight, 1); n++;
577 XtSetArg (args[n], XmNshadowThickness, 1); n++;
578 XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT); n++;
579 XtSetArg (args[n], XmNautoUnmanage, False); n++;
580 historyForm = XmCreateForm (historyShell, "historyForm", args, n);
583 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
584 (3, 2,"Help Volumes Visited:")));
586 XtSetArg (args[n], XmNlabelString, labelString); n++;
587 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
588 XtSetArg (args[n], XmNleftOffset, 5); n++;
589 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
590 XtSetArg (args[n], XmNtopOffset, 10); n++;
592 XmCreateLabelGadget (historyForm, "volumeListLabel", args, n);
593 XtManageChild (volumeListLabel);
594 XmStringFree (labelString);
597 /* Create our history scrolled list */
599 XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
600 XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
601 XtSetArg (args[n], XmNresizable, FALSE); n++;
602 hw->help_dialog.history.volumeList =
603 XmCreateScrolledList (historyForm, "historyVolumeList", args, n);
604 XtManageChild (hw->help_dialog.history.volumeList);
606 XtAddCallback (hw->help_dialog.history.volumeList,
607 XmNsingleSelectionCallback,
608 (XtCallbackProc)ProcessVolumeSelectionCB, (XtPointer) hw);
610 /* Set the constraints on our scrolled list */
612 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
613 XtSetArg (args[n], XmNtopWidget, volumeListLabel); n++;
614 XtSetArg (args[n], XmNtopOffset, 5); n++;
615 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
616 XtSetArg (args[n], XmNleftOffset, 10); n++;
617 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
618 XtSetArg (args[n], XmNrightOffset, 10); n++;
619 XtSetValues (XtParent (hw->help_dialog.history.volumeList), args, n);
622 /* Create the Result Label and scrolled list */
624 /* Create Result List Label */
625 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
626 (3, 8,"Help Topics Visited:")));
628 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
629 XtSetArg (args[n], XmNtopWidget,
630 XtParent(hw->help_dialog.history.volumeList)); n++;
631 XtSetArg (args[n], XmNtopOffset, 10); n++;
632 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
633 XtSetArg (args[n], XmNleftOffset, 10); n++;
634 XtSetArg (args[n], XmNlabelString, labelString); n++;
635 hw->help_dialog.history.topicsListLabel =
636 XmCreateLabelGadget (historyForm, "topicsListLabel", args, n);
637 XtManageChild (hw->help_dialog.history.topicsListLabel);
638 XmStringFree (labelString);
641 /* Create our volume topics list */
643 XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
644 XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
645 XtSetArg (args[n], XmNresizable, FALSE); n++;
646 hw->help_dialog.history.topicList =
647 XmCreateScrolledList (historyForm, "historyTopicList", args, n);
648 XtManageChild (hw->help_dialog.history.topicList);
650 XtAddCallback (hw->help_dialog.history.topicList,
651 XmNsingleSelectionCallback,
652 (XtCallbackProc)ProcessTopicSelectionCB,
655 XtAddCallback (hw->help_dialog.history.topicList,
656 XmNdefaultActionCallback,
657 (XtCallbackProc)ProcessTopicSelectionCB,
660 /* Set the constraints on our scrolled list */
662 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
663 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.history.topicsListLabel); n++;
664 XtSetArg (args[n], XmNtopOffset, 5); n++;
665 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
666 XtSetArg (args[n], XmNleftOffset, 10); n++;
667 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
668 XtSetArg (args[n], XmNrightOffset, 10); n++;
669 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
670 XtSetArg (args[n], XmNbottomOffset, 70); n++;
671 XtSetValues (XtParent (hw->help_dialog.history.topicList), args, n);
674 /* Create a separator between the buttons */
677 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
678 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
679 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
680 XtSetArg (args[n], XmNtopWidget,
681 XtParent(hw->help_dialog.history.topicList)); n++;
682 XtSetArg (args[n], XmNtopOffset, 8); n++;
683 separator = XmCreateSeparatorGadget (historyForm, "separator", args, n);
684 XtManageChild (separator);
687 /* Create the action buttons along the bottom */
688 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
691 XtSetArg (args[n], XmNlabelString, labelString); n++;
692 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
693 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
694 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
695 XtSetArg (args[n], XmNtopWidget, separator); n++;
696 XtSetArg (args[n], XmNtopOffset, 5); n++;
697 XtSetArg (args[n], XmNmarginHeight, 4); n++;
698 XtSetArg (args[n], XmNmarginWidth, 6); n++;
699 /*XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
700 *XtSetArg (args[n], XmNbottomOffset, 3); n++;
702 cancelBtn = XmCreatePushButtonGadget (historyForm, "cancelBtn", args, n);
704 XtAddCallback(cancelBtn, XmNactivateCallback,
705 (XtCallbackProc)CloseHistoryCB, (XtPointer) hw);
707 XtManageChild (cancelBtn);
708 XmStringFree (labelString);
710 XtSetArg (args[0], XmNdefaultButton, cancelBtn);
711 XtSetValues (historyForm, args, 1);
713 /* set the cancel button (for KCancel) */
715 XtSetArg (args[n], XmNcancelButton, cancelBtn); n++;
716 XtSetValues (historyForm, args, n);
719 /* Build the Help button */
721 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
724 XtSetArg (args[n], XmNlabelString, labelString); n++;
725 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
726 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
727 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
728 XtSetArg (args[n], XmNtopWidget, separator); n++;
729 XtSetArg (args[n], XmNtopOffset, 5); n++;
730 XtSetArg (args[n], XmNmarginHeight, 4); n++;
731 XtSetArg (args[n], XmNmarginWidth, 6); n++;
732 helpBtn = XmCreatePushButtonGadget (historyForm, "helpBtn", args, n);
733 XtManageChild (helpBtn);
735 /* Setup and add our help callback for this button */
736 pHelpInfo = _DtHelpListAdd(DtHELP_historyHelpBtn_STR,
737 (Widget) hw, &hw->help_dialog.help,
738 &hw->help_dialog.help.pHelpListHead);
739 XtAddCallback (helpBtn, XmNactivateCallback,
740 _DtHelpCB, (XtPointer) pHelpInfo);
742 XmStringFree (labelString);
745 /* Adjust the decorations for the dialog shell of the dialog */
747 XtSetArg(args[n], XmNmwmFunctions,
748 MWM_FUNC_MOVE |MWM_FUNC_RESIZE); n++;
749 XtSetArg (args[n], XmNmwmDecorations,
750 MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_RESIZEH); n++;
751 XtSetValues (historyShell, args, n);
753 /* calculate and set the buttons' positions on the form */
756 unsigned long avgWidth = 73; /* default size, in 10ths of pixel */
758 XmFontList fontList = NULL;
760 #define BTN_MARGINS 4
761 #define BETW_BTN_SPC 5
763 XtSetArg(args[0], XmNfontList, &fontList);
764 XtGetValues(hw->help_dialog.history.topicList, args, 1);
766 btnList[0] = cancelBtn;
767 btnList[1] = helpBtn;
769 /* get the average width of the topic list's font */
770 xa_ave_width = XmInternAtom(XtDisplay(cancelBtn), "AVERAGE_WIDTH", False);
771 _DtHelpXmFontListGetPropertyMax(fontList, xa_ave_width, &avgWidth);
773 /* xa_ave_width is given in 10ths of a pixel; convert to pixels by div thru 10 */
774 /* we want a 25 column minimum width */
775 formWidth = avgWidth * 25 / 10;
777 _DtHelpSetButtonPositions(btnList, 2, formWidth, BTN_MARGINS, BETW_BTN_SPC);
780 /* Perform the final form layout so our dialog resizes correctly. */
781 /* Get height of: bottom buttons and separator */
783 XtSetArg(args[n], XmNheight, &btnHeight); n++;
784 XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
785 XtGetValues(cancelBtn, args, n);
786 offset = btnHeight + widgetBorderHeight + 15;
787 /* 20 =='s fudge factor */
790 XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
791 XtSetArg(args[n], XmNheight, &btnHeight); n++;
792 XtGetValues(separator, args, n);
793 offset += btnHeight + widgetBorderHeight;
797 /* make the bottom attachment for the seporator such that things will fit,
798 * and the dialog will size properly.
801 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
802 XtSetArg (args[n], XmNbottomOffset, offset); n++;
803 XtSetValues (XtParent (hw->help_dialog.history.topicList), args, n);
805 /* We may have some history values already, so update our newlly
806 * created scrolled list widget.
810 /* Add the popup position callback to our history dialog */
811 XtAddCallback (historyShell, XmNpopupCallback, (XtCallbackProc)_DtHelpMapCB,
812 (XtPointer) XtParent(hw));
814 /* Add our help callback to the shell of the dialog */
815 pHelpInfo = _DtHelpListAdd(DtHELP_historyShell_STR,
816 (Widget) hw, &hw->help_dialog.help,
817 &hw->help_dialog.help.pHelpListHead);
818 XtAddCallback(historyForm, XmNhelpCallback,
819 _DtHelpCB, (XtPointer) pHelpInfo);
821 /* Assign our new search dialog to our widget instance */
822 hw->help_dialog.history.historyWidget = historyForm;
829 /*****************************************************************************
830 * Function: void _DtHelpUpdateHistoryList(char *locationId,
835 * Parameters: parent Specifies the ID string for the new topic we
836 * are going to display in the HelpDialog widget.
838 * helpDialogWidget Specifies the current help dialog widget.
840 * Return Value: Void.
842 * Purpose: Updates the Path Display area on top of the help
845 *****************************************************************************/
846 void _DtHelpUpdateHistoryList(
852 DtHistoryListStruct *pCurrentHistoryList=NULL;
853 XmString topicTitle = NULL;
854 XmString currentItemTitle = NULL;
855 Boolean allocTopic=FALSE;
856 Boolean dupItem=FALSE;
857 Boolean changedSelectedVolume=FALSE;
862 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw;
865 /* Lets just build a history dialog so we can start populating it.
866 * We won't manage it tell we need it
868 if (hw->help_dialog.history.historyWidget == NULL)
869 CreateHistoryDialog((Widget) hw);
871 /* Find out what type of topic we are currently processing */
874 case DtHELP_TYPE_TOPIC:
877 * get the font list for the volume list.
879 XtSetArg(args[0], XmNfontList, &fontList);
880 XtGetValues(hw->help_dialog.history.topicList, args, 1);
882 /* First we get the current topics Title */
885 if (_DtHelpFormatTopicTitle (hw->help_dialog.help.pDisplayArea,
886 hw->help_dialog.display.volumeHandle,
887 locationId, &topicTitle,
888 &fontList, &mod) != 0
889 || NULL == topicTitle)
890 topicTitle = XmStringCreateLocalized(locationId);
894 XtSetArg(args[0], XmNfontList, fontList);
895 XtSetValues(hw->help_dialog.history.topicList, args, 1);
896 XmFontListFree(fontList);
900 * get the font list for the volume list.
902 XtSetArg(args[0], XmNfontList, &fontList);
903 XtGetValues(hw->help_dialog.history.volumeList, args, 1);
905 /* Second, we get the current volume title */
907 _DtHelpFormatVolumeTitle (hw->help_dialog.help.pDisplayArea,
908 hw->help_dialog.display.volumeHandle,
909 ¤tItemTitle, &fontList, &mod);
911 if(currentItemTitle == NULL &&
912 NULL != hw->help_dialog.display.helpVolume)
913 currentItemTitle = XmStringCreateLocalized(
914 hw->help_dialog.display.helpVolume);
917 XtSetArg(args[0], XmNfontList, fontList);
918 XtSetValues(hw->help_dialog.history.volumeList, args, 1);
919 XmFontListFree(fontList);
925 case DtHELP_TYPE_FILE:
926 currentItemTitle = XmStringCreateLocalized(
927 ((char *)_DTGETMESSAGE(3, 5, "Help Files")));
928 topicTitle = hw->help_dialog.display.topicTitleLbl;
932 case DtHELP_TYPE_MAN_PAGE:
933 currentItemTitle = XmStringCreateLocalized(
934 ((char *)_DTGETMESSAGE(3, 6, "Man Pages")));
935 topicTitle = hw->help_dialog.display.topicTitleLbl;
939 case DtHELP_TYPE_STRING:
940 case DtHELP_TYPE_DYNAMIC_STRING:
941 currentItemTitle = XmStringCreateLocalized(
942 ((char *)_DTGETMESSAGE(3, 7, "Help Messages")));
943 topicTitle = hw->help_dialog.display.topicTitleLbl;
947 /* Bogus type, how did we ever get here ??? */
950 } /* End Switch Statement */
953 /* Now add this item to the history list if necessary. This fuction
954 * will return a pointer to the current working history list item.
956 pCurrentHistoryList = AddItemToHistoryList(
957 &(hw->help_dialog.history.pHistoryListHead),
958 currentItemTitle, topicType, &dupItem);
962 /* We can skip this if it already exists in our history list,else
963 * we add the new history item to the top of the scrolled window
965 XmListAddItem(hw->help_dialog.history.volumeList,currentItemTitle, 1);
966 XmListSelectPos(hw->help_dialog.history.volumeList,1, FALSE);
968 else /* dupItem == True */
970 /* We changed to a diferent volume or help type so force it selected */
971 XmListSelectItem(hw->help_dialog.history.volumeList,
972 currentItemTitle, FALSE);
973 changedSelectedVolume = TRUE;
974 if (NULL != currentItemTitle)
975 XmStringFree(currentItemTitle);
978 /* Now add this item to the proper Topic List. */
979 if (pCurrentHistoryList != NULL)
982 if (!IsTopicInHistoryList(pCurrentHistoryList->pTopicHead, topicTitle))
984 /* Add the new topic to the history top of the history list */
985 _DtHelpTopicListAddToHead(locationId, topicTitle,topicType,
987 hw->help_dialog.display.helpVolume,
988 &(pCurrentHistoryList->pTopicHead),
989 &(pCurrentHistoryList->pTopicTale),
990 &(pCurrentHistoryList->totalNodes),
991 hw->help_dialog.backtr.scrollPosition);
993 XmUpdateDisplay((Widget) hw);
994 UpdateTopicList(pCurrentHistoryList, (Widget)hw, topicType);
997 /* Force the top item to be selected */
998 XmListSelectPos(hw->help_dialog.history.topicList,1, FALSE);
1002 if (changedSelectedVolume)
1004 if (TRUE == vol_changed)
1005 UpdateTopicList(pCurrentHistoryList, (Widget)hw, topicType);
1006 XmListSelectItem(hw->help_dialog.history.topicList,topicTitle,
1008 /* Make sure the item is visible */
1012 if (allocTopic == True)
1013 XmStringFree(topicTitle);
1018 /*****************************************************************************
1019 * Function: static DtHistoryListStruct *AddItemToHistoryList(
1022 * title Specifies the XmString of the title. If
1023 * 'duplicateItem' returns False, the caller
1024 * must not modify or free this parameter.
1027 * Return Value: Pointer to the current history list node that we are going
1030 * Purpose: Add or update our history list with a new item
1032 *****************************************************************************/
1033 static DtHistoryListStruct *AddItemToHistoryList(
1034 DtHistoryListStruct **pHead,
1037 Boolean *duplicateItem)
1039 DtHistoryListStruct *pTemp=NULL;
1046 *duplicateItem = False;
1048 while (!done && (pTemp != NULL))
1050 if (XmStringCompare (title, pTemp->itemTitle) == True)
1052 /* We have a match, so lets use it */
1053 *duplicateItem = TRUE;
1057 pTemp = pTemp->pNext;
1063 /* We did not find a match, so lets add one to the top of
1066 pTemp =(DtHistoryListStruct *) XtMalloc((sizeof(DtHistoryListStruct)));
1069 pTemp->itemTitle = title;
1070 pTemp->totalNodes = 0;
1071 pTemp->topicType = topicType;
1072 pTemp->pNext = (*pHead);
1073 pTemp->pTopicHead = NULL;
1074 pTemp->pTopicTale = NULL;
1076 /* Re-Assign our head pointer to point to the new
1087 /*****************************************************************************
1088 * Function: static DtHistoryListStruct PullTopicListFromSelVolumeList
1093 * Return Value: Pointer to the current history list node that we are going
1096 * Purpose: Add or update our history list with a new item
1098 *****************************************************************************/
1099 static DtTopicListStruct *PullTopicListFromSelVolumeList(
1102 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw;
1103 DtHistoryListStruct *pTemp=NULL;
1104 Boolean itemsSelected=FALSE;
1106 int *positionList; /* Should always be only one item */
1110 pTemp = hw->help_dialog.history.pHistoryListHead;
1112 /* Find out what item is currently selected in our visited volumes list */
1114 itemsSelected = XmListGetSelectedPos(hw->help_dialog.history.volumeList,
1115 &positionList, &positionCount);
1119 /* We should get in here every time */
1121 for (i=1;i < positionList[0]; i++)
1122 pTemp = pTemp->pNext;
1125 return (pTemp->pTopicHead);
1131 /* error condition we must account for */