1 /* $TOG: GlobSearch.c /main/21 1999/11/11 10:59:15 mgreess $ */
2 /************************************<+>*************************************
3 ****************************************************************************
7 ** Project: DtHelp Project
9 ** Description: Builds and displays an instance of a DtHelp GlobSearch
12 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
13 ** (c) Copyright 1993, 1994 International Business Machines Corp.
14 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
15 ** (c) Copyright 1993, 1994 Novell, Inc.
19 ****************************************************************************
20 ************************************<+>*************************************/
21 #include <sys/param.h>
25 #include <sys/utsname.h>
28 #include <stdlib.h> /* for MB_CUR_MAX */
29 #include <unistd.h> /* R_OK */
30 #include <locale.h> /* getlocale(), LOCALE_STATUS */
34 # include <libgen.h> /* for regcmp, regex */
37 # include <regex.h> /* for regcomp, regexec */
46 #include <Xm/LabelG.h>
47 #include <Xm/ScrolledW.h>
48 #include <Xm/SeparatoG.h>
49 #include <Xm/PushBG.h>
51 #include <Xm/DialogS.h>
52 #include <Xm/MwmUtil.h>
53 #include <Xm/Protocols.h>
54 #include <Xm/RowColumn.h>
55 #include <Xm/SelectioB.h>
56 #include <Xm/ToggleBG.h>
58 #include <X11/Intrinsic.h>
59 #include <X11/Shell.h>
60 #include <X11/ShellP.h>
61 #include <X11/Xutil.h>
62 #include <X11/keysymdef.h>
65 #include <Dt/HelpDialog.h>
71 #include "StringFuncsI.h"
72 #include "DisplayAreaI.h"
73 #include "HelpDialogP.h"
74 #include "HelpDialogI.h"
75 #include "HelpAccessI.h"
76 #include "HelpUtilI.h"
78 #include "GlobSearchI.h"
79 #include "FileListUtilsI.h"
80 #include "FileUtilsI.h"
82 #include "HelpXlate.h"
83 #include "VolSelectI.h"
86 /******** TYPES ***********/
88 SEARCH_RESULTS_STATUS = 1,
93 FIRST_PROMPT_STATUS = 6
96 static Boolean VolumeHasIndexP (
97 _DtHelpGlobSrchSources srchSource,
100 static void DeleteListContents(
101 _DtHelpGlobSearchStuff * srch);
102 static void StatusLabelUpdate(
103 DtHelpDialogWidget hw,
104 ResultsStatus status,
107 static void ResultsListUpdate(
108 DtHelpDialogWidget hw,
109 _DtHelpFileEntry newFile);
110 static void StopSearchCB(
112 XtPointer clientData,
114 static void VolNameDisplay(
115 DtHelpDialogWidget hw,
116 _DtHelpFileEntry file,
118 static int VolHitsDisplay (
119 DtHelpDialogWidget hw,
120 _DtHelpFileEntry file);
121 static void UpdateSearchVolumesCB(
123 XtPointer clientData,
125 static void UpdateSearchStartStatusCB(
127 XtPointer clientData,
130 /********** CONSTANTS *************/
131 #define DIR_SLASH '/'
134 /* message catalog set number for GlobSearch.c */
137 #define DONT_SET (-1) /* used as third value of a Boolean */
139 #define HIT_FONT_RES_NAME "*helpSearchMonoFont"
140 #define HIT_FONT_RES_CLASS "*HelpSearchMonoFont"
141 #define PREFIX_FONT_SPEC "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
142 #define PREFIX_FONT_SPEC1 "-dt-application-bold-r-normal-*-*-140-*-*-m-*-iso8859-1"
143 #define PREFIX_FONT_SPEC2 "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
144 #define PREFIX_FONT_SPEC3 "courb14" /* non CDE platforms */
145 #define PREFIX_FONT_TAG "prefixFontTag"
147 #define START_SEARCH_CAT s_GlobSrchDlgBtnCatNum[0]
148 #define START_SEARCH_STR s_GlobSrchDlgBtnStrs[0]
149 #define START_SEARCH_MNEM "S"
150 #define CONT_SEARCH_CAT s_GlobSrchDlgBtnCatNum[1]
151 #define CONT_SEARCH_STR s_GlobSrchDlgBtnStrs[1]
152 #define CONT_SEARCH_MNEM "S"
153 #define STOP_SEARCH_CAT s_GlobSrchDlgBtnCatNum[2]
154 #define STOP_SEARCH_STR s_GlobSrchDlgBtnStrs[2]
155 #define STOP_SEARCH_MNEM "S"
156 #define CLOSE_BTN_CAT s_GlobSrchDlgBtnCatNum[3]
157 #define CLOSE_BTN_STR s_GlobSrchDlgBtnStrs[3]
158 #define CLOSE_BTN_MNEM "C"
159 #define HELP_BTN_CAT s_GlobSrchDlgBtnCatNum[4]
160 #define HELP_BTN_STR s_GlobSrchDlgBtnStrs[4]
161 #define HELP_BTN_MNEM "H"
164 /********** MACROS ************/
165 #define max(a,b) ((a) > (b) ? (a) : (b))
167 /********** Global VARIABLES ************/
168 char _DtHelpDefaultSrchHitPrefixFont[] = PREFIX_FONT_SPEC;
170 /********** VARIABLES ************/
171 static const char *DirSlash = "/";
172 static char * s_GlobSrchDlgBtnStrs[] = {
179 /* catalog index numbers for the strings */
180 static unsigned char s_GlobSrchDlgBtnCatNum[] = {
181 12, 13, 14, 15, 16 };
183 static char * s_PrefixFontListTag = NULL;
185 /* Setup for the Retrun Translation set for the text field */
186 static char defaultBtnTranslations[] = "<Key>Return: Activate()";
187 /* static char defaultListTranslations[] = "<Key>Return: Activate()"; */
188 /* static char defaultMgrTranslations[] = "<Key>Return: ManagerParentActivate()"; */
191 /************************************************************************
192 The startPosition and nextVolPosition values of the DtHelpGlobSrchVol
193 structure are used as follows:
195 startPosition: the position of the volume in the results list
196 if hitCnt == 0, startPosition is the same value as the
197 most recent volume with hits
198 nextVolPosition: the position of the next volume in the results list
199 if hitCnt == 0, nextVolPosition is the same value as the
200 most recent volume with hits
201 The value must be adjusted to include the positions
202 occupied by hits and topics that are listed for the volume
204 These variables are maintained using the AdjustPositionValues()
205 routine, which increment/decrement the position values of all
206 files after the start. So, when doing a search and display,
207 as results are added to the list, the position values of volumes
208 later in the list are always up to date.
209 ************************************************************************/
212 /*======================================================================*/
213 /*======================================================================*/
214 /*======================================================================*/
215 /*======================================================================*/
218 /*****************************************************************************
219 * Function: void MergeFontListIntoWidgetFonts()
221 * Parameters: widget a widget with a XmNfontList resource
222 * newFontsList font list with fonts to merge into widget
226 * Purpose: Merges the fonts from the newFontsList into the fontlist
229 *****************************************************************************/
230 static void MergeFontListIntoWidgetFonts(
232 XmFontList newFontsList)
234 XmFontList fontList = NULL;
235 XmFontContext context;
236 XmFontListEntry entry;
239 /* get current resultList fontlist */
240 XtSetArg(args[0], XmNfontList, &fontList);
241 XtGetValues(widget,args,1);
243 if (NULL == fontList) return; /* RETURN on error */
245 /* work with copy, because FontListAppendEntry() destroys input FL */
246 fontList = XmFontListCopy(fontList);
248 /* walk through the volTitlesFontList entries and add them in */
249 XmFontListInitFontContext(&context,newFontsList);
250 for ( entry = XmFontListNextEntry(context);
252 entry = XmFontListNextEntry(context) )
254 fontList = XmFontListAppendEntry(fontList,entry);
256 if (context) XmFontListFreeFontContext(context);
258 /* install the changed list */
259 XtSetArg(args[0], XmNfontList, fontList);
260 XtSetValues(widget,args,1);
262 if (fontList) XmFontListFree(fontList);
266 /*****************************************************************************
267 * Function: void UpdateCurVolBtnSens()
269 * Parameters: new the help widget
271 * Return Value: True if cur vol has an index
274 * Purpose: Checks on current volume for an index
275 and sets buttons appropriately
277 *****************************************************************************/
278 static Boolean UpdateCurVolBtnSens(
279 DtHelpDialogWidget hw,
280 Boolean selectVolBtn)
282 XmToggleButtonCallbackStruct status; /* the call data */
286 /* set the cur vol btn sensitivity */
287 /* set the volumes/show selection btns by generating a false event */
288 status.reason = XmCR_VALUE_CHANGED;
290 status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
293 if ( VolumeHasIndexP (
294 hw->help_dialog.srch.srchSources,
295 hw->help_dialog.display.helpType,
296 hw->help_dialog.display.helpVolume) )
299 sourceBtn = hw->help_dialog.srch.curVolRadBtn;
304 sourceBtn = hw->help_dialog.srch.allVolRadBtn;
306 /* ??? XtSetSensitive(hw->help_dialog.srch.curVolRadBtn,curState); */
307 hw->help_dialog.srch.curVolRadBtnSens = curState;
308 if (selectVolBtn) UpdateSearchVolumesCB(sourceBtn,hw,&status);
312 sourceBtn = hw->help_dialog.srch.curVolRadBtn;
314 hw->help_dialog.srch.curVolRadBtnSens = curState;
316 UpdateSearchVolumesCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
324 /************************************************************************
325 * Function: LoadPrefixFont()
327 * Loads the prefix font, if that hasn't yet occurred
329 ************************************************************************/
330 static void LoadPrefixFont(
331 DtHelpDialogWidget hw)
333 XmFontListEntry entry;
334 XmFontList curFontList = NULL;
335 XmFontList newFontList = NULL;
336 char * fontSpec = NULL;
339 if (hw->help_dialog.srch.hitsFontLoaded) return; /* RETURN */
341 /* this code is for when the resource is part of the widget */
342 fontSpec = hw->help_dialog.srch.hitPrefixFont;
344 /* get current font list */
345 XtSetArg(args[0], XmNfontList, &curFontList);
346 XtGetValues(hw->help_dialog.srch.resultList,args,1);
348 /* work with copy, because FontListAppendEntry() destroys input FL */
349 newFontList = XmFontListCopy(curFontList);
351 /* load and merge fonts */
352 s_PrefixFontListTag = PREFIX_FONT_TAG;
353 entry = XmFontListEntryLoad(XtDisplay(hw->help_dialog.srch.srchForm),
354 fontSpec,XmFONT_IS_FONT, s_PrefixFontListTag);
355 newFontList = XmFontListAppendEntry(newFontList,entry);
356 XmFontListEntryFree(&entry);
359 if (NULL == newFontList)
361 s_PrefixFontListTag = XmFONTLIST_DEFAULT_TAG;
365 /* set new font list */
366 XtSetArg(args[0], XmNfontList, newFontList);
367 XtSetValues(hw->help_dialog.srch.resultList,args,1);
368 if (newFontList) XmFontListFree(newFontList);
370 hw->help_dialog.srch.hitsFontLoaded = True;
375 /************************************************************************
376 * Function: VolumeHasIndexP()
378 * Looks for the specified volume in the file system and
379 * tests whether the volume has an index associated with it.
381 ************************************************************************/
382 static Boolean VolumeHasIndexP (
383 _DtHelpGlobSrchSources srchSource,
388 _DtHelpVolumeHdl vol;
389 int keyWordCount = 0;
390 char **currentKeyList = NULL;
392 /* if help content isn't a volume, it has no index */
393 if ( _DtHelpGlobSrchCurVolume == srchSource
394 && helpType != DtHELP_TYPE_TOPIC )
395 return False; /* RETURN */
397 /* try to locate file and its entry, if present */
398 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, baseName,
399 _DtHelpFileSuffixList,False,R_OK);
400 if (_DtHelpOpenVolume(path, &vol) == 0 )
402 /* Get the keyword list values */
403 keyWordCount = _DtHelpCeGetKeywordList(vol,&(currentKeyList));
405 /* no need to free currentKeyList because these are mgd by CE */
406 _DtHelpCloseVolume(vol);
410 return (keyWordCount > 0);
415 /************************************************************************
416 * Function: GetVolumeInfoCB()
418 * Get the info on the volume and return it
419 * Any of the 'out' parameters may be NULL.
421 ************************************************************************/
422 static Boolean GetVolumeInfoCB (
423 XtPointer pDisplayArea, /* in: display area in use */
424 char * volumePath, /* in: full path to file */
425 char ** ret_title, /* out: mallocd doc title text string */
426 XmString * ret_titleXmStr,/* out: mallocd doc title string */
427 char ** ret_docId, /* out: mallocd doc Id string */
428 char ** ret_timeStamp, /* out: mallocd doc time string */
429 int * ret_nameKey, /* out: hash value for fast discimination */
430 XmFontList * io_fontList, /* io: fontList for title */
431 Boolean * ret_mod) /* out: has font list been changed */
434 _DtHelpVolumeHdl vol;
435 char * baseName = volumePath; /* no path component */
438 if(_DtHelpCeStrrchr(volumePath, DirSlash, MB_CUR_MAX, &baseName)==0)
442 if ( _DtHelpOpenVolume(volumePath, &vol) != 0 )
443 { /* if can't open, do best possible */
445 *ret_titleXmStr = XmStringCreateLocalized(baseName);
446 if (ret_title) *ret_title= XtNewString(baseName);
447 if (ret_nameKey) *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
451 /** volume is open, now get the data **/
455 char * locTitle = NULL;
457 /* locTitle is owned by caller */
458 _DtHelpGetAsciiVolumeTitle(pDisplayArea, vol, &locTitle);
459 if (locTitle == NULL)
460 locTitle = XtNewString(baseName);
461 *ret_title = locTitle;
466 XmString locTitleXmStr = NULL;
468 /* locTitle is owned by caller */
469 _DtHelpFormatVolumeTitle(pDisplayArea,vol,
470 &locTitleXmStr,io_fontList,ret_mod);
471 if (locTitleXmStr == NULL)
472 locTitleXmStr = XmStringCreateLocalized(baseName);
473 *ret_titleXmStr = locTitleXmStr;
476 if (ret_docId || ret_timeStamp)
478 char * locDocId = NULL;
479 char * locTimeStamp = NULL;
481 /* locDocId & locTimeStamp will point to private memory; do not modify */
482 _DtHelpCeGetDocStamp(vol,&locDocId, &locTimeStamp);
485 *ret_docId = locDocId ? locDocId : XtNewString(&empty);
487 *ret_timeStamp = locTimeStamp?locTimeStamp:XtNewString(&empty);
492 *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
495 _DtHelpCloseVolume(vol);
501 /************************************************************************
502 * Function: AdjustPositionValues()
504 * Adjust the position values of all volumes in the list by the amount given
506 ************************************************************************/
507 static void AdjustPositionValues(
508 _DtHelpFileList fileList,
513 _DtHelpGlobSrchVol * curVol;
515 if ( NULL == fileList
516 || NULL == (curVol = (_DtHelpGlobSrchVol *) fileList->clientData) )
519 /* do we need to find first next file that has hits and is in list? */
520 if(False == adjustThisFile)
522 curVol->nextVolPosition += adjNextAmount;
523 for ( fileList = _DtHelpFileListGetNext(NULL,fileList); /* begin with next */
525 fileList = _DtHelpFileListGetNext(NULL,fileList) )
527 register _DtHelpGlobSrchVol * vol=(_DtHelpGlobSrchVol *)fileList->clientData;
528 if (vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
530 vol->nextVolPosition += adjNextAmount;
532 /* all further files require same adj amts */
533 adjStartAmount = adjNextAmount;
537 /* add in the adjust amount to all files */
538 for ( /* do nothing */;
540 fileList = _DtHelpFileListGetNext(NULL,fileList) )
542 register _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) fileList->clientData;
545 vol->startPosition += adjStartAmount;
546 vol->nextVolPosition += adjNextAmount;
548 /* overwrite, once we've done the first file, if haven't already */
549 adjStartAmount = adjNextAmount;
554 /************************************************************************
555 * Function: HitLoadTopics()
557 * Loads the topics referred to by a hit
558 * Returns: 0 if loaded ok, -1 otherwise
559 ************************************************************************/
560 static int HitLoadTopics (
561 DtHelpDialogWidget hw,
562 _DtHelpFileEntry file,
563 _DtHelpGlobSrchHit * hit)
565 _DtHelpVolumeHdl volHandle;
566 char * * origTopicIdList = NULL;
569 XmString * titlesList = NULL;
570 char * * idList = NULL;
571 char * * fileList = NULL;
572 XmFontList fontList = NULL;
574 Boolean allMods = False;
577 if (hit->topicsLoaded) return 0; /* RETURN: ok */
579 if (_DtHelpOpenVolume(file->fullFilePath, &volHandle) != 0 )
580 return -1; /* RETURN: error */
582 topicCnt = _DtHelpCeFindKeyword(volHandle,hit->indexEntry,&origTopicIdList);
583 if (topicCnt <= 0) return -1; /* RETURN: error */
585 /* get results font list */
586 XtSetArg(args[0], XmNfontList, &fontList);
587 XtGetValues(hw->help_dialog.srch.resultList,args,1);
589 #if defined(DONT_USE_CDExc22774)
590 /* Don't need to copy, _DtHelpFormatVolumeTitle copies
594 /* FIX: check whether this is a memory leak. It isn't if the
595 GetValues of XmFontList returns its own list, not a copy */
596 /* work with copy, because FontListAppendEntry() destroys input FL */
597 fontList = XmFontListCopy(fontList);
600 /* get the titles of all topics */
601 for (i=0; i<topicCnt; i++)
603 XmString titleStr = NULL;
604 Boolean valid = False;
605 XmFontList lastFontList = NULL;
608 * mod==True indicates _DtHelpFormatTopicTitle copied fontList
609 * once already. Save a pointer to it so we can free the font list
610 * if _DtHelpFormatTopicTitle copies it again.
612 lastFontList = fontList;
614 valid = _DtHelpFormatTopicTitle(hw->help_dialog.help.pDisplayArea,
615 volHandle,origTopicIdList[i], &titleStr, &fontList, &mod);
617 if (mod && NULL != lastFontList) XmFontListFree(lastFontList);
619 allMods |= mod; /* track for all iterations */
621 if(valid!=0 || NULL==titleStr)
623 titleStr=XmStringCreateLocalized(origTopicIdList[i]);
624 } /* if couldn't get title */
626 /* note that titleStr is an XmString, not an (Xt) String */
627 titlesList = (XmString *)_DtHelpCeAddPtrToArray (
628 (void **)titlesList, (void *) titleStr);
629 idList = (char **)_DtHelpCeAddPtrToArray (
631 (void *) XtNewString(origTopicIdList[i]));
632 fileList = (char **)_DtHelpCeAddPtrToArray (
634 (void *) XtNewString(file->fullFilePath));
635 } /* for all topics of this index entry */
637 /* install font list, if changed */
640 XtSetArg(args[0], XmNfontList, fontList);
641 XtSetValues(hw->help_dialog.srch.resultList,args,1);
642 if (fontList) XmFontListFree(fontList);
645 /* put results into hit */
646 hit->topicTitles = titlesList;
647 hit->topicIdList = idList;
648 hit->topicFileList = fileList;
649 hit->topicCnt = topicCnt;
650 hit->topicsLoaded = True;
652 _DtHelpCloseVolume(volHandle);
659 /************************************************************************
660 * Function: HitNameDisplay()
662 * Updates the name of the hit, not delete or insert
663 ************************************************************************/
664 static int HitNameDisplay (
665 DtHelpDialogWidget hw,
666 _DtHelpFileEntry file,
667 _DtHelpGlobSrchHit * hit,
672 char * contractPrefix;
674 XmString prefixString;
675 XmString labelString;
679 /* FIX: this method of getting/using the prefixes
680 is a performance nightmare; plus subject to font variability */
681 expandPrefix = (char *)_DTGETMESSAGE (GSSET, 28," +");
682 contractPrefix = (char *)_DTGETMESSAGE (GSSET, 29," -");
683 gotoPrefix = (char *)_DTGETMESSAGE (GSSET, 30," ");
685 /* if more than one topic for this index, signal it */
686 tmpStr = gotoPrefix; /* index entry has one topic */
687 if ( hit->topicCnt > 1 )
689 if (hit->topicsDisplayed) /* topics currently displayed */
690 tmpStr = contractPrefix;
691 else /* topics not displayed */
692 tmpStr = expandPrefix;
693 sprintf(buf, "%s%3d ", tmpStr, hit->topicCnt); /* 4d too spacy */
697 prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
698 XmCHARSET_TEXT, NULL);
699 labelString = XmStringConcat(prefixString,hit->indexTitle);
700 /* recall indexTitle is an XmString in the volume's indexXmStrsList */
702 /* install/insert the item */
704 XmListAddItemUnselected(hw->help_dialog.srch.resultList,
707 XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
708 &labelString,1,hitPos);
710 XmStringFree(prefixString);
711 XmStringFree(labelString);
712 return (insertHit ? 1 : 0);
717 /************************************************************************
718 * Function: HitTopicsDisplay()
720 * Loads the topics referred to by a hit and displays them
721 * Returns the number of topics displayed
722 ************************************************************************/
723 static int HitTopicsDisplay (
724 DtHelpDialogWidget hw,
725 _DtHelpFileEntry file,
726 _DtHelpGlobSrchHit * hit,
727 int firstTopicListPosition)
729 XmString * pTopicString;
730 XmString prefixString;
731 XmString labelString;
736 if ( False == hit->topicsLoaded && HitLoadTopics(hw,file,hit) < 0 )
737 return 0; /* RETURN: error */
738 if ( hit->topicsDisplayed ) return 0; /* RETURN: ok */
741 /*tmpStr = (char *)_DTGETMESSAGE (GSSET, 32," * ");*/
742 tmpStr = (char *)_DTGETMESSAGE (GSSET, 31," ");
743 prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
744 XmCHARSET_TEXT, NULL);
746 if (hit->topicCnt > 0)
748 items = (XmString *) XtMalloc (sizeof (XmString) * hit->topicCnt);
750 /* put XmString-formatted topic titles into list */
751 for (i = 0, pTopicString = hit->topicTitles; NULL != *pTopicString;
752 pTopicString++, i++ )
753 items[i] = XmStringConcat(prefixString,*pTopicString);
755 XmListAddItemsUnselected(hw->help_dialog.srch.resultList, items,
756 hit->topicCnt, firstTopicListPosition);
757 for (i = 0; i < hit->topicCnt; i++)
758 XmStringFree(items[i]);
759 XtFree((char *) items);
762 XmStringFree(prefixString);
765 hit->topicsDisplayed = True;
766 hit->showTopicsWithHit = True;
767 return hit->topicCnt;
773 /************************************************************************
774 * Function: HitTopicsUndisplay()
776 * Releases the topics referred to by a hit and undisplays them
777 * Returns number of topics removed from display and hit.
778 ************************************************************************/
779 static int HitTopicsUndisplay (
780 DtHelpDialogWidget hw,
781 _DtHelpFileEntry file,
782 _DtHelpGlobSrchHit * hit,
783 int firstTopicListPosition)
788 if ( False == hit->topicsDisplayed ) return 0; /* RETURN */
790 XtSetArg(args[0], XmNtopItemPosition, &topPos);
791 XtGetValues(hw->help_dialog.srch.resultList,args,1);
793 /* count the topics -- they are also being collapsed */
794 if (hit->topicCnt > 0)
795 XmListDeleteItemsPos(hw->help_dialog.srch.resultList,
796 hit->topicCnt, firstTopicListPosition);
798 hit->topicsDisplayed = False;
799 /* NOTE: don't reset hit->showTopicsWithHit here; require that
800 to be explicitly reset in ProcessResultSelection() */
802 XmListSetPos(hw->help_dialog.srch.resultList, topPos);
804 return hit->topicCnt;
810 /************************************************************************
811 * Function: HitFree()
813 * Frees the memory associated with a hit and returns the next hit
814 * member of the structure
815 ************************************************************************/
816 static _DtHelpGlobSrchHit * HitFree (
817 _DtHelpGlobSrchHit * hit,
818 Boolean freeHitItself)
821 _DtHelpGlobSrchHit * nextHit;
823 if (NULL == hit) return NULL;
827 /* Free the mem of the topics id list */
828 _DtHelpCeFreeStringArray(hit->topicIdList);
829 hit->topicIdList = NULL; /* mem not owned by me */
831 /* Free the mem of the topics files list */
832 _DtHelpCeFreeStringArray(hit->topicFileList);
833 hit->topicFileList = NULL;
835 /* topicTitles are XmStrings and we can't use FreeStringArray() */
836 for ( nextStr = hit->topicTitles;
837 NULL != nextStr && NULL != *nextStr;
839 XmStringFree (*nextStr);
840 XtFree((char *) hit->topicTitles); /* its an XmString * */
841 hit->topicTitles = NULL;
844 hit->topicsLoaded = False;
845 hit->topicsDisplayed = False;
849 /* Free the index entry */
850 XtFree(hit->indexEntry);
858 /************************************************************************
859 * Function: HitListFree()
861 * Walks along a hit list and frees its contents
862 ************************************************************************/
863 static void HitListFree(
864 _DtHelpGlobSrchVol * vol,
865 Boolean freeHitsThemselves)
867 register _DtHelpGlobSrchHit * hit;
869 if (NULL == vol) return; /* RETURN */
871 for ( hit = vol->hitListHead;
873 hit = HitFree(hit,freeHitsThemselves) )
876 /* reset search flags */
877 vol->nothingDone = True;
878 vol->topicSearchDone = False;
879 vol->indexSearchDone = False;
880 vol->searchCompleted = False;
881 vol->searchedCnt = 0;
882 vol->gatheredFullIndex = False;
884 /* reset hit flags */
885 vol->hitsDisplayed = False;
886 vol->showHitsWithVol = False;
887 vol->zeroHitsOk = False;
890 /* reset list display flags */
891 vol->startPosition = 1;
892 vol->nextVolPosition = 1;
894 /* dont free indexXmStrsList here because they
895 are reused for every search on this volume */
896 vol->curIndexXmStr = vol->indexXmStrsList;
898 /* indexEntriesList,volhandle inited elsewhere */
900 if (freeHitsThemselves)
902 vol->hitListHead = NULL;
903 vol->hitListTail = NULL;
908 /************************************************************************
909 * Function: HitListFreeAllVolHits()
911 * Walks along all the volumes and frees their hits
912 ************************************************************************/
914 HitListFreeAllVolHits (
915 DtHelpDialogWidget hw,
916 Boolean freeFullIndex)
918 _DtHelpGlobSrchVol * vol;
919 _DtHelpFileEntry curFile;
921 /* walk the files, freeing all hits and their data */
922 for ( curFile = hw->help_dialog.srch.volListHead;
924 curFile = _DtHelpFileListGetNext(NULL,curFile) )
926 vol = (_DtHelpGlobSrchVol *) curFile->clientData;
928 if (NULL == vol) continue; /* CONTINUE */
929 if (vol->gatheredFullIndex && freeFullIndex == False) continue;
930 HitListFree(vol,True); /* True: free hits themselves */
932 hw->help_dialog.srch.hitsFound = False;
936 /************************************************************************
937 * Function: HitListGetNth()
939 * Retrieves the Nth entry from the hits contained in the VolList
941 * This code follows the same counting paradigm used when adding
942 * the items to the srchResultList widget, so that we can just use the
943 * position value returned by it to retrieve the selected item.
945 * This paradigm also counts the presence of a volume as an item
946 * if it contains any hits, and doesn't count it if it contains
947 * no hits. It also counts the topicTitles that are associated
948 * with a hit and displayed indented beneath it.
950 * The position count is 1 based, which corresponds with the
954 * ret_hit: retuns NULL if an error or a pointer to the hit structure.
955 * ret_locationId: returns NULL is position is for the hit
956 * structure itself, returns a pointer to private
957 * memory containing the location id if position
958 * is a topic belonging to the hit.
960 * Returns: 0 if ok, -1 if error
961 ************************************************************************/
962 static int HitListGetNth (
963 _DtHelpFileList volListHead,
965 _DtHelpFileEntry * ret_file,
966 _DtHelpGlobSrchHit * * ret_hit,
967 char * * ret_locationId,
968 char * * ret_helpFile)
970 _DtHelpGlobSrchHit * hit = NULL;
971 _DtHelpGlobSrchVol * curVol;
972 _DtHelpFileEntry curFile = NULL;
973 _DtHelpFileEntry posFile = NULL;
974 char * * locationIdList = NULL;
975 char * * fileNameList = NULL;
978 if (NULL == volListHead) goto done; /* GOTO on error */
980 /* walk along the volumes to find the one containing the position
981 Because we need the most recent file with hits before the
982 nextFile that has too high a position, only set posFile when
983 we aren't ready to stop yet and we're on a file with hits. */
984 for ( curFile = volListHead;
986 curFile = _DtHelpFileListGetNext(curFile,curFile) )
988 /* it is impt to use > test so that multiple volumes with the same
989 start position are properly handled. This occurs when they
990 have no hits in them. */
991 curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
992 if (NULL == curVol) continue;
994 if (curVol->startPosition > position) break; /* BREAK */
995 if (curVol->hitCnt > 0) posFile = curFile; /* recent with hits */
997 if (curVol->showVolInList && curVol->nextVolPosition > position)
1004 if(NULL == posFile) goto done; /* GOTO on error */
1006 /*** walk along the hits to find the one matching the position ***/
1007 curVol = (_DtHelpGlobSrchVol *) posFile->clientData;
1008 curPos = curVol->startPosition;
1010 locationIdList = NULL;
1011 fileNameList = NULL;
1013 /* (position == curPos) ==> volume name itself was selected */
1014 if ( curPos < position )
1015 { /* a hit inside the volume */
1016 if ( curVol->hitsDisplayed )
1018 for ( curPos++, hit = curVol->hitListHead;
1019 curPos < position && NULL != hit;
1020 curPos++, hit = hit->next )
1022 if (False == hit->topicsDisplayed) continue; /* CONTINUE */
1024 /* walk all displayed topics to see if the position is here */
1025 for ( locationIdList=hit->topicIdList,fileNameList=hit->topicFileList;
1026 NULL != locationIdList[0];
1027 locationIdList++, fileNameList++ )
1029 /* use GOTO to escape with all pointers correct and
1030 without introducing an additional flag variable */
1031 if (++curPos == position) goto done; /* GOTO */
1032 } /* for all locations of a hit before the position */
1033 } /* for all members of the hit list before the position */
1034 } /* if hits are currently shown */
1035 else posFile = NULL; /* an error occurred */
1036 } /* if position is in the hit list */
1039 if (ret_hit) *ret_hit = hit;
1040 if (ret_file) *ret_file = posFile;
1043 if ( locationIdList ) *ret_locationId = locationIdList[0];
1044 else *ret_locationId = NULL;
1048 if ( fileNameList ) *ret_helpFile = fileNameList[0];
1049 else *ret_helpFile = NULL;
1051 /* WARNING: depends on pointers and integers the same size */
1053 return (NULL == ((ulong_t)hit|(ulong_t)posFile|(ulong_t)locationIdList)) ? -1 : 0;
1055 return (0 == ((int)hit|(int)posFile|(int)locationIdList)) ? -1 : 0;
1061 /************************************************************************
1062 * Function: HitListAddFound()
1064 * Adds a hit to the hit list of the specified volume
1065 * The hits are added either to the end of the list,
1066 * so that the srchResultList presents the items in the order found,
1067 * or in a sorted order.
1068 * If a hit on that topic already exists, just the existing
1069 * hit structure is returned.
1071 * Return Parameters:
1072 * Ret_hit points to the hit data. This is not a copy--do not
1076 * Returns 0 if no error, -1 if an error occurred.
1077 ************************************************************************/
1078 static int HitListAddFound (
1079 _DtHelpFileEntry curFile,
1080 XmString indexTitle,
1082 Boolean insertSorted,
1083 _DtHelpGlobSrchHit **ret_hit)
1085 _DtHelpGlobSrchHit * prev;
1086 _DtHelpGlobSrchHit * next;
1087 _DtHelpGlobSrchHit * srcHit;
1088 _DtHelpGlobSrchVol * vol;
1090 extern _CEStrcollProc _DtHelpCeGetStrcollProc();
1091 _CEStrcollProc strcollfn = _DtHelpCeGetStrcollProc();
1093 if (NULL == curFile) return -1; /* RETURN */
1094 vol = (_DtHelpGlobSrchVol *) curFile->clientData;
1095 if (NULL == vol) return -1; /* RETURN */
1097 /* walk along the hits, looking for one matching the new hit */
1098 /* recall that position is 1-based */
1099 newKey = _DtHelpCeStrHashToKey(indexEntry);
1101 if ( insertSorted ) /* find position and check for duplicates */
1103 /* walk along list */
1104 for( next = vol->hitListHead;
1106 prev = next, next = next->next )
1110 /* do a NLS case insensitive compare using NLS collating */
1111 if ( (ret = (*strcollfn)(next->indexEntry,indexEntry)) >= 0 )
1115 if(ret_hit) *ret_hit = next;
1116 return 0; /* RETURN */
1118 /* prev and next are set correctly */
1123 else /* check for duplicates */
1125 /* walk along list */
1126 for( next = vol->hitListHead;
1128 prev = next, next = next->next )
1130 if ( newKey == next->indexKey /* quick compare */
1131 && strcmp(indexEntry,next->indexEntry) == 0 ) /* long compare */
1133 if(ret_hit) *ret_hit = next;
1134 return 0; /* RETURN */
1137 /* prev and next are set correctly (at end of list) */
1140 /* handle a new hit */
1141 srcHit = (_DtHelpGlobSrchHit *)XtCalloc(1,sizeof(_DtHelpGlobSrchHit));
1142 if (NULL == srcHit) return -1; /* RETURN */
1144 /* init hit values */
1145 /* leave srcHit->hitCnt == 0 here */
1146 if (NULL == indexTitle)
1147 srcHit->indexTitle = XmStringCreateLocalized(indexEntry);
1149 srcHit->indexTitle = indexTitle;
1150 srcHit->indexEntry = XtNewString(indexEntry);
1151 srcHit->indexKey = newKey;
1152 srcHit->volume = curFile;
1154 /* integrate hit into the list */
1155 srcHit->next = next;
1156 if (prev) prev->next = srcHit;
1157 else vol->hitListHead = srcHit;
1158 if (!next) vol->hitListTail = srcHit;
1160 /* add in the volume contribution */
1164 if(ret_hit) *ret_hit = srcHit;
1170 /************************************************************************
1171 * Function: CountSelectedVolumes()
1173 * Counts the number volumes with the searchThisVolume flag set
1174 * for which the search has yet to complete
1176 ************************************************************************/
1177 static int CountSelectedVolumes (
1178 _DtHelpFileList volListHead,
1179 Boolean countSearchCompletedVolumes)
1183 /* walk all volumes */
1184 for ( /* nothing */;
1185 NULL != volListHead;
1186 volListHead = _DtHelpFileListGetNext(NULL, volListHead) )
1188 register _DtHelpGlobSrchVol * vol;
1190 /* get the volume info */
1191 vol = (_DtHelpGlobSrchVol *) volListHead->clientData;
1192 /* if (NULL != vol && vol->searchThisVolume && False == vol->searchCompleted)*/
1193 if (vol && vol->searchThisVolume)
1195 if ( (False == vol->searchCompleted)
1196 || (countSearchCompletedVolumes && vol->searchCompleted) )
1199 } /* walk all volumes */
1205 /************************************************************************
1206 * Function: GetNextSearchFileAndDisplayCompleted()
1208 * Scans list for next file ready for searching
1209 * If it encounters a file that has completed it's search
1210 * and for which the results should be displayed, they are displayed
1212 ************************************************************************/
1213 static _DtHelpFileEntry GetNextSearchFileAndDisplayCompleted(
1214 DtHelpDialogWidget hw,
1215 _DtHelpFileList listHead,
1216 _DtHelpFileEntry curFile)
1218 /* get first file needing work */
1219 for ( curFile = _DtHelpFileListGetNext(listHead, curFile);
1221 curFile = _DtHelpFileListGetNext(NULL, curFile) )
1223 register _DtHelpGlobSrchVol * vol;
1225 vol = (_DtHelpGlobSrchVol *) curFile->clientData;
1226 if (NULL == vol) continue; /* CONTINUE */
1228 /* if file already searched and should be displayed, then do so */
1229 if ( vol->searchThisVolume && vol->searchCompleted
1230 && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
1232 /* record that a hit found */
1233 if ( vol->hitCnt > 0
1234 || ( vol->zeroHitsOk
1235 && _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
1236 hw->help_dialog.srch.hitsFound = True;
1238 /* True: adjust count beginning with this file */
1239 AdjustPositionValues(curFile,0,1,True);
1240 ResultsListUpdate(hw,curFile);
1242 /* display the hits as well? */
1243 if ( vol->showHitsWithVol
1244 || hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
1246 VolHitsDisplay(hw,curFile);
1248 /* update the volume label to show state; False--dont insert */
1249 VolNameDisplay(hw,curFile,False);
1253 /* if want to search, and need to, then return it */
1254 if ( vol->searchThisVolume && False == vol->searchCompleted
1255 && vol->showVolInList ) /* don' search unless results will be shown */
1259 XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
1265 /************************************************************************
1266 * Function: AddVolInfoToFile
1268 * Creates a volume info entry for each member of the list
1269 * and initializes its values
1270 * If searchStatus is False, all volumes are set. If its True,
1271 * all are set if selectedFilesOnly is false, otherwise only
1272 * selected files are set to true.
1274 ************************************************************************/
1275 static void AddVolInfoToFile(
1276 _DtHelpFileEntry file,
1277 Boolean initialSearchStatus,
1278 Boolean displayStatus,
1279 Boolean selectedFilesOnly)
1281 _DtHelpGlobSrchVol * vol;
1283 if (NULL == file) return; /* RETURN */
1285 vol = (_DtHelpGlobSrchVol *) file->clientData;
1288 vol = (_DtHelpGlobSrchVol *) XtCalloc(1,sizeof(_DtHelpGlobSrchVol));
1289 file->clientData = (XtPointer) vol;
1290 if (NULL == vol) return; /* RETURN: memory alloc error */
1292 /* calloc() inited almost everything inside to 0 */
1293 /* set first time creation values */
1294 vol->nothingDone = True;
1297 /* now set search and display flags */
1298 vol->searchThisVolume = initialSearchStatus;
1299 vol->showVolInList = displayStatus;
1300 if ( False == file->fileSelected && True == selectedFilesOnly )
1302 vol->searchThisVolume = False;
1303 vol->showVolInList = False;
1308 /************************************************************************
1309 * Function: AddVolInfoToList
1311 * Creates a volume info entry for each member of the list
1312 * and initializes its values
1313 * If searchStatus is False, all volumes are set. If its True,
1314 * all are set if selectedFilesOnly is false, otherwise only
1315 * selected files are set to true.
1317 ************************************************************************/
1318 static void AddVolInfoToList(
1319 _DtHelpFileList listHead,
1320 Boolean initialSearchStatus,
1321 Boolean displayStatus,
1322 Boolean selectedFilesOnly)
1324 /* walk the files and allocate the vol info as needed */
1327 listHead = _DtHelpFileListGetNext(listHead,listHead) )
1329 AddVolInfoToFile(listHead,
1330 initialSearchStatus, displayStatus, selectedFilesOnly);
1336 /************************************************************************
1337 * Function: SetVolStatus()
1339 * Sets all volumes in the list to the specified search and/or display
1342 * If searchThisVolume is False, all volumes are set. If its True,
1343 * all are set if selectedFilesOnly is false, otherwise only
1344 * selected files are set to true. If searchThisVolume is False,
1345 * then the settings remain unchanged in all volumes.
1347 ************************************************************************/
1348 static void SetVolStatus(
1349 _DtHelpFileList listHead,
1350 Boolean searchThisVolume,
1351 Boolean showVolInList,
1353 Boolean selectedFilesOnly)
1355 /* walk the files and set the status */
1358 listHead = _DtHelpFileListGetNext(listHead,listHead) )
1360 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
1362 if (NULL == vol) continue;
1364 if ( (False == selectedFilesOnly)
1365 || (True == listHead->fileSelected && True == selectedFilesOnly) )
1367 /* just set the inclusion and/or display flags;
1368 don't reset the search progress flags */
1369 vol->searchThisVolume = searchThisVolume;
1370 vol->showVolInList = showVolInList;
1371 vol->zeroHitsOk = zeroHitsOk;
1377 /************************************************************************
1378 * Function: VolNameDisplay()
1380 * Updates the display of the volume name
1381 ************************************************************************/
1382 static void VolNameDisplay(
1383 DtHelpDialogWidget hw,
1384 _DtHelpFileEntry file,
1387 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
1388 XmString prefixString;
1389 XmString labelString;
1393 if ( NULL == vol || (False == vol->zeroHitsOk && 0 == vol->hitCnt) )
1394 return; /* RETURN */
1396 /* put volume name into list */
1397 if (vol->hitCnt <= 0) tmpStr = (char *)_DTGETMESSAGE (GSSET, 25," ");
1398 else if (vol->hitsDisplayed) tmpStr = (char *)_DTGETMESSAGE (GSSET, 27,"-");
1399 else tmpStr = (char *)_DTGETMESSAGE (GSSET, 26,"+"); /* >0 hits */
1400 sprintf(buf, "%s%3d ", tmpStr, vol->hitCnt); /* 4d too spacy */
1403 prefixString = XmStringGenerate(buf, s_PrefixFontListTag,
1404 XmCHARSET_TEXT, NULL);
1405 labelString = XmStringConcat(prefixString,file->fileTitleXmStr);
1407 /* replace or insert to reflect changed contents */
1409 XmListAddItemUnselected(hw->help_dialog.srch.resultList,
1410 labelString, vol->startPosition);
1412 XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
1413 &labelString, 1, vol->startPosition);
1415 XmStringFree(prefixString);
1416 XmStringFree(labelString);
1420 /************************************************************************
1421 * Function: VolHitsDisplay()
1423 * displays the hits associated with a volume
1424 * Returns the number of new items added to the list
1425 ************************************************************************/
1426 static int VolHitsDisplay (
1427 DtHelpDialogWidget hw,
1428 _DtHelpFileEntry file)
1430 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
1431 _DtHelpGlobSrchHit * hit;
1432 int listPos = vol->startPosition; /* vol item position */
1435 if (True == vol->hitsDisplayed ) return 0; /* RETURN */
1437 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1438 if (hw->help_dialog.srch.selectionDlg)
1439 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1441 /*** walk through the hits and count and display any open hits ***/
1442 for ( hit = vol->hitListHead, itemCnt = 0;
1446 itemCnt++; /* True: insert Hit into list */
1447 HitNameDisplay (hw,file,hit,listPos + itemCnt,True);
1449 /* display topics too? */
1450 if (hit->showTopicsWithHit)
1453 newItems = HitTopicsDisplay(hw,file,hit, listPos + itemCnt + 1);
1454 HitNameDisplay (hw,file,hit,listPos + itemCnt,False);
1455 itemCnt += newItems;
1460 vol->hitsDisplayed = True;
1461 vol->showHitsWithVol = True;
1463 /* adjust count beginning with next file with hits */
1464 AdjustPositionValues(file, 0, itemCnt, True);
1466 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1467 if (hw->help_dialog.srch.selectionDlg)
1468 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1475 /************************************************************************
1476 * Function: VolHitsUndisplay()
1478 * undisplays the hits associated with a volume
1479 ************************************************************************/
1480 static int VolHitsUndisplay (
1481 DtHelpDialogWidget hw,
1482 _DtHelpFileEntry file)
1484 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
1485 _DtHelpGlobSrchHit * hit;
1486 Boolean nonVisibleItems;
1487 int listPos = vol->startPosition; /* vol item position */
1496 if (False == vol->hitsDisplayed) return 0; /* RETURN */
1498 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1499 if (hw->help_dialog.srch.selectionDlg)
1500 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1502 XtSetArg(args[0], XmNtopItemPosition, &topPos);
1503 XtSetArg(args[1], XmNvisibleItemCount, &visItemCnt);
1504 XtGetValues(hw->help_dialog.srch.resultList,args,2);
1506 /* these are the num visible items below the volume name */
1507 topNonVisPos = topPos + visItemCnt; /* 1st non vis pos */
1509 /* num of items that will be undisplayed */
1510 undisItemCnt = vol->nextVolPosition - (vol->startPosition + 1);
1512 /* find out if any items aren't visible */
1513 nonVisibleItems = False;
1514 if ( vol->nextVolPosition > topNonVisPos )
1515 nonVisibleItems = True;
1517 /*** walk through the hits and count and delete any open topics ***/
1518 /* Make two passes: the first pass deletes all non-visible
1519 items. The second pass deletes the remaining visible items.
1520 The objective is to make collapse as fast and smooth as expand. */
1521 if (nonVisibleItems)
1522 { /* delete all items with a position > topNonVisPos */
1523 curDelPos = listPos + 1; /* starting position */
1524 for ( hit = vol->hitListHead, itemCnt = 0;
1528 /* are we still in the visible region? */
1529 if (curDelPos < topNonVisPos)
1531 /* move down the list to next hit */
1532 curDelPos++; /* this hit's item */
1533 /* plus any open topics */
1534 if (hit->topicsDisplayed) curDelPos += hit->topicCnt;
1535 continue; /* CONTINUE */
1537 /* we're in non-visible region--undisplay hit */
1538 XmListDeletePos(hw->help_dialog.srch.resultList, curDelPos);
1539 /* undisplay any topics */
1540 if ( hit->topicsDisplayed )
1541 itemCnt += HitTopicsUndisplay(hw,file,hit,curDelPos);
1543 } /* if non visible items */
1545 /* now delete the remaining visible items */
1546 /* Note that curDelPos is a virtual cursor that helps us
1547 figure out when to stop undisplaying. Virtually, we''re
1548 moving the cursor down the list with every delete. Actually,
1549 the rest of the list bumps up one--that''s why we delete
1552 curDelPos = listPos + 1; /* starting position */
1553 for ( hit = vol->hitListHead, itemCnt = 0;
1554 (NULL != hit) && (curDelPos < topNonVisPos);
1557 curDelPos++; /* undisplay hit item */
1558 XmListDeletePos(hw->help_dialog.srch.resultList, listPos + 1);
1559 /* undipslay any open topics */
1560 if ( hit->topicsDisplayed )
1562 curDelPos += HitTopicsUndisplay(hw,file,hit,listPos + 1);
1563 XmListSetPos(hw->help_dialog.srch.resultList, topPos);
1568 vol->hitsDisplayed = False;
1569 /* NOTE: don't reset vol->showHitsWithVol here; require that
1570 to be explicitly reset in ProcessResultSelection() */
1572 /* adjust count beginning with next file with hits */
1573 AdjustPositionValues(file, 0, -undisItemCnt, True);
1575 XmListSetPos(hw->help_dialog.srch.resultList, topPos);
1577 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1578 if (hw->help_dialog.srch.selectionDlg)
1579 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1581 return undisItemCnt;
1586 /************************************************************************
1587 * Function: VolListFree()
1589 * Releases all memory used by the volume list
1591 ************************************************************************/
1592 static void VolListFree (
1593 _DtHelpGlobSearchStuff * srch)
1595 _DtHelpFileList nextFile;
1597 /* walk all volumes */
1598 nextFile = srch->volListHead;
1599 while ( NULL != nextFile )
1601 _DtHelpGlobSrchVol * vol;
1602 _DtHelpFileList tmpFile;
1605 /* get the volume info */
1606 vol = (_DtHelpGlobSrchVol *) nextFile->clientData;
1608 /** free vol entry contents and container **/
1609 XtFree(vol->stdLocale);
1610 XtFree(vol->iconv3Codeset);
1611 HitListFree(vol,True); /* True: free hits themselves */
1613 /* no need to free indexEntriesList because these aren't owned by vol */
1614 vol->indexEntriesList = NULL;
1616 /* free indexXmStrsList */
1617 /* indexXmStrs are XmStrings and we can't use FreeStringArray() */
1618 for ( nextStr = vol->indexXmStrsList;
1619 NULL != nextStr && NULL != *nextStr;
1621 XmStringFree (*nextStr);
1622 XtFree((char *) vol->indexXmStrsList); /* its a XmString * */
1623 vol->indexXmStrsList = NULL;
1626 nextFile = _DtHelpFileListGetNext(NULL, nextFile);
1627 _DtHelpFileFreeEntry(tmpFile); /* also frees the clientData (vol) */
1628 } /* walk all volumes */
1630 /* reset related values */
1631 srch->volListHead = NULL;
1632 srch->curSrchVol = NULL;
1633 srch->volLeftCnt = 0;
1635 /* delete the results */
1636 DeleteListContents(srch);
1641 /************************************************************************
1642 * Function: ScanStatusCB
1644 * Updates the status display with the number of volumes found
1645 * as the scan progresses
1647 ************************************************************************/
1648 static void ScanStatusCB(
1650 XtPointer clientData)
1652 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
1654 StatusLabelUpdate(hw,SCANNING_STATUS,True,count);
1658 /************************************************************************
1659 * Function: VolListBuild
1661 * Frees the old list and builds a new one by scanning the
1662 * help directories for volumes and adding the associated
1663 * volume information used for searching.
1665 ************************************************************************/
1666 static void VolListBuild(
1667 DtHelpDialogWidget hw,
1668 Boolean searchStatus,
1669 Boolean displayStatus,
1670 Boolean selectedVolumesOnly)
1673 XmFontList origFontList;
1675 /* turn on hour glass */
1676 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1677 if (hw->help_dialog.srch.selectionDlg)
1678 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1680 StatusLabelUpdate(hw,SCANNING_STATUS,True,0);
1682 origFontList = hw->help_dialog.srch.volTitlesFontList;
1684 /* and rescan the volumes for the new list */
1685 _DtHelpFileListScanPaths( &hw->help_dialog.srch.volListHead,
1686 &hw->help_dialog.srch.volTitlesFontList,&mod,
1687 DtHelpVOLUME_TYPE, _DtHelpFileSuffixList, False,
1688 GetVolumeInfoCB,hw->help_dialog.help.pDisplayArea,
1689 /* sysPathCompare */ _DtHELP_FILE_NAME,
1690 /*otherPathCompare*/ _DtHELP_FILE_NAME|_DtHELP_FILE_TIME| _DtHELP_FILE_IDSTR,
1691 /* sortBy */ _DtHELP_FILE_TITLE, ScanStatusCB, (XtPointer)hw);
1693 /* if new fonts added to list, add them to the resultList */
1696 MergeFontListIntoWidgetFonts(
1697 hw->help_dialog.srch.resultList,
1698 hw->help_dialog.srch.volTitlesFontList);
1700 if (origFontList) XmFontListFree(origFontList);
1703 /* Add on the Vol info and (T,F) allow search on all volumes */
1704 AddVolInfoToList(hw->help_dialog.srch.volListHead,
1705 searchStatus, displayStatus, selectedVolumesOnly);
1707 hw->help_dialog.srch.volScanDone = True;
1709 StatusLabelUpdate(hw,BLANK_STATUS,True,0);
1711 /* turn off hour glass */
1712 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1713 if (hw->help_dialog.srch.selectionDlg)
1714 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1719 #if 0 || defined(DEBUG) /* for debug, set to 1 */
1720 /************************************************************************
1721 * Function: OutputVolInfo()
1723 * Output info on all volumes in the list
1725 ************************************************************************/
1726 static void OutputVolInfo(
1727 _DtHelpFileList listHead)
1731 listHead = _DtHelpFileListGetNext(listHead,listHead) )
1733 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
1734 if (NULL == vol) continue;
1736 /* output the info */
1737 printf("==================\n");
1738 printf("fileName: %s, %s\npathName: %s\n",
1739 listHead->fileName, listHead->fileTitle, listHead->fullFilePath);
1740 printf("searchThisVolume = %d, hitCnt = %d, startPos = %d\n",
1741 (int) listHead->fileSelected,
1743 (int) vol->startPosition);
1749 /************************************************************************
1750 * Function: SearchContinuePossible()
1752 * Test whether the search can be continued from the
1755 ************************************************************************/
1756 static Boolean SearchContinuePossible(
1757 DtHelpDialogWidget hw,
1760 char * normSrchWord;
1761 Boolean possible = False;
1763 normSrchWord = XtNewString(srchWord);
1764 _DtHelpCeCompressSpace(normSrchWord);
1765 _DtHelpCeUpperCase(normSrchWord);
1767 /* are we searching on the same word as previous search ? */
1768 /* comparison with srchNormWordStr is correct, given calls to this fn */
1769 /* FIX: use CheckSearchWord()? */
1770 if ( ( hw->help_dialog.srch.fullIndex
1771 || ( NULL != hw->help_dialog.srch.normWordStr
1772 && NULL != normSrchWord
1773 && strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
1774 && NULL != hw->help_dialog.srch.volListHead
1775 && hw->help_dialog.srch.volLeftCnt > 0 )
1778 XtFree(normSrchWord);
1784 /************************************************************************
1785 * Function: SearchOnSameCriteria()
1787 * Test whether the search criteria have changed
1789 ************************************************************************/
1790 static Boolean SearchOnSameCriteria(
1791 DtHelpDialogWidget hw,
1794 char * normSrchWord;
1795 Boolean sameCrit = False;
1797 normSrchWord = XtNewString(srchWord);
1798 _DtHelpCeCompressSpace(normSrchWord);
1799 _DtHelpCeUpperCase(normSrchWord);
1801 /* are we searching on the same word as previous search ? */
1802 /* comparison with srchNormWordStr is correct, given calls to this fn */
1803 if ( hw->help_dialog.srch.fullIndex
1804 || ( NULL != hw->help_dialog.srch.normWordStr
1805 && NULL != normSrchWord
1806 && strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
1809 XtFree(normSrchWord);
1812 #endif /* not_used */
1817 /************************************************************************
1818 * Function: UpdateActionButtonLabel()
1820 * Sets the start button label properly
1822 ************************************************************************/
1823 static void UpdateActionButtonLabel(
1824 DtHelpDialogWidget hw,
1826 Boolean startContAction)
1829 XmString labelString;
1830 XmString curLabelString;
1832 /* char * mnemonic; */
1834 /* if action label is to start or continue */
1835 _DtHelpProcessLock();
1836 if (startContAction)
1838 if ( SearchContinuePossible(hw,srchWord) )
1839 { /* then continue search */
1840 textString=(char *)_DTGETMESSAGE (GSSET,
1841 CONT_SEARCH_CAT,CONT_SEARCH_STR);
1842 labelString = XmStringCreateLocalized(textString);
1843 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 22,CONT_SEARCH_MNEM));*/
1846 { /* otherwise start it */
1847 textString=(char *)_DTGETMESSAGE (GSSET,
1848 START_SEARCH_CAT,START_SEARCH_STR);
1849 labelString = XmStringCreateLocalized(textString);
1850 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
1853 else /* action label is to stop */
1855 textString = (char *)_DTGETMESSAGE (GSSET,
1856 STOP_SEARCH_CAT,STOP_SEARCH_STR);
1857 labelString = XmStringCreateLocalized(textString);
1858 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, ??,STOP_SEARCH_MNEM));*/
1860 _DtHelpProcessUnlock();
1862 /* get the current state of the button */
1863 XtSetArg(args[0],XmNlabelString,&curLabelString);
1864 XtGetValues (hw->help_dialog.srch.actionBtn, args, 1);
1866 /* update label if it is different; avoid flashing this way */
1867 if ( XmStringCompare(labelString,curLabelString) == False )
1869 XtSetArg(args[0],XmNlabelString,labelString);
1870 XtSetArg(args[1], XmNalignment, XmALIGNMENT_CENTER);
1871 /* XtSetArg(args[2], XmNmnemonic, mnemonic[0]);*/
1872 XtSetValues (hw->help_dialog.srch.actionBtn, args, 2);
1873 XmUpdateDisplay(hw->help_dialog.srch.actionBtn);
1876 /* release the memory */
1877 XmStringFree(labelString);
1878 XmStringFree(curLabelString);
1882 /*****************************************************************************
1883 * Function: CheckSearchWord()
1887 * Return Value: True: word has changed
1888 * False: word is same
1890 * Purpose: Checks whether the search word is a new
1891 * one or the same as before. If the same, it frees
1892 * the word and returns False. If new, it moves the
1893 * previous word to another variable and installs
1894 * the new word in its place, using the srchWord mem.
1895 * ...but only if updateWidgetFields is True
1897 *****************************************************************************/
1898 static Boolean CheckSearchWord(
1899 DtHelpDialogWidget hw,
1901 Boolean updateWidgetFields)
1906 /* avoid a core dump */
1907 if ( NULL == srchWord )
1909 if ( NULL == hw->help_dialog.srch.normWordStr
1910 || hw->help_dialog.srch.normWordStr[0] == 0)
1911 return False; /* word hasn't changed */
1912 return True; /* RETURN: word has changed */
1915 _DtHelpCeCompressSpace(srchWord);
1916 rawSrchWord = XtNewString(srchWord);
1917 _DtHelpCeUpperCase(srchWord);
1918 /* FIX: to support regcomp(3), do that here */
1920 /* are we searching on the same word? */
1921 if ( NULL != hw->help_dialog.srch.normWordStr
1922 && strcmp(srchWord, hw->help_dialog.srch.normWordStr) == 0 )
1925 XtFree(rawSrchWord);
1927 /* output a message */
1928 if ( NULL != hw->help_dialog.srch.normWordStr
1929 && EOS != hw->help_dialog.srch.normWordStr[0])
1930 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
1933 return False; /* RETURN: no change */
1936 if (False == updateWidgetFields) return True; /* RETURN */
1938 /* update search word fields */
1939 XtFree(hw->help_dialog.srch.normWordStr);
1940 XtFree(hw->help_dialog.srch.rawWordStr);
1941 hw->help_dialog.srch.normWordStr = srchWord;
1942 hw->help_dialog.srch.rawWordStr = rawSrchWord;
1943 hw->help_dialog.srch.wordFieldLen = strlen(srchWord); /* note: not nl_strlen
1944 because used on strncmp not nl_strncmp */
1946 /* convert first char to a value for easy access for _DtHelpStrchr() */
1947 if ( mbtowc(&firstChar,srchWord,1) <= 0 ) firstChar = 0;
1948 hw->help_dialog.srch.wordFieldFirstChar = firstChar;
1950 /* output a message */
1951 if ( NULL != hw->help_dialog.srch.normWordStr
1952 && EOS != hw->help_dialog.srch.normWordStr[0])
1953 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
1955 return True; /* word changed */
1960 /*****************************************************************************
1961 * Function: PrepSearchSourceData()
1965 * Return Value: Void.
1967 * Purpose: Based on the current settings of the volume
1968 * selection buttons construct or utilitize an
1969 * existing volume list for processing.
1970 * Determine whether to continue search or
1971 * restart by comparing search words and states.
1973 *****************************************************************************/
1974 static void PrepSearchSourceData(
1975 DtHelpDialogWidget hw,
1978 /* try to install the new word; if returns False, word is same
1979 as before. True = also update widget fields. */
1980 /* This test determines whether we might need to continue. */
1981 if ( hw->help_dialog.srch.fullIndex
1982 || CheckSearchWord(hw,srchWord,True) == False )
1984 /* check to see if CheckSearchWord() was called. If it wasn't
1985 then srchWord has not been freed or saved. We will lose the
1986 memory unless we free it here. */
1987 if (hw->help_dialog.srch.fullIndex)
1990 /* are we continuing an interrupted search? */
1991 if ( hw->help_dialog.srch.volLeftCnt > 0
1992 && NULL != hw->help_dialog.srch.volListHead )
1993 return; /* RETURN: continue with search */
1995 /* if searching full index, False=dont free vol with full index */
1996 if (hw->help_dialog.srch.fullIndex)
1997 HitListFreeAllVolHits(hw,False);
1998 /* else we're searching on the same word, but completed
1999 previous search. So reset the volumes to search/display
2000 according to the current settings of the Volumes radio buttons,
2001 but leave the results intact.
2003 /* fall thru to do prep */
2005 else /* searching for a different word */
2007 /* free all hit-related data and reset flags */
2008 HitListFreeAllVolHits(hw,True); /*True=free everything*/
2011 /*** It's not just a continue. So, we may be beginning a new search
2012 or continuing a search based on new volume selection params ***/
2014 /* update display area */
2015 DeleteListContents(&hw->help_dialog.srch);
2016 StatusLabelUpdate(hw,WORKING_STATUS,False,0);
2018 /*** update the volumes list according to sources selected ***/
2019 if ( _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources )
2021 /* volume list already built when opening selection dialog */
2022 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
2023 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
2024 /* (T,T,T,T): enable search, enable display,
2025 zero hits ok, only for selected volumes */
2026 SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
2027 } /* if selected volumes button */
2028 else if ( _DtHelpGlobSrchAllVolumes == hw->help_dialog.srch.srchSources )
2030 /* Scan directories for volumes if necessary */
2031 if ( False == hw->help_dialog.srch.volScanDone
2032 || NULL == hw->help_dialog.srch.volListHead)
2034 /* Add on the Vol info; (T,T,F) search, display, all */
2035 VolListBuild(hw,True,True,False);
2038 /* (T,T,F,F): enable search,enable display,no 0 hits,for all vols */
2039 SetVolStatus(hw->help_dialog.srch.volListHead,True,True,False,False);
2040 } /* if all volumes button */
2041 else /*** current volume button ***/
2044 _DtHelpFileEntry cur;
2046 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
2047 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
2049 /* try to locate file and its entry, if present */
2050 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
2051 _DtHelpFileSuffixList,False,R_OK);
2052 cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
2053 GetVolumeInfoCB, _DtHELP_FILE_NAME,
2054 hw->help_dialog.help.pDisplayArea);
2056 if (NULL == cur && NULL != path) /*file was located but isn't in list*/
2057 { /* add it to the list */
2059 XmFontList origFontList;
2061 origFontList = hw->help_dialog.srch.volTitlesFontList;
2063 _DtHelpFileListAddFile(&hw->help_dialog.srch.volListHead,
2064 &hw->help_dialog.srch.volTitlesFontList,&mod,path,NULL,
2065 GetVolumeInfoCB, _DtHELP_FILE_NAME, _DtHELP_FILE_TITLE,
2066 hw->help_dialog.help.pDisplayArea);
2069 MergeFontListIntoWidgetFonts(
2070 hw->help_dialog.srch.resultList,
2071 hw->help_dialog.srch.volTitlesFontList);
2073 if (origFontList) XmFontListFree(origFontList);
2076 /* (F,F,F): disable search, disable display, for all volumes */
2077 AddVolInfoToList(hw->help_dialog.srch.volListHead,False,False,False);
2078 cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
2079 GetVolumeInfoCB, _DtHELP_FILE_NAME,
2080 hw->help_dialog.help.pDisplayArea);
2083 if (cur) /* file present in list */
2085 /* enable search and display on this volume */
2086 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) cur->clientData;
2088 vol->searchThisVolume = True;
2089 vol->showVolInList = True;
2090 vol->zeroHitsOk = True; /* show zero hits for search of cur vol */
2092 else /* file not found */
2094 /* FIX: put up error dialog and disable the button */
2095 /*printf("Current volume %s not found\n",
2096 hw->help_dialog.display.helpVolume);*/
2097 } /* if file found */
2099 XtFree(path); /* tests for NULL */
2100 } /* if selected/all/cur volumes sources */
2102 #if 0 || defined(DEBUG) /* for debug, set to 1 */
2103 OutputVolInfo(hw->help_dialog.srch.volListHead);
2106 /* get num volumes to process */
2107 hw->help_dialog.srch.volLeftCnt =
2108 CountSelectedVolumes(hw->help_dialog.srch.volListHead,True);
2110 /* empty the results list */
2111 XmUpdateDisplay(hw->help_dialog.srch.resultList);
2115 /************************************************************************
2116 * Function: CloseSearchCB()
2118 * Close the Global Search Dialog
2120 ************************************************************************/
2121 static void CloseSearchCB (
2123 XtPointer clientData,
2126 _DtHelpGlobSearchStuff * srch = (_DtHelpGlobSearchStuff *) clientData;
2128 /* stop any work proc */
2129 if(srch->workProcId)
2131 XtRemoveWorkProc(srch->workProcId);
2132 srch->workProcId = 0;
2135 /* unmanage the srchForm dialog but dont destroy it */
2136 if (NULL != srch->srchForm)
2138 XtUnmanageChild(srch->srchForm);
2139 XtUnmapWidget(srch->srchForm);
2144 /*****************************************************************************
2145 * Function: void DeleteListContents()
2149 * Return Value: Void.
2151 * Purpose: empties list and resets position values
2153 *****************************************************************************/
2154 static void DeleteListContents(
2155 _DtHelpGlobSearchStuff * srch)
2157 _DtHelpFileEntry curFile;
2159 if (NULL != srch->resultList)
2160 XmListDeleteAllItems(srch->resultList);
2162 for ( curFile = srch->volListHead;
2164 curFile = _DtHelpFileListGetNext(NULL,curFile) )
2166 register _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) curFile->clientData;
2167 if (NULL == vol) continue; /* CONTINUE */
2169 /* if any hits are displayed and any have open topics,
2170 walk through and close them */
2171 if ( vol->hitsDisplayed
2172 && ((vol->nextVolPosition - vol->startPosition) != vol->hitCnt) )
2174 register _DtHelpGlobSrchHit * hit;
2175 for ( hit = vol->hitListHead;
2179 hit->topicsDisplayed = False;
2183 vol->startPosition = 1;
2184 vol->nextVolPosition = 1;
2185 vol->hitsDisplayed = False;
2190 /*****************************************************************************
2191 * Function: void StatusLabelUpdate()
2195 * Return Value: Void.
2197 * Purpose: Installs proper label over results list
2199 *****************************************************************************/
2200 static void StatusLabelUpdate(
2201 DtHelpDialogWidget hw,
2202 ResultsStatus status,
2203 Boolean forceUpdate,
2207 XmString labelString;
2208 XmString curLabelString;
2213 /* only update if necessary */
2214 if (status == hw->help_dialog.srch.statusLineUsage && !forceUpdate)
2218 /* order up the right message */
2219 hw->help_dialog.srch.statusLineUsage = status;
2222 case SCANNING_STATUS:
2223 labelMsg = (char *)_DTGETMESSAGE(GSSET, 17,"Scanning for volumes... Found %d");
2224 sprintf(buf,labelMsg,intArg);
2227 case WORKING_STATUS:
2228 labelMsg = (char *)_DTGETMESSAGE(GSSET, 18,
2229 "Searching... Volumes remaining: %d");
2230 /* we need +1 because of when this message is used */
2231 sprintf(buf,labelMsg,hw->help_dialog.srch.volLeftCnt + 1);
2234 case SEARCH_RESULTS_STATUS:
2235 /* if no hits found */
2236 if (hw->help_dialog.srch.hitsFound == False) /*dont use == True*/
2238 if (hw->help_dialog.srch.fullIndex)
2240 if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchAllVolumes)
2241 labelMsg = (char *)_DTGETMESSAGE (GSSET,19,
2242 "No index entries found.");
2244 labelMsg = (char *)_DTGETMESSAGE (GSSET,50,
2245 "No index entries found. Try All Volumes.");
2247 else /* searched on a pattern */
2249 labelMsg = (char *)_DTGETMESSAGE (GSSET,51,
2250 "No index entries found. Try another word.");
2252 /* change focus to the search word. Traversal is ignored
2253 if srchWord is desensitized (Contains btn not selected) */
2255 if (XtIsSensitive(hw->help_dialog.srch.wordField))
2258 * make sure the text field is editable before sending
2259 * the traversal there.
2261 XtSetArg(args[0],XmNeditable,True);
2262 XtSetValues(hw->help_dialog.srch.wordField, args, 1);
2264 (hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
2268 (hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
2271 else /* if hits found */
2273 /* select the appropriate message */
2274 if (hw->help_dialog.srch.fullIndex)
2276 labelMsg = (char *)_DTGETMESSAGE(GSSET, 20,"Complete Index");
2281 labelMsg = (char *)_DTGETMESSAGE(GSSET, 21,"Entries with \"%s\"");
2282 sprintf(buf,labelMsg,hw->help_dialog.srch.rawWordStr);
2286 /* change focus to the results list */
2288 hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
2291 } /* if no hits found else */
2295 labelMsg = (char *)_DTGETMESSAGE (GSSET, 22,"No volumes selected");
2297 case FIRST_PROMPT_STATUS:
2298 labelMsg = (char *)_DTGETMESSAGE(GSSET,23,"Select search options above");
2302 /* DBG: when an empty string, form constraints are wrong; make a space */
2307 /* make a label string */
2308 labelString = XmStringCreateLocalized(labelMsg);
2310 /* get the current string of the label */
2311 curLabelString = NULL;
2312 XtSetArg(args[0],XmNlabelString,&curLabelString);
2313 XtGetValues (hw->help_dialog.srch.statusLabel, args, 1);
2315 /* update label if it is different; avoid flashing this way */
2316 if ( NULL != curLabelString && NULL != labelString
2317 && XmStringCompare(labelString,curLabelString) == False )
2319 /* update msg over results list */
2320 XtSetArg(args[0],XmNlabelString,labelString);
2321 XtSetValues(hw->help_dialog.srch.statusLabel,args,1);
2324 XmStringFree(labelString);
2325 XmStringFree(curLabelString);
2327 XmUpdateDisplay(hw->help_dialog.srch.statusLabel);
2333 /*****************************************************************************
2334 * Function: void ResultsListUpdate()
2338 * Return Value: Void.
2340 * Purpose: empty list and display results status message
2342 *****************************************************************************/
2343 static void ResultsListUpdate(
2344 DtHelpDialogWidget hw,
2345 _DtHelpFileEntry newFile)
2347 _DtHelpFileEntry testFile;
2349 /* check that in fact, there are no results that will be overwritten */
2350 for ( testFile = hw->help_dialog.srch.volListHead;
2352 testFile = _DtHelpFileListGetNext(NULL,testFile) )
2354 register _DtHelpGlobSrchVol * vol;
2355 vol = (_DtHelpGlobSrchVol *)testFile->clientData;
2356 if (vol && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk))
2360 /* clean the list out if this is the first new result */
2361 /* this presumes that files are processed in order in the list */
2362 if (testFile == newFile)
2364 DeleteListContents(&hw->help_dialog.srch);
2365 AdjustPositionValues(newFile,0,1,True);
2367 /* True: insert new item */
2368 VolNameDisplay(hw,newFile,True);
2370 /* Update status label */
2371 StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0); /* FIX: False */
2376 /*****************************************************************************
2377 * Function: void SearchForPattern()
2381 * Return Value: True if pattern found, False if not found
2383 * Purpose: Find a pattern in a string
2385 * WARNING: may convert string to uppercase in place
2386 * depending on which code is compiled.
2387 *****************************************************************************/
2388 static Boolean SearchForPattern(
2393 #if defined(NO_REGEX) /* don't support regex in string searches */
2396 _DtHelpCeUpperCase(string);
2397 /* FIX: make this code much faster by using an improved
2398 pattern search algorithm, such as Rabin-Karp. */
2399 /* hit is set to NULL if no matching char is found */
2400 while (_DtHelpCeStrchr(string, pattern, MB_CUR_MAX, &hit) == 0)
2402 if ( strncmp(hit,pattern,patternLen) == 0 )
2405 string = hit + mblen(hit,1);
2407 return (NULL != hit); /* RETURN True or False */
2408 #else /* if NO_REGEX */
2413 /* use regexec to pattern match */
2414 /* a 0 return value indicates success */
2415 if ( regcomp(&re,pattern,REG_NOSUB|REG_ICASE|REG_EXTENDED) == 0 )
2417 /* a 0 return value indicates success */
2418 ret = regexec(&re,string,0,NULL,0);
2421 return (ret == 0); /* RETURN True or False */
2422 # else /* NO_REGCOMP */
2426 /* a non NULL return value indicates success */
2427 compiledRE = (char *)regcmp(pattern, (char *) NULL);
2430 /* a non NULL return value indicates success */
2431 ret = regex(compiledRE, string);
2434 return (ret != NULL); /* RETURN True or False */
2435 # endif /* NO_REGCOMP */
2436 #endif /* if NO_REGEX */
2440 /*****************************************************************************
2441 * Function: void OpenVolForSearch()
2445 * Return Value: False if an error
2448 * Purpose: Opens a volume for searching,
2449 * gets the volume locale, if
2450 * different from system locale,
2451 * saves system locale in vol,
2452 * installs volume locale
2454 * Note that the system locale
2455 *****************************************************************************/
2456 static Boolean OpenVolForSearch(
2457 DtHelpDialogWidget hw,
2458 char * fullFilePath,
2459 _DtHelpGlobSrchVol * curVol)
2461 Boolean openedVolume = False;
2463 /* open the volume if not open */
2464 if ( NULL == curVol->volHandle )
2466 _DtHelpOpenVolume(fullFilePath, &curVol->volHandle);
2467 if (NULL == curVol->volHandle) return False; /* RETURN */
2469 if (curVol->gotLocale == False)
2471 curVol->stdLocale = _DtHelpGetVolumeLocale(curVol->volHandle);
2472 /* get the op-specific locales; the strings are default values */
2473 _DtHelpCeXlateStdToOpLocale(DtLCX_OPER_ICONV3,curVol->stdLocale,
2474 "iso88591",&curVol->iconv3Codeset);
2475 curVol->gotLocale = True;
2477 openedVolume = True;
2479 /* get the codeset of the application's locale, if haven't gotten it */
2480 if ( NULL == hw->help_dialog.srch.iconv3Codeset )
2482 char * locale = NULL;
2483 _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,
2484 setlocale(LC_CTYPE,NULL),&locale,NULL,NULL);
2485 /* get the op-specific locales; the strings are default values */
2486 /* impt: XlateStdToOpLocale() call requires a locale, not a codeset */
2487 _DtHelpCeXlateStdToOpLocale(DtLCX_OPER_ICONV3,locale,
2488 "iso88591",&hw->help_dialog.srch.iconv3Codeset);
2492 /** only saves or changes the locale if necessary **/
2493 /* create an iconv3 context to convert codeset of */
2494 /* the volume to the codeset of the application */
2495 if ( _DtHelpCeIconvContextSuitable(hw->help_dialog.srch.iconv3Context,
2496 curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset) == False )
2498 /* close old, open new */
2499 _DtHelpCeIconvClose(&hw->help_dialog.srch.iconv3Context);
2500 _DtHelpCeIconvOpen(&hw->help_dialog.srch.iconv3Context,
2501 curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset,' ',' ');
2504 /* else volume already open */
2506 /* if just opened volume */
2509 /* we just share pointers; when freeing localeWordStr, we need to
2510 test whether they are different before freeing */
2511 hw->help_dialog.srch.localeWordStr = hw->help_dialog.srch.normWordStr;
2514 /* get the str coll function, iff needed */
2515 if (NULL == curVol->strcollProc)
2517 /* get strcollProc for vol locale */
2518 curVol->strcollProc = _DtHelpCeGetStrcollProc();
2525 /*****************************************************************************
2526 * Function: void CloseVolAfterSearch()
2530 * Return Value: Void.
2532 * Purpose: Closes a volume opened for searching,
2533 * installs system locale, if diff from volume.
2535 *****************************************************************************/
2536 static void CloseVolAfterSearch(
2537 DtHelpDialogWidget hw,
2538 _DtHelpGlobSrchVol * curVol)
2540 /* close the volume if open */
2541 if ( NULL != curVol->volHandle )
2543 _DtHelpCloseVolume(curVol->volHandle);
2544 curVol->volHandle = NULL;
2545 /* free the locale word string, if allocated */
2546 if(hw->help_dialog.srch.localeWordStr!=hw->help_dialog.srch.normWordStr)
2548 XtFree(hw->help_dialog.srch.localeWordStr);
2549 hw->help_dialog.srch.localeWordStr = NULL;
2553 /* don't free the iconv context...may apply to the next volume */
2558 /*****************************************************************************
2559 * Function: void SearchTopic()
2563 * Return Value: Void.
2565 * Purpose: Get a single topic and search for the search word in it
2567 *****************************************************************************/
2568 static void SearchTopic(
2569 DtHelpDialogWidget hw,
2570 _DtHelpFileEntry curFile,
2571 _DtHelpGlobSrchVol * curVol,
2579 /* if the volume is not open; don't continue */
2580 if ( NULL == curVol->volHandle )
2581 return; /* RETURN */
2583 if ( NULL == curVol->indexEntriesList )
2584 _CEVolumeTopicList(curVol->volHandle,&curVol->indexEntriesList);
2585 if ( NULL == curVol->volHandle || NULL == curVol->indexEntriesList )
2587 curVol->topicSearchInProgress = False;
2588 curVol->topicSearchDone = True;
2589 curVol->indexSearchInProgress = True;
2590 if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
2591 return; /* RETURN */
2594 curVol->topicSearchInProgress = True;
2597 /* search the topics */
2598 /* note that indexEntriesList[0] is correct; ptr is incremented */
2599 /* we can increment the pointer because we don't own this memory;
2600 the open volume does. */
2602 i < numSearches && NULL != curVol->indexEntriesList[0];
2603 i++, curVol->indexEntriesList++ )
2605 char * topicTitle = NULL;
2608 validTopic = _DtHelpGetTopicTitle( curVol->volHandle,
2609 curVol->indexEntriesList[0],&topicTitle);
2612 /* look for a hit and process if there was one */
2613 if (SearchForPattern(topicTitle,srchWord,srchWordLen) == True)
2615 HitListAddFound(curFile, curVol->indexEntriesList[0], True, NULL);
2619 /* clean up and advance to next topic */
2621 curVol->searchedCnt++;
2622 } /* for all topics to search */
2625 if ( NULL == curVol->indexEntriesList /* no topics queried */
2626 || NULL == curVol->indexEntriesList[0] ) /* no more topics available */
2628 /* hand off to next stage */
2629 curVol->indexEntriesList = NULL;
2630 curVol->topicSearchInProgress = False;
2631 curVol->topicSearchDone = True;
2632 curVol->indexSearchInProgress = True;
2639 /*****************************************************************************
2640 * Function: void SearchIndex()
2644 * Return Value: void
2646 * Purpose: Get a single Index and search for the search word in it
2648 * Commentary: There are two strings for each index entry.
2649 * One string is the straight text in
2650 * the codeset of the volume. The
2651 * other string is a XmString that
2652 * has a font tag that will allow
2653 * it to be displayed in the
2656 * Preconditions: This code requires that the volume to be search
2657 * has already been opened [OpenVolForSearch()],
2658 * that the locale of the volume has been installed,
2659 * and that the search word is in the same code
2660 * set as the volume and has been converted to
2663 *****************************************************************************/
2664 static void SearchIndex(
2665 DtHelpDialogWidget hw,
2666 _DtHelpFileEntry curFile,
2667 _DtHelpGlobSrchVol * curVol,
2668 _DtHelpCeIconvContext iconvContext,
2674 char * indexEntry = NULL;
2675 size_t entryLen = 100; /* starting size */
2678 /* if the volume is not open; don't continue */
2679 if ( NULL == curVol->volHandle )
2680 return; /* RETURN */
2682 /* get the XmStrings of the entries */
2683 if ( NULL == curVol->indexXmStrsList )
2685 XmFontList fontList = NULL;
2686 Boolean mod = False;
2689 /* get results font list */
2690 XtSetArg(args[0], XmNfontList, &fontList);
2691 XtGetValues(hw->help_dialog.srch.resultList,args,1);
2694 /* Don't need to copy, _DtHelpFormatVolumeTitle copies
2698 /* work with copy, because FontListAppendEntry() destroys input FL */
2699 fontList = XmFontListCopy(fontList);
2702 /* get the entries */
2703 _DtHelpFormatIndexEntries(hw->help_dialog.help.pDisplayArea,
2704 curVol->volHandle,&numEntries, &curVol->indexXmStrsList,
2707 /* install the changed list */
2710 XtSetArg(args[0], XmNfontList, fontList);
2711 XtSetValues(hw->help_dialog.srch.resultList,args,1);
2712 if (fontList) XmFontListFree(fontList);
2716 /* get the pure strings for searching */
2717 if ( NULL == curVol->indexEntriesList )
2719 /* recall that the array and strings pointed to by
2720 the indexEntriesList is owned by the open volume */
2721 _DtHelpCeGetKeywordList(curVol->volHandle,&curVol->indexEntriesList);
2723 /* and re-init curIndexXmStr */
2724 curVol->curIndexXmStr = curVol->indexXmStrsList;
2727 if ( NULL == curVol->volHandle
2728 || NULL == curVol->indexEntriesList
2729 || NULL == curVol->indexXmStrsList )
2731 curVol->indexSearchInProgress = False;
2732 curVol->indexSearchDone = True;
2733 curVol->searchCompleted = True;
2734 if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
2735 return; /* RETURN */
2738 curVol->indexSearchInProgress = True;
2740 /* alloc memory for index processing */
2741 indexEntry = XtMalloc(sizeof(char)*(entryLen+1));
2742 if (NULL == indexEntry) return; /* RETURN */
2744 /* get a index entry */
2746 i < numSearches && NULL != curVol->indexEntriesList[0];
2747 i++, curVol->indexEntriesList++, curVol->curIndexXmStr++ )
2749 /* prevent overflow of buffer */
2750 if (strlen(curVol->indexEntriesList[0]) > entryLen)
2752 entryLen = strlen(curVol->indexEntriesList[0]) + 50;
2753 indexEntry = XtRealloc(indexEntry,entryLen+1);
2754 if (NULL == indexEntry) break; /* BREAK */
2756 indexEntry[0] = EOS; /* init to empty string */
2758 /* look for a hit and process if there was one */
2759 /* if srchWord is NULL, all entries are hits */
2760 /* copy, and possible iconv, the index string into the */
2761 /* the codeset of srchWord (the application) */
2762 if ( NULL == srchWord
2763 || ( _DtHelpCeIconvStr(iconvContext,curVol->indexEntriesList[0],
2764 &indexEntry, &entryLen,indexEntry,entryLen) == 0
2765 && SearchForPattern(indexEntry, srchWord, srchWordLen) == True ) )
2767 _DtHelpGlobSrchHit * hit;
2768 char * * topicIdList;
2770 HitListAddFound ( curFile, curVol->curIndexXmStr[0],
2771 curVol->indexEntriesList[0], True, &hit);
2773 /* topicIdList is set but not allocated & need not be freed */
2774 hit->topicCnt = _DtHelpCeFindKeyword(curVol->volHandle,
2775 hit->indexEntry,&topicIdList);
2778 /* clean up and advance to next topic */
2779 curVol->searchedCnt++;
2782 if ( NULL == curVol->indexEntriesList /*no topics queried*/
2783 || NULL == curVol->indexEntriesList[0] )/*no more index entries avail*/
2785 /* hand off to next stage */
2786 curVol->indexEntriesList = NULL; /* init */
2787 curVol->curIndexXmStr = curVol->indexXmStrsList; /* re-init */
2788 curVol->indexSearchInProgress = False;
2789 curVol->indexSearchDone = True;
2790 curVol->searchCompleted = True;
2797 /*****************************************************************************
2798 * Function: void SearchVolume()
2802 * Return Value: Void.
2804 * Purpose: do the search operation
2805 * This routine does incremental search--it searchs
2806 * a little, then returns to allow further processing.
2807 * It is called whenever Xt detects no other events.
2809 *****************************************************************************/
2810 static void SearchVolume(
2811 DtHelpDialogWidget hw,
2812 _DtHelpFileEntry curFile,
2813 _DtHelpGlobSrchVol * curVol,
2816 XmString labelString;
2820 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
2821 if (hw->help_dialog.srch.selectionDlg)
2822 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
2824 /* Process according to state */
2825 if ( curVol->nothingDone )
2827 curVol->nothingDone = False;
2828 curVol->topicSearchInProgress = True;
2830 /* Update the search status string */
2831 sprintf(buf,(char *)_DTGETMESSAGE(GSSET,18,
2832 "Searching... Volumes remaining: %d"),
2833 hw->help_dialog.srch.volLeftCnt);
2834 labelString = XmStringCreateLocalized(buf);
2835 XtSetArg(args[0],XmNlabelString,labelString);
2836 XtSetValues (hw->help_dialog.srch.statusLabel, args, 1);
2837 XmStringFree(labelString);
2839 XmUpdateDisplay((Widget) hw->help_dialog.srch.statusLabel);
2842 OpenVolForSearch(hw,curFile->fullFilePath,curVol);
2844 if ( curVol->topicSearchInProgress )
2846 SearchTopic(hw, curFile,curVol,hw->help_dialog.srch.localeWordStr,
2847 hw->help_dialog.srch.wordFieldLen, numSearches);
2850 /* NOTE: because this isn't an "else if", we could potentially
2851 search for 2*numSearches; but I know that I've disabled the
2852 topic search. Furthermore, my code depends upon the possibility
2853 of searching an entire volume in one call to the routine, if
2854 desired, and having an else if would break that.
2856 if ( curVol->indexSearchInProgress )
2859 srchWord = hw->help_dialog.srch.localeWordStr;
2860 /* FullIndex search indicated by a null search word string */
2861 if (hw->help_dialog.srch.fullIndex) srchWord = NULL;
2862 SearchIndex(hw, curFile, curVol, hw->help_dialog.srch.iconv3Context,
2863 srchWord, hw->help_dialog.srch.wordFieldLen, numSearches);
2866 /* If search was completed, update dependent stuff */
2867 if (curVol->searchCompleted)
2869 /* handle completion */
2870 CloseVolAfterSearch(hw,curVol);
2871 curVol->indexEntriesList = NULL; /* mem not owned by GlobSrch */
2872 if (hw->help_dialog.srch.fullIndex)
2873 curVol->gatheredFullIndex = True;
2874 hw->help_dialog.srch.volLeftCnt--;
2875 if (hw->help_dialog.srch.volLeftCnt < 0)
2876 hw->help_dialog.srch.volLeftCnt = 0;
2879 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
2880 if (hw->help_dialog.srch.selectionDlg)
2881 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
2886 /*****************************************************************************
2887 * Function: void SearchFile()
2891 * Return Value: Void.
2893 * Purpose: do the search operation on an entire file
2894 * It searches the entire file at once
2895 * and displays the results in the list.
2897 *****************************************************************************/
2898 static void SearchFile(
2899 DtHelpDialogWidget hw,
2900 _DtHelpFileEntry file)
2902 register _DtHelpGlobSrchVol * vol;
2904 /* get volume info, adding if necessary */
2905 vol = (_DtHelpGlobSrchVol *) file->clientData;
2906 /* (T,T,F): enable search, enable display, any volume */
2907 if (NULL == vol) AddVolInfoToFile(file, True, True, False);
2908 vol = (_DtHelpGlobSrchVol *) file->clientData;
2909 if (NULL == vol) return;
2911 /* conduct search of entire volume in one call */
2912 hw->help_dialog.srch.volLeftCnt = 1;
2913 vol->searchThisVolume = True;
2914 vol->showVolInList = True;
2915 vol->zeroHitsOk = True;
2916 SearchVolume(hw,file,vol,INT_MAX);
2919 StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);/*FIX: False*/
2921 /* update the list to show the volume */
2922 AdjustPositionValues(file,0,1,True);
2923 /* True: do insert new item */
2924 VolNameDisplay(hw,file,True);
2926 if (vol->showHitsWithVol)
2928 VolHitsDisplay(hw,file);
2929 /* False: don't insert new item */
2930 VolNameDisplay(hw,file,False);
2937 /*****************************************************************************
2938 * Function: void DoBackgroundSearchWP(
2939 * XtPointer clientData)
2945 * Return Value: Void.
2947 * Purpose: do the search operation in the background
2948 * This routine does incremental search--it searchs
2949 * a little, then returns to allow further processing.
2950 * It is called whenever Xt detects no other events.
2952 *****************************************************************************/
2953 static Boolean DoBackgroundSearchWP(
2954 XtPointer clientData)
2956 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
2957 _DtHelpFileEntry curFile;
2958 _DtHelpGlobSrchVol * curVol = NULL;
2960 if ( 0 == hw->help_dialog.srch.volLeftCnt )
2961 goto searchComplete; /* GOTO: done! */
2963 /* get file to work on */
2964 curFile = hw->help_dialog.srch.curSrchVol;
2965 if ( NULL == curFile )
2967 curFile = GetNextSearchFileAndDisplayCompleted(
2968 hw, hw->help_dialog.srch.volListHead, NULL);
2969 if ( NULL == curFile ) goto searchComplete; /* GOTO: done */
2970 hw->help_dialog.srch.curSrchVol = curFile;
2971 } /* if no current file */
2973 /* get volume info */
2974 curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
2976 #define NUM_SEARCHES_PER_CALL 30
2977 SearchVolume(hw,curFile,curVol,NUM_SEARCHES_PER_CALL);
2979 /* If search was completed, update dependent stuff */
2980 if (curVol->searchCompleted)
2982 /* update the search results list */
2983 /* True: adjust count beginning with this file */
2984 if (curVol->hitCnt > 0 || curVol->zeroHitsOk)
2986 /* record that a hit found */
2987 if ( curVol->hitCnt > 0
2988 || ( curVol->zeroHitsOk
2989 && _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
2990 hw->help_dialog.srch.hitsFound = True;
2992 /* update the list to show the volume */
2993 AdjustPositionValues(curFile,0,1,True);
2994 ResultsListUpdate(hw,curFile);
2996 /* update the list to show the hits? */
2997 if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
2999 VolHitsDisplay(hw,curFile);
3000 /* False: don't insert new item */
3001 VolNameDisplay(hw,curFile,False);
3003 XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
3006 /* prepare for next search */
3007 hw->help_dialog.srch.curSrchVol =
3008 GetNextSearchFileAndDisplayCompleted(hw,NULL,curFile);
3010 } /* if search completed */
3013 if ( hw->help_dialog.srch.volLeftCnt > 0
3014 || False == curVol->searchCompleted )
3015 return False; /* RETURN: False ==> continue processing */
3017 /* Do this when no more files are left to search */
3020 XmPushButtonCallbackStruct status;
3022 /* zero search data before stopping */
3023 hw->help_dialog.srch.volLeftCnt = 0; /* just in case */
3024 hw->help_dialog.srch.curSrchVol = NULL; /* just in case */
3026 /* generate a fake event to reset the dialog */
3027 status.reason = XmCR_ACTIVATE;
3028 status.event = NULL;
3029 status.click_count = 1;
3030 StopSearchCB(hw->help_dialog.srch.actionBtn,
3031 (XtPointer)hw,(XtPointer)&status);
3033 return True; /* RETURN: True ==> stop processing */
3039 /*****************************************************************************
3040 * Function: void StartSearchCB(Widget w,
3041 * XtPointer clientData,
3042 * XtPointer callData);
3048 * Return Value: Void.
3050 * Purpose: Create a new user bookmark
3052 * Warning: This CB is also used by the volume selection buttons
3053 * to activate a search when they are selected. The routine
3054 * cannot rely upon the w or callData params. The clientData
3055 * will always be the help widget.
3056 *****************************************************************************/
3057 static void StartSearchCB(
3058 Widget w, /* dont use */
3059 XtPointer clientData,
3060 XtPointer callData) /* dont use */
3062 char *srchWord = NULL;
3063 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3064 XtAppContext appCntx;
3068 /* set state of start button correctly */
3069 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
3071 /* if help content isn't a volume, it has no index */
3072 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
3073 && hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC )
3074 return; /* RETURN */
3076 /* retrieve the name */
3077 srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
3079 /* test for empty (also emtpy spaces) and only process if not emtpy */
3080 _DtHelpCeCompressSpace(srchWord);
3081 if ( (strlen(srchWord) > (size_t) 0 || hw->help_dialog.srch.fullIndex)
3082 && hw->help_dialog.srch.workProcId == 0)
3083 /* test on workProcId prevents multiple activations due to
3084 race condition on desensitizing the start button */
3086 _DtHelpTurnOnHourGlass(XtParent(hw));
3087 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3088 if (hw->help_dialog.srch.selectionDlg)
3089 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3091 /*XtSetSensitive (hw->help_dialog.srch.actionBtn,False);*/
3092 XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False);
3093 XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,False);
3094 XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,False);
3095 XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
3097 /* 9/26/94: these two XtSetArgs (and following SetValues) cause a core dump
3098 for the SunOS 5.3 optimized executable. It isn't a problem for the
3099 non-optimized or debuggable versions or any versions on AIX 3.2 or
3101 #if !defined(sun) && !defined(__osf__)
3103 XtSetArg(args[n],XmNeditable,False); n++;
3104 XtSetArg(args[n],XmNcursorPositionVisible,False); n++;
3105 XtSetValues (hw->help_dialog.srch.wordField, args, n);
3107 XmUpdateDisplay(hw->help_dialog.srch.srchForm);
3109 /* process the source selection and retain in widget srchWord memory */
3110 PrepSearchSourceData(hw, srchWord);
3112 /* activate search thread; do it even with a 0 count, because the
3113 process reactivates the dialog after search is completed */
3114 appCntx = XtWidgetToApplicationContext((Widget) hw);
3115 hw->help_dialog.srch.workProcId =
3116 XtAppAddWorkProc(appCntx,DoBackgroundSearchWP, (XtPointer) hw);
3118 hw->help_dialog.srch.searchInProgress = True;
3120 /* dont free srchWord */
3122 /* turn on "Stop" label */
3123 UpdateActionButtonLabel(hw,NULL,False);
3125 _DtHelpTurnOffHourGlass(XtParent(hw));
3126 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3127 if (hw->help_dialog.srch.selectionDlg)
3128 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3132 if ( strlen(srchWord) == 0 )
3133 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
3141 /*****************************************************************************
3142 * Function: void StartSelectedVolumeSearchCB(Widget w,
3143 * XtPointer clientData,
3144 * XtPointer callData);
3150 * Return Value: Void.
3152 * Purpose: Begin a search on the selected volume
3154 *****************************************************************************/
3155 static void StartSelectedVolumeSearchCB(
3157 XtPointer clientData,
3160 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3161 _DtHelpFileEntry file;
3163 Boolean noSelectedFiles = True;
3165 /* if not full index search */
3166 if (hw->help_dialog.srch.fullIndex == False)
3168 /* get the current contents of the search word field */
3169 srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
3171 /* test the word ; False=dontUpdate--do this in PrepSearchSourceData() */
3172 if ( CheckSearchWord(hw,srchWord,False) == True )
3173 { /* word has changed since last search; do a whole new search */
3174 StartSearchCB(NULL,(XtPointer) hw, NULL);
3175 return; /* RETURN */
3178 /* if the text field is empty, do nothing */
3179 if ( strlen(hw->help_dialog.srch.normWordStr) == 0 )
3180 return; /* RETURN */
3183 /* set this to true to counteract False if no hits */
3184 hw->help_dialog.srch.hitsFound = True;
3186 /* Word is the same, just the selection has changed. */
3187 /* Determine which one was selected or deselected */
3188 for ( file = hw->help_dialog.srch.volListHead;
3190 file = _DtHelpFileListGetNext(NULL,file) )
3192 register _DtHelpGlobSrchVol * vol;
3193 vol = (_DtHelpGlobSrchVol *) file->clientData;
3194 if (NULL == vol) continue;
3197 if (file->fileSelected) noSelectedFiles = False;
3199 /* test for contradictory flags; fileSelected reflects dialog list */
3200 if (file->fileSelected != vol->showVolInList)
3202 /* file has been deselected */
3203 if (False == file->fileSelected)
3205 if (vol->showVolInList)
3207 /* update list: delete hits, topics, and volume title */
3208 if (vol->hitsDisplayed) VolHitsUndisplay(hw,file);
3210 /* delete hits first, then volume */
3212 hw->help_dialog.srch.resultList,vol->startPosition);
3213 AdjustPositionValues(file, 0, -1, True);
3214 vol->showVolInList = False;
3215 vol->searchThisVolume = False;
3218 else /* file has been selected */
3220 SearchFile(hw,file);
3221 } /* if file de/selected */
3222 } /* if contradictory flags */
3223 } /* for all volumes */
3226 if (noSelectedFiles) StatusLabelUpdate(hw,NO_VOL_STATUS,True,0);
3231 /*****************************************************************************
3232 * Function: void UpdateSearchStartStatusCB(Widget w,
3233 * XtPointer clientData,
3234 * XtPointer callData);
3240 * Return Value: Void.
3242 * Purpose: update the status of the search status button
3243 * Routine is called whenever text is changed in the search
3246 *****************************************************************************/
3247 static void UpdateSearchStartStatusCB(
3249 XtPointer clientData,
3252 char *srchWord = NULL;
3253 /*XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) callData;*/
3254 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3257 /* retrieve the name */
3258 srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
3260 /* test for empty (also emtpy spaces) */
3261 _DtHelpCeCompressSpace(srchWord);
3263 /* FIX: change the locale from the volume locale back to the system
3264 locale temporarily (if not already in that locale) */
3265 _DtHelpCeUpperCase(srchWord);
3267 /* only sensitize if working on a help volume and word is not emtpy
3270 if ( ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
3271 && hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC)
3272 || ( strlen(srchWord) == (size_t) 0
3273 && hw->help_dialog.srch.fullIndex == False))
3275 XtSetSensitive (hw->help_dialog.srch.actionBtn,newState);
3277 /* if word has changed from word of previous search, change to Start */
3278 UpdateActionButtonLabel(hw,srchWord,True);
3284 /*****************************************************************************
3285 * Function: void StopSearchCB(Widget w,
3286 * XtPointer clientData,
3287 * XtPointer callData);
3293 * Return Value: Void.
3295 * Purpose: Stop the search
3297 *****************************************************************************/
3298 static void StopSearchCB(
3300 XtPointer clientData,
3303 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3308 /* stop the search thread */
3309 if(hw->help_dialog.srch.workProcId != 0)
3310 XtRemoveWorkProc(hw->help_dialog.srch.workProcId);
3311 hw->help_dialog.srch.workProcId = 0;
3313 hw->help_dialog.srch.searchInProgress = False;
3315 /* update statuses */
3317 XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,
3318 hw->help_dialog.srch.curVolRadBtnSens);
3320 XtSetSensitive (hw->help_dialog.srch.curVolRadBtn, TRUE);
3323 XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,True);
3324 XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,True);
3326 XtSetArg(args[n],XmNeditable,True); n++;
3327 XtSetArg(args[n],XmNcursorPositionVisible,True); n++;
3328 XtSetValues (hw->help_dialog.srch.wordField, args, n);
3330 /* update select btn status; only when selected and dialog closed */
3331 XtSetArg(args[0],XmNset,&cur);
3332 XtGetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
3333 XtSetSensitive(hw->help_dialog.srch.selectBtn,
3334 cur && ( NULL == hw->help_dialog.srch.selectionDlg
3335 || !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
3337 /* set the action button label appropriately */
3338 UpdateActionButtonLabel(hw,hw->help_dialog.srch.normWordStr,True);
3340 /* post message of results */
3341 StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);
3347 /*****************************************************************************
3348 * Function: void ActionButtonCB(Widget w,
3349 * XtPointer clientData,
3350 * XtPointer callData);
3356 * Return Value: Void.
3358 * Purpose: Act upon the action
3360 *****************************************************************************/
3361 static void ActionButtonCB(
3363 XtPointer clientData,
3366 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3368 if ( hw->help_dialog.srch.searchInProgress == False )
3369 StartSearchCB(w,clientData,callData);
3371 StopSearchCB(w,clientData,callData);
3377 /*****************************************************************************
3378 * Function: void GotoResultCB(Widget w,
3379 * XtPointer clientData,
3380 * XtPointer callData);
3386 * Return Value: Void.
3388 * Purpose: Goto a result topic
3390 *****************************************************************************/
3391 static void GotoResultCB(
3393 XtPointer clientData,
3396 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3397 char * helpFile = NULL;
3398 int * topicPosList=NULL;
3403 /* Determine the item selected and find that item in our list */
3404 status = XmListGetSelectedPos(hw->help_dialog.srch.resultList, &topicPosList,&i);
3406 /* if true, an item selected */
3407 if (status && topicPosList)
3409 _DtHelpGlobSrchHit * entry = NULL;
3410 _DtHelpFileEntry file = NULL;
3411 char * locationId = NULL;
3412 topicPosition = topicPosList[0] - 1; /* convert to 0 based */
3413 XtFree((String)topicPosList);
3416 HitListGetNth(hw->help_dialog.srch.volListHead,
3417 topicPosition,&file,&entry,&locationId,&helpFile);
3419 /* jump to selected location */
3420 XtFree(hw->help_dialog.display.locationId);
3421 hw->help_dialog.display.locationId = XtNewString(locationId);
3422 XtFree(hw->help_dialog.display.helpVolume);
3423 hw->help_dialog.display.helpVolume = XtNewString(helpFile);
3424 hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
3425 hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
3427 _DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
3431 if (topicPosList) XtFree((String)topicPosList);
3433 /* FIX: Put up a message to suggest selecting an item first */
3434 /* Don't close the dialog */
3437 #endif /* not_used */
3439 #if 0 /* save--used in code commented out elsewhere in this file */
3441 /*****************************************************************************
3442 * Function: void CloseHelpCB()
3446 * Return Value: Void.
3448 * Purpose: Close and destroy the help widget
3450 *****************************************************************************/
3451 static void CloseHelpCB(
3453 XtPointer clientData,
3459 #endif /* save--used in code commented out elsewhere in this file */
3462 /*****************************************************************************
3463 * Function: void GotoLocation(hw,helpVolume,location)
3467 * Return Value: Void.
3469 * Purpose: Goto a topic by opening a new help dialog window
3471 *****************************************************************************/
3472 static void GotoLocation(
3473 DtHelpDialogWidget hw,
3477 #if 0 /* don't delete...useful as reference */
3483 /* This opens a new help window on the topic */
3485 XtSetArg( args[n], XmNtitle, "Help" ); n++;
3486 XtSetArg( args[n], DtNhelpType, DtHELP_TYPE_TOPIC ); n++;
3487 XtSetArg( args[n], DtNlocationId, locationId ); n++;
3488 XtSetArg( args[n], DtNhelpVolume, helpVolume ); n++;
3489 helpDlg = DtCreateHelpDialog(XtParent(hw),"mainHelpDialog",args,n);
3490 XtAddCallback(helpDlg,DtNcloseCallback,CloseHelpCB,helpDlg);
3491 XtManageChild(helpDlg);
3495 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3496 if (hw->help_dialog.srch.selectionDlg)
3497 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3499 /* jump to selected location in same window */
3500 XtFree(hw->help_dialog.display.locationId);
3501 hw->help_dialog.display.locationId = XtNewString(locationId);
3502 XtFree(hw->help_dialog.display.helpVolume);
3503 hw->help_dialog.display.helpVolume = XtNewString(helpVolume);
3504 hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
3505 hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
3507 _DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
3509 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3510 if (hw->help_dialog.srch.selectionDlg)
3511 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3518 /*****************************************************************************
3519 * Function: void ProcessResultSelectionCB(Widget w,
3520 * XtPointer clientData,
3521 * XtPointer callData);
3527 * Return Value: Void.
3529 * Purpose: Process user selection of an item in the result List.
3531 *****************************************************************************/
3532 static void ProcessResultSelectionCB(
3534 XtPointer clientData,
3537 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3538 int * topicPosList = NULL;
3543 /* Determine the item selected and find that item in our list */
3544 status = XmListGetSelectedPos(
3545 hw->help_dialog.srch.resultList, &topicPosList,&n);
3547 /* if true, an item selected */
3548 if (status && topicPosList)
3550 _DtHelpFileEntry file = NULL;
3551 _DtHelpGlobSrchHit * hit = NULL;
3552 char * locationId = NULL;
3553 char * helpFile = NULL;
3555 topicPosition = topicPosList[0]; /* 1 based */
3556 XtFree((String)topicPosList);
3559 if ( HitListGetNth(hw->help_dialog.srch.volListHead,
3560 topicPosition,&file,&hit,&locationId,&helpFile) == 0 )
3562 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3565 XmListDeselectPos(hw->help_dialog.srch.resultList,topicPosition);
3567 /* was a volume item selected? */
3570 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
3571 if (vol->hitCnt > 0)
3573 if (False == vol->hitsDisplayed)
3575 VolHitsDisplay(hw,file); /* toggle state */
3579 VolHitsUndisplay(hw,file);
3580 vol->showHitsWithVol = False;
3582 /* update the volume label to show the state */
3583 /* False: dont insert hw item */
3584 VolNameDisplay(hw,file,False);
3586 /* else don't otherwise handle a 0-hits volume */
3588 /* was an expandable index selected */
3589 else if (NULL == locationId && hit->topicCnt > 1)
3593 /* if we're turning them on, build a list */
3594 if (False == hit->topicsDisplayed)
3596 topicCnt = HitTopicsDisplay(hw,file,hit,topicPosition+1);
3600 topicCnt = - HitTopicsUndisplay(hw,file,hit,topicPosition+1);
3601 hit->showTopicsWithHit = False;
3603 /* update the hit label to show the state; False--dont insert */
3604 HitNameDisplay(hw,file,hit,topicPosition,False);
3606 /* add to all the following */
3609 /* adjust count beginning with next file with hits */
3610 AdjustPositionValues(file, 0, topicCnt, True);
3613 /* a location or index with one topic was selected */
3616 /* if a single click, goto the location */
3617 if (hit->topicCnt == 1)
3619 if ( HitLoadTopics(hw,file,hit) == 0 )
3621 GotoLocation(hw, file->fullFilePath, hit->topicIdList[0]);
3622 HitFree(hit,False); /*release what was loaded 3 lines up*/
3625 { /* volume couldn't be opened or some other error */
3626 /* FIX: error message */
3628 } /* if an index with a single topic */
3630 { /* a location from an open multi-topic index entry */
3631 GotoLocation(hw, file->fullFilePath, locationId);
3633 } /* else index with one topic or topic was selected */
3635 /* finish up processing a selection */
3636 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3638 } /* got the nth item */
3640 else /* could not find the nth hit */
3642 if (topicPosList) XtFree((String)topicPosList);
3649 /*****************************************************************************
3650 * Function: void CloseVolSelDialogCB(Widget w,
3651 * XtPointer clientData,
3652 * XtPointer callData);
3656 * Return Value: Void.
3658 * Purpose: Resets the selection dialog variable to NULL
3660 *****************************************************************************/
3661 static void CloseVolSelDialogCB(
3663 XtPointer clientData,
3666 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3668 /* unmanage & destroy the dialog zero the variable */
3669 if ( hw->help_dialog.srch.selectionDlg
3670 && XtIsManaged(hw->help_dialog.srch.selectionDlg) )
3671 XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
3673 /* start a search to be sure we got all changes; FIX: need this??? */
3674 /*StartSearchCB(NULL,hw,NULL);*/
3675 XtSetSensitive(hw->help_dialog.srch.selectBtn,True);
3678 if (hw->help_dialog.srch.hitsFound == True)
3679 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
3681 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
3686 /*****************************************************************************
3687 * Function: void CreateVolSelDialog(
3691 * Return Value: Void.
3693 * Purpose: Creates selection dialog to chose volumes
3695 *****************************************************************************/
3696 static void CreateVolSelDialog(
3697 DtHelpDialogWidget hw)
3700 _DtHelpFileDlgChildren dlgChld;
3701 Atom wm_delete_window;
3704 /* desensitize the button */
3705 XtSetSensitive(hw->help_dialog.srch.selectBtn,False);
3707 /* only create one */
3708 if ( NULL != hw->help_dialog.srch.selectionDlg )
3710 XtManageChild(hw->help_dialog.srch.selectionDlg);
3714 /* open the modal dialog and let user select the volumes */
3715 selDlg = _DtHelpFileListCreateSelectionDialog(
3716 hw, hw->help_dialog.srch.srchForm, False,
3717 (char *)_DTGETMESSAGE (GSSET, 40,
3718 "Help - Search Volume Selection"),
3719 &hw->help_dialog.srch.volTitlesFontList,
3720 hw->help_dialog.srch.volListHead, &dlgChld);
3721 hw->help_dialog.srch.selectionDlg = selDlg;
3723 XtAddCallback(dlgChld.closeBtn, XmNactivateCallback,
3724 CloseVolSelDialogCB,(XtPointer)hw);
3725 XtAddCallback(dlgChld.form, XmNunmapCallback,
3726 CloseVolSelDialogCB,(XtPointer)hw);
3728 /* set the default response to a WM_DELETE_WINDOW message
3729 to no response instead of UNMAP. */
3730 XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
3731 XtSetValues(dlgChld.shell, args, 1);
3732 wm_delete_window = XmInternAtom(XtDisplay(dlgChld.shell),
3733 "WM_DELETE_WINDOW", FALSE);
3734 XmAddWMProtocolCallback(dlgChld.shell,wm_delete_window,
3735 (XtCallbackProc)CloseVolSelDialogCB, (XtPointer)hw);
3737 XtAddCallback(dlgChld.list, XmNsingleSelectionCallback,
3738 StartSelectedVolumeSearchCB, (XtPointer) hw);
3739 XtAddCallback(dlgChld.list, XmNmultipleSelectionCallback,
3740 StartSelectedVolumeSearchCB, (XtPointer) hw);
3741 XtAddCallback(dlgChld.list, XmNextendedSelectionCallback,
3742 StartSelectedVolumeSearchCB, (XtPointer) hw);
3743 XtAddCallback(dlgChld.list, XmNdefaultActionCallback,
3744 StartSelectedVolumeSearchCB, (XtPointer) hw);
3749 /*****************************************************************************
3750 * Function: void OpenSelectDialogCB(Widget w,
3751 * XtPointer clientData,
3752 * XtPointer callData);
3758 * Return Value: Void.
3760 * Purpose: Process user selection of the select button
3762 *****************************************************************************/
3763 static void OpenSelectDialogCB(
3765 XtPointer clientData,
3768 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3770 /* only build the list of files if it hasn't been done */
3771 if ( False == hw->help_dialog.srch.volScanDone
3772 || NULL == hw->help_dialog.srch.volListHead)
3774 /* Add on the Vol info; (T,T,T) search, display, selected only */
3775 VolListBuild(hw,True,True,True);
3778 /* FIX: the modal behaviour doesn't seem to be set; is it desired/needed? */
3779 /* don't need to worry about having open twice, since
3780 the dialog is always opened in modal mode from the search dialog */
3781 /* open the dialog and let user select the volumes */
3782 CreateVolSelDialog(hw);
3786 /*****************************************************************************
3787 * Function: void UpdateSearchVolumesCB(Widget w,
3788 * XtPointer clientData,
3789 * XtPointer callData);
3795 * Return Value: Void.
3797 * Purpose: Process user selection of a button in the Volumes Radio box
3799 *****************************************************************************/
3800 static void UpdateSearchVolumesCB(
3802 XtPointer clientData,
3805 XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
3806 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3812 if (hw->help_dialog.srch.hitsFound == True)
3813 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
3815 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
3819 /* if turning off the button, just reinforce the current settings.
3820 This message occurs when an on button is hit again. */
3821 if ( False == status->set )
3823 XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
3824 XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
3825 XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
3826 XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
3827 XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
3828 XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
3832 /*** if work when something is turned on; ignore the off messages
3833 except when the button is the selected volumes button; we
3834 want to catch every click on that button */
3835 if ( XmCR_VALUE_CHANGED == status->reason
3836 && True == status->set
3837 && NULL != status->event ) /* event is NULL for 1st of the two calls
3838 to this routine that are made when a
3839 button is pressed. */
3841 /*** now update the sources value according to button selected ***/
3842 hw->help_dialog.srch.volLeftCnt = 0; /* change invalidates prior search */
3843 UpdateActionButtonLabel(hw,NULL,True);
3845 XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
3846 XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
3847 XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
3848 XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
3849 XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
3850 XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
3852 /*** selected volumes button activated ***/
3853 if (hw->help_dialog.srch.selVolRadBtn == widget)
3856 hw->help_dialog.srch.srchSources = _DtHelpGlobSrchSelectedVolumes;
3858 /* only build the list of files if it hasn't been done */
3859 if ( False == hw->help_dialog.srch.volScanDone
3860 || NULL == hw->help_dialog.srch.volListHead)
3862 /* Add on the Vol info; (T,T,T) search, display, selected only */
3863 VolListBuild(hw,True,True,True);
3866 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
3867 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
3868 /* (T,T,T,T): enable search, enable display,
3869 zero hits ok, only for selected volumes */
3870 /* Set these here so that the CountSelectedVolumes() works right */
3871 SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
3873 /* count all volumes selected, including those already searched */
3874 if (CountSelectedVolumes(hw->help_dialog.srch.volListHead,True)==0)
3876 StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
3877 DeleteListContents(&hw->help_dialog.srch);
3878 CreateVolSelDialog(hw);
3879 /* NOTE: don't start search here, start it from the callback */
3880 /* set state of start button correctly */
3881 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
3883 else /* volumes already selected; just display */
3885 hw->help_dialog.srch.hitsFound = False; /*DBG*/
3886 StartSearchCB(NULL,(XtPointer) hw, NULL);
3888 } /* if selected volumes button */
3890 /*** all volumes button ***/
3891 else if (hw->help_dialog.srch.allVolRadBtn == widget)
3893 /* close the selection dialog, if open */
3894 if (hw->help_dialog.srch.selectionDlg)
3895 XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
3897 /* set sources state */
3898 hw->help_dialog.srch.srchSources = _DtHelpGlobSrchAllVolumes;
3899 hw->help_dialog.srch.hitsFound = False; /*DBG*/
3900 StartSearchCB(NULL,(XtPointer) hw, NULL);
3902 /*** current volume button ***/
3905 /* close the selection dialog, if open */
3906 if (hw->help_dialog.srch.selectionDlg)
3907 XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
3909 /* set sources state */
3910 hw->help_dialog.srch.srchSources = _DtHelpGlobSrchCurVolume;
3911 hw->help_dialog.srch.hitsFound = False; /*DBG*/
3912 StartSearchCB(NULL,(XtPointer) hw, NULL);
3915 /* update the Select... button status */
3916 /* do this last, so that while searching for volumes (VolListBuild),
3917 the button is not active. */
3918 XtSetSensitive(hw->help_dialog.srch.selectBtn,
3919 (hw->help_dialog.srch.selVolRadBtn == widget)
3920 && ( NULL == hw->help_dialog.srch.selectionDlg
3921 || !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
3923 } /* if value changed */
3928 /*****************************************************************************
3929 * Function: void UpdateIndexSelectionCB(Widget w,
3930 * XtPointer clientData,
3931 * XtPointer callData);
3937 * Return Value: Void.
3939 * Purpose: Process user selection of a button in the Entries Radio box
3941 *****************************************************************************/
3942 static void UpdateIndexSelectionCB(
3944 XtPointer clientData,
3947 XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
3948 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3949 Boolean containsState;
3954 if (hw->help_dialog.srch.hitsFound == True)
3955 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
3957 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
3960 /* if turning off the button, just reinforce the current settings.
3961 This message occurs when an on button is hit again. */
3962 if ( False == status->set )
3964 containsState = (hw->help_dialog.srch.containsRadBtn == widget);
3965 XtSetArg(args[0], XmNset, !containsState);
3966 XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
3967 XtSetArg(args[0], XmNset, containsState);
3968 XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
3972 /*** if work when something is turned on; ignore the off messages
3973 except when the button is the selected volumes button; we
3974 want to catch every click on that button */
3975 if ( XmCR_VALUE_CHANGED == status->reason
3976 && True == status->set
3977 && NULL != status->event ) /* event is NULL for 1st of the two calls
3978 to this routine that are made when a
3979 button is pressed. */
3981 /* if search in progress, stop it */
3982 if(hw->help_dialog.srch.searchInProgress||hw->help_dialog.srch.workProcId)
3984 XmPushButtonCallbackStruct status;
3986 /* generate a fake event to reset the dialog */
3987 status.reason = XmCR_ACTIVATE;
3988 status.event = NULL;
3989 status.click_count = 1;
3990 StopSearchCB(hw->help_dialog.srch.actionBtn,
3991 (XtPointer)hw,(XtPointer)&status);
3994 containsState = (hw->help_dialog.srch.containsRadBtn == widget);
3995 XtSetArg(args[0], XmNset, !containsState);
3996 XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
3997 XtSetArg(args[0], XmNset, containsState);
3998 XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
4000 /* sensitize/desensitize the Contains text field */
4001 XtSetSensitive(hw->help_dialog.srch.wordField,containsState);
4003 XtSetArg(args[n],XmNeditable,containsState); n++;
4004 XtSetArg(args[n],XmNcursorPositionVisible,containsState); n++;
4005 XtSetValues(hw->help_dialog.srch.wordField,args,n);
4007 /* set widget status here; do this way bec. srchFullIndex is a bit flag */
4008 hw->help_dialog.srch.fullIndex = (containsState ? False : True); /*flag*/
4010 /* set state of start button correctly */
4011 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
4014 { /* if changing to "Containing" */
4015 /* change focus to the search word */
4016 XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
4017 /* user will need to hit CR to initiate search */
4020 { /* if changing to full index */
4021 /* indicate that no contains word is valid by deleting it */
4022 /* FIX: I'm concerned that normWordStr & localeWordStr aren't in synch */
4023 XtFree(hw->help_dialog.srch.normWordStr);
4024 hw->help_dialog.srch.normWordStr = NULL;
4025 /* search full index */
4026 StartSearchCB(NULL,(XtPointer) hw, NULL);
4029 /* and search to update results to the new state */
4030 } /* if value changed */
4035 /*****************************************************************************
4036 * Function: void ContainsDisarmCB(Widget w,
4037 * XtPointer clientData,
4038 * XtPointer callData);
4044 * Return Value: Void.
4046 * Purpose: Process disarm of the contains radio button
4048 *****************************************************************************/
4049 static void ContainsDisarmCB(
4051 XtPointer clientData,
4054 XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
4055 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
4057 /* Force focus to the word field if set. */
4058 if (True==status->set)
4059 XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
4064 /*****************************************************************************
4065 * Function: CreateCurVolBtnLabel()
4070 * Return Value: True or False if current vol has an index
4072 * Purpose: Creates the label for the current volume button
4074 *****************************************************************************/
4075 static Boolean CreateCurVolBtnLabel(
4076 DtHelpDialogWidget hw,
4077 Boolean * out_curVolAvailable,
4078 XmString * out_labelString,
4079 char * * out_mnemonic)
4084 XmString volTitleString = NULL;
4085 XmString preTitleString = NULL;
4086 XmString postTitleString = NULL;
4088 XmString labelString;
4090 Boolean curVolAvail;
4095 if (out_curVolAvailable)
4096 *out_curVolAvailable = False;
4097 if (out_labelString)
4098 *out_labelString = XmStringCreateLocalized("dum");
4104 /* if help content is a volume, get the title */
4105 if ( hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC )
4107 /* determine whether a current volume index is available */
4108 curVolAvail = VolumeHasIndexP(
4109 hw->help_dialog.srch.srchSources,
4110 hw->help_dialog.display.helpType,
4111 hw->help_dialog.display.helpVolume);
4113 /* change False to True to search home dir; may want this */
4114 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
4115 _DtHelpFileSuffixList,False,R_OK);
4117 /* title needs to be an XmString to use volume's font */
4120 XmFontList fontList = NULL;
4121 Boolean mod = False;
4123 /* get the font list of the btn */
4125 XtSetArg (args[n], XmNfontList, &fontList); n++;
4126 XtGetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
4128 #if defined(DONT_USE_CDExc22774)
4129 /* copy the list before passing it in for modification */
4130 fontList = XmFontListCopy (fontList);
4133 GetVolumeInfoCB(hw->help_dialog.help.pDisplayArea,path,
4134 NULL,&volTitleString,NULL,NULL,NULL,&fontList,&mod);
4136 /* if font list was changed, install it */
4139 /* set the font list of the btn */
4141 XtSetArg (args[n], XmNfontList, fontList); n++;
4142 XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
4143 if (fontList) XmFontListFree (fontList);
4148 if (NULL == volTitleString)
4149 volTitleString = XmStringCreateLocalized(
4150 hw->help_dialog.display.helpVolume);
4151 } /* if helpType == TOPIC */
4153 { /* if helpType != TOPIC */
4154 curVolAvail = False;
4155 switch (hw->help_dialog.display.helpType)
4157 case DtHELP_TYPE_STRING:
4158 case DtHELP_TYPE_DYNAMIC_STRING:
4159 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4160 (GSSET, 32,"Help Message")));
4162 case DtHELP_TYPE_FILE:
4163 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4164 (GSSET, 33,"Help File")));
4166 case DtHELP_TYPE_MAN_PAGE:
4167 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4168 (GSSET, 34,"Manual Page")));
4171 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4172 (GSSET, 35,"Unknown Format")));
4174 } /* switch on helpType */
4175 } /* if helpType != TOPIC */
4177 /* record path in the widget */
4178 XtFree(hw->help_dialog.srch.curVolPath);
4179 hw->help_dialog.srch.curVolPath = path;
4182 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4183 (GSSET, 3,"Current")));
4184 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 4,"r"));*/
4187 /* append volume name to title */
4188 preTitle = (char *)_DTGETMESSAGE(GSSET, 60," (");
4189 preTitleString = XmStringCreateLocalized(preTitle);
4190 postTitle = (char *)_DTGETMESSAGE(GSSET, 61,")");
4191 postTitleString = XmStringCreateLocalized(postTitle);
4193 newTitle = XmStringConcat(labelString,preTitleString);
4194 XmStringFree(labelString);
4195 XmStringFree(preTitleString);
4196 labelString = newTitle;
4198 newTitle = XmStringConcat(labelString,volTitleString);
4199 XmStringFree(labelString);
4200 XmStringFree(volTitleString);
4201 labelString = newTitle;
4203 newTitle = XmStringConcat(labelString,postTitleString);
4204 XmStringFree(labelString);
4205 XmStringFree(postTitleString);
4206 labelString = newTitle;
4208 /* set the out values */
4209 if (out_curVolAvailable) *out_curVolAvailable = curVolAvail;
4210 if (out_mnemonic) *out_mnemonic = mnemonic;
4211 if (out_labelString) *out_labelString = labelString;
4212 else XmStringFree(labelString);
4220 /*****************************************************************************
4221 * Function: void CreateGlobSrchDialog()
4228 * Purpose: Creates and displays an instance of the search dialog.
4230 *****************************************************************************/
4231 static void CreateGlobSrchDialog(
4238 /* Widget topWidget; */
4239 Widget volumesFrame;
4244 XmString labelString;
4245 /* char * mnemonic; */
4246 Dimension widgetHeight;
4247 Dimension widgetBorderHeight;
4249 DtHelpListStruct *pHelpInfo;
4250 Atom wm_delete_window;
4251 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw ;
4252 XtTranslations btnTransTable;
4253 /* XtTranslations listTransTable; */
4254 /* XtTranslations mgrTransTable; */
4255 Boolean curVolAvailable;
4259 /* get state of the volume */
4260 curVolAvailable = VolumeHasIndexP (
4261 hw->help_dialog.srch.srchSources,
4262 hw->help_dialog.display.helpType,
4263 hw->help_dialog.display.helpVolume);
4265 /* Set up the translations table stuff */
4266 btnTransTable = XtParseTranslationTable(defaultBtnTranslations);
4267 /* listTransTable = XtParseTranslationTable(defaultListTranslations); */
4268 /* mgrTransTable = XtParseTranslationTable(defaultMgrTranslations); */
4270 /* Create the shell used for the dialog. */
4271 title = XtNewString(((char *)_DTGETMESSAGE(GSSET,1,"Help - Index Search")));
4273 XtSetArg (args[n], XmNtitle, title); n++;
4274 XtSetArg (args[n], XmNallowShellResize, True); n++;
4275 srchShell = XmCreateDialogShell((Widget) hw, "searchShell", args, n);
4278 /* Set the useAsyncGeo on the shell */
4280 XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
4281 XtSetValues (XtParent(srchShell), args, n); /* parent is new's shell */
4283 /* Adjust the decorations for the dialog shell of the dialog */
4285 XtSetArg(args[n], XmNmwmFunctions, 0); n++;
4286 XtSetArg (args[n], XmNmwmDecorations,
4287 MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
4288 XtSetValues (srchShell, args, n);
4291 /* Grab the window mgr close and install a close dialog
4292 callback when closed from dialog WM menu; this prevents
4293 the dialog from closing the host application. */
4294 wm_delete_window = XmInternAtom(XtDisplay(srchShell),
4295 "WM_DELETE_WINDOW", FALSE);
4296 XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
4297 XmAddWMProtocolCallback(srchShell,wm_delete_window,
4298 CloseSearchCB, (XtPointer)&hw->help_dialog.srch);
4299 XtSetValues(srchShell, args, 1);
4301 /* set the callback that positions the dialog when popped up */
4302 XtAddCallback (srchShell, XmNpopupCallback,
4303 (XtCallbackProc)_DtHelpMapCB, (XtPointer) XtParent(hw));
4305 /*** Create the form used for the dialog. ***/
4306 /* setting RESIZE_NONE is important to prevent the resultList from
4307 dynamically resizing as items with various fonts are added and
4310 XtSetArg (args[n], XmNmarginWidth, 1); n++;
4311 XtSetArg (args[n], XmNmarginHeight, 1); n++;
4312 XtSetArg (args[n], XmNshadowThickness, 1); n++;
4313 XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT); n++;
4314 XtSetArg (args[n], XmNautoUnmanage, False); n++;
4315 XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
4316 parentForm = XmCreateForm (srchShell, "parentForm", args, n);
4317 hw->help_dialog.srch.srchForm = parentForm;
4319 /*==============================================================*/
4320 /****** Create the volumes region ******/
4322 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
4323 XtSetArg (args[n], XmNtopOffset, 5); n++;
4324 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4325 XtSetArg (args[n], XmNrightOffset, 5); n++;
4326 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4327 XtSetArg (args[n], XmNleftOffset, 5); n++;
4328 XtSetArg (args[n], XmNmarginWidth, 5); n++;
4329 XtSetArg (args[n], XmNmarginHeight, 2); n++;
4330 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
4331 volumesFrame = XmCreateFrame(parentForm, "volFrame", args, n);
4332 XtManageChild (volumesFrame);
4334 /* put form inside frame */
4335 volumesForm = XmCreateForm (volumesFrame, "volumesForm", args, 0);
4336 XtManageChild (volumesForm);
4338 /* create the frame title */
4339 labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,2, "Search")));
4341 XtSetArg (args[n], XmNlabelString, labelString); n++;
4342 XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
4343 XtSetArg (args[n], XmNtraversalOn, False); n++;
4344 frameTitle = XmCreateLabelGadget(volumesFrame, "volFrameTitle", args, n);
4345 XtManageChild (frameTitle);
4346 XmStringFree (labelString);
4348 /* create Current Volume radio button */
4349 /* Use a dummy label until CreateCurVolBtnLabel can be used.
4350 It refs the srchCurVolRadBtn widget and other things that need
4353 labelString = XmStringCreateLocalized (" ");
4355 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4356 XtSetArg (args[n], XmNset, TRUE); n++;
4358 XtSetArg(args[n], XmNlabelString, labelString); n++;
4359 XtSetArg (args[n], XmNmarginHeight, 0); n++;
4360 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
4361 XtSetArg (args[n], XmNtopOffset, 0); n++;
4362 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4363 XtSetArg (args[n], XmNleftOffset, 5); n++;
4364 /* Attaching to form causes the hilite outline of the button to
4365 stretch to the form edge when selected. But it also forces
4366 the form to resize when the current volume title is too big
4367 for the available space. */
4368 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4369 XtSetArg (args[n], XmNrightOffset, 10); n++;
4370 XtSetArg (args[n], XmNbottomOffset, 0); n++;
4371 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4372 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4373 hw->help_dialog.srch.curVolRadBtn =
4374 XmCreateToggleButtonGadget(volumesForm,"srchCurVolRadBtn",args,n);
4375 XtAddCallback(hw->help_dialog.srch.curVolRadBtn,XmNvalueChangedCallback,
4376 UpdateSearchVolumesCB, (XtPointer) hw);
4377 /* ??? XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False); */
4378 XtManageChild (hw->help_dialog.srch.curVolRadBtn);
4379 XmStringFree (labelString);
4381 /* create All Volumes radio button */
4382 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4383 (GSSET, 5,"All Volumes")));
4384 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 7,"A"));*/
4387 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4388 XtSetArg (args[n], XmNset, FALSE); n++;
4389 XtSetArg (args[n], XmNlabelString, labelString); n++;
4390 XtSetArg (args[n], XmNmarginHeight, 0); n++;
4391 XtSetArg (args[n], XmNmarginWidth, 2); n++;
4392 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4393 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.curVolRadBtn); n++;
4394 XtSetArg (args[n], XmNtopOffset, 1); n++;
4395 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4396 XtSetArg (args[n], XmNleftOffset, 5); n++;
4397 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4398 hw->help_dialog.srch.allVolRadBtn =
4399 XmCreateToggleButtonGadget(volumesForm,"srchAllVolRadBtn",args, n);
4400 XtAddCallback(hw->help_dialog.srch.allVolRadBtn,XmNvalueChangedCallback,
4401 UpdateSearchVolumesCB, (XtPointer) hw);
4402 XtManageChild (hw->help_dialog.srch.allVolRadBtn);
4403 XmStringFree (labelString);
4405 /* create Selected Volumes radio button */
4406 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4407 (GSSET, 6,"Selected")));
4408 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 9,"d"));*/
4411 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4412 XtSetArg (args[n], XmNlabelString, labelString); n++;
4413 XtSetArg (args[n], XmNmarginHeight, 0); n++;
4414 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4415 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
4416 XtSetArg (args[n], XmNtopOffset, 1); n++;
4417 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4418 XtSetArg (args[n], XmNleftOffset, 5); n++;
4419 XtSetArg (args[n], XmNbottomOffset, 2); n++;
4420 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4421 hw->help_dialog.srch.selVolRadBtn =
4422 XmCreateToggleButtonGadget(volumesForm,"srchSelVolRadBtn", args, n);
4423 XtAddCallback(hw->help_dialog.srch.selVolRadBtn,XmNvalueChangedCallback,
4424 UpdateSearchVolumesCB, (XtPointer) hw);
4425 XtManageChild (hw->help_dialog.srch.selVolRadBtn);
4426 XmStringFree (labelString);
4429 /* Create Selected... button */
4430 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4431 (GSSET, 7,"Select Volumes...")));
4434 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4435 XtSetArg (args[n], XmNtopOffset, 0); n++;
4436 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
4437 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4438 XtSetArg (args[n], XmNrightOffset, 10); n++;
4439 XtSetArg (args[n], XmNbottomOffset, 2); n++;
4440 XtSetArg (args[n], XmNmarginTop, 0); n++;
4441 XtSetArg (args[n], XmNmarginHeight, 3); n++;
4442 XtSetArg (args[n], XmNlabelString, labelString); n++;
4443 hw->help_dialog.srch.selectBtn =
4444 XmCreatePushButtonGadget(volumesForm,"selectBtn", args, n);
4445 XtAddCallback (hw->help_dialog.srch.selectBtn, XmNactivateCallback,
4446 OpenSelectDialogCB, (XtPointer) hw);
4447 XtManageChild (hw->help_dialog.srch.selectBtn);
4448 XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
4449 XmStringFree (labelString);
4451 /****** Create the show selection region ******/
4453 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4454 XtSetArg (args[n], XmNtopWidget, volumesFrame); n++;
4455 XtSetArg (args[n], XmNtopOffset, 5); n++;
4456 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4457 XtSetArg (args[n], XmNrightOffset, 5); n++;
4458 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4459 XtSetArg (args[n], XmNleftOffset, 5); n++;
4460 XtSetArg (args[n], XmNmarginWidth, 5); n++;
4461 XtSetArg (args[n], XmNmarginHeight, 2); n++;
4462 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
4463 showFrame = XmCreateFrame(parentForm, "showFrame", args, n);
4464 XtManageChild (showFrame);
4466 /* FIX: is this doing enough? Goal: CR activation of FullIndex */
4467 /* Setup the proper translation on the title box widget */
4468 /* XtAugmentTranslations(showFrame, mgrTransTable); */
4470 /* put form inside frame */
4471 showForm = XmCreateForm (showFrame, "showForm", args, 0);
4472 XtManageChild (showForm);
4474 /* create the frame title */
4475 labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,8, "Show")));
4477 XtSetArg (args[n], XmNlabelString, labelString); n++;
4478 XtSetArg (args[n], XmNtraversalOn, False); n++;
4479 XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
4480 frameTitle = XmCreateLabelGadget(showFrame, "showFrameTitle", args, n);
4481 XtManageChild (frameTitle);
4482 XmStringFree (labelString);
4484 /* create the All Entries button */
4485 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4486 (GSSET, 9,"Complete Index")));
4489 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4490 XtSetArg (args[n], XmNset, True); n++;
4491 XtSetArg (args[n], XmNlabelString, labelString); n++;
4492 XtSetArg (args[n], XmNmarginHeight, 1); n++;
4493 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
4494 XtSetArg (args[n], XmNtopOffset, 0); n++;
4495 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4496 XtSetArg (args[n], XmNleftOffset, 5); n++;
4497 XtSetArg (args[n], XmNbottomOffset, 0); n++;
4498 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4499 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4500 hw->help_dialog.srch.fullIndexRadBtn =
4501 XmCreateToggleButtonGadget(showForm,"srchFullIndexRadBtn",args,n);
4502 XtAddCallback(hw->help_dialog.srch.fullIndexRadBtn,XmNvalueChangedCallback,
4503 UpdateIndexSelectionCB, (XtPointer) hw);
4504 XtManageChild (hw->help_dialog.srch.fullIndexRadBtn);
4505 XmStringFree (labelString);
4507 /* create Contains radio button */
4508 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4509 (GSSET, 10,"Entries with:")));
4510 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 16,"n"));*/
4513 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4514 XtSetArg (args[n], XmNset, False); n++;
4515 XtSetArg (args[n], XmNlabelString, labelString); n++;
4516 XtSetArg (args[n], XmNmarginHeight, 1); n++;
4517 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4518 XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn);n++;
4519 XtSetArg (args[n], XmNtopOffset, 1); n++;
4520 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4521 XtSetArg (args[n], XmNleftOffset, 5); n++;
4522 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4523 XtSetArg (args[n], XmNbottomOffset, 4); n++;
4524 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4525 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4526 hw->help_dialog.srch.containsRadBtn =
4527 XmCreateToggleButtonGadget(showForm,"srchContainsRadBtn",args,n);
4528 XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNvalueChangedCallback,
4529 UpdateIndexSelectionCB, (XtPointer) hw);
4530 XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNdisarmCallback,
4531 ContainsDisarmCB, (XtPointer) hw);
4532 XtManageChild (hw->help_dialog.srch.containsRadBtn);
4533 XmStringFree (labelString);
4535 /* create the search name text field */
4537 XtSetArg (args[n], XmNvalue, ""); n++;
4538 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4539 XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn); n++;
4540 XtSetArg (args[n], XmNtopOffset, 0); n++;
4541 XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
4542 XtSetArg (args[n], XmNleftWidget,hw->help_dialog.srch.containsRadBtn); n++;
4543 XtSetArg (args[n], XmNleftOffset, 5); n++;
4544 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4545 XtSetArg (args[n], XmNrightOffset, 10); n++;
4546 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4547 XtSetArg (args[n], XmNbottomOffset, 3); n++;
4548 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4549 XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
4550 hw->help_dialog.srch.wordField =
4551 XmCreateTextField (showForm,"srchWord",args, n);
4552 XtSetSensitive(hw->help_dialog.srch.wordField,False);
4553 XtManageChild (hw->help_dialog.srch.wordField);
4554 /* Because the actionBtn is the default button on the form,
4555 and it activates a search, we do not need to (nor do we want
4556 to, since ActionButtonCB toggles between states) make it
4557 a callback on activation of the text field */
4558 XtAddCallback (hw->help_dialog.srch.wordField, XmNvalueChangedCallback,
4559 UpdateSearchStartStatusCB, (XtPointer) hw);
4561 /* Setup the proper translation on the text field widget */
4562 XtAugmentTranslations(hw->help_dialog.srch.wordField, btnTransTable);
4565 /* Create a separator search specs and result area */
4567 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4568 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4569 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4570 XtSetArg (args[n], XmNtopWidget, showFrame); n++;
4571 XtSetArg (args[n], XmNtopOffset, 10); n++;
4572 separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
4573 XtManageChild (separator);
4575 /*==============================================================*/
4576 /****** result related stuff *******/
4577 /* Create result List Label */
4579 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4580 XtSetArg (args[n], XmNtopWidget, separator); n++;
4581 XtSetArg (args[n], XmNtopOffset, 10); n++;
4582 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4583 XtSetArg (args[n], XmNleftOffset, 10); n++;
4584 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4585 XtSetArg (args[n], XmNrightOffset, 10); n++;
4586 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4587 hw->help_dialog.srch.statusLabel =
4588 XmCreateLabelGadget (parentForm, "resultListLabel", args, n);
4589 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,True,0); /* installs a label */
4590 XtManageChild (hw->help_dialog.srch.statusLabel);
4592 /* Create our result topics scrolled list (not placed on form) */
4594 XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
4595 XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
4596 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4597 XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
4598 hw->help_dialog.srch.resultList =
4599 XmCreateScrolledList (parentForm, "resultList", args, n);
4600 XtManageChild (hw->help_dialog.srch.resultList);
4602 XtAddCallback (hw->help_dialog.srch.resultList, XmNsingleSelectionCallback,
4603 ProcessResultSelectionCB, (XtPointer) hw);
4604 XtAddCallback (hw->help_dialog.srch.resultList, XmNdefaultActionCallback,
4605 ProcessResultSelectionCB, (XtPointer) hw);
4607 /* Set the constraints on our scrolled list (place on form) */
4609 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4610 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.statusLabel); n++;
4611 XtSetArg (args[n], XmNtopOffset, 5); n++;
4612 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4613 XtSetArg (args[n], XmNleftOffset, 10); n++;
4614 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4615 XtSetArg (args[n], XmNrightOffset, 10); n++;
4616 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4617 XtSetArg (args[n], XmNbottomOffset, 70); n++;
4618 /* 70 is just a rough value that will be updated with a calculated
4619 value below, after we know the height of the buttons */
4620 XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
4622 /* Create a separator between the buttons */
4624 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4625 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4626 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4627 XtSetArg (args[n], XmNtopWidget,
4628 XtParent (hw->help_dialog.srch.resultList)); n++;
4629 XtSetArg (args[n], XmNtopOffset, 5); n++;
4630 separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
4631 XtManageChild (separator);
4633 /***** search spec-related stuff *****/
4634 /* Create start button (left of stop button)*/
4635 _DtHelpProcessLock();
4636 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4637 (GSSET, START_SEARCH_CAT,START_SEARCH_STR)));
4638 _DtHelpProcessUnlock();
4639 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
4642 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4643 XtSetArg (args[n], XmNtopWidget, separator); n++;
4644 XtSetArg (args[n], XmNtopOffset, 5); n++;
4645 /* L & R position set below */
4646 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4647 XtSetArg (args[n], XmNbottomOffset, 5); n++;
4648 /*XtSetArg (args[n], XmNmarginHeight, 3); n++;*/
4649 XtSetArg (args[n], XmNlabelString, labelString); n++;
4650 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4651 hw->help_dialog.srch.actionBtn =
4652 XmCreatePushButtonGadget(parentForm,"actionBtn", args, n);
4653 XtAddCallback (hw->help_dialog.srch.actionBtn, XmNactivateCallback,
4654 ActionButtonCB, (XtPointer) hw);
4655 XtSetSensitive (hw->help_dialog.srch.actionBtn,False);
4656 XtManageChild (hw->help_dialog.srch.actionBtn);
4657 XmStringFree (labelString);
4659 XtSetArg (args[0], XmNdefaultButton, hw->help_dialog.srch.actionBtn);
4660 XtSetValues (parentForm, args, 1);
4662 /* Build the Cancel Button */
4663 _DtHelpProcessLock();
4664 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4665 (GSSET, CLOSE_BTN_CAT,CLOSE_BTN_STR)));
4666 _DtHelpProcessUnlock();
4667 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 25,CLOSE_BTN_MNEM));*/
4669 XtSetArg (args[n], XmNlabelString, labelString); n++;
4670 /* L & R position set below */
4671 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4672 XtSetArg (args[n], XmNtopWidget, separator); n++;
4673 XtSetArg (args[n], XmNtopOffset, 5); n++;
4674 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4675 XtSetArg (args[n], XmNbottomOffset, 5); n++;
4676 XtSetArg (args[n], XmNmarginHeight, 3); n++;
4677 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4678 hw->help_dialog.srch.closeBtn =
4679 XmCreatePushButtonGadget (parentForm, "srchCloseBtn", args, n);
4681 XtAddCallback(hw->help_dialog.srch.closeBtn,
4682 XmNactivateCallback, CloseSearchCB,(XtPointer) &hw->help_dialog.srch);
4684 XtManageChild (hw->help_dialog.srch.closeBtn);
4685 XmStringFree (labelString);
4687 /* Build the Help button */
4688 _DtHelpProcessLock();
4689 labelString = XmStringCreateLocalized((char *)_DTGETMESSAGE
4690 (GSSET, HELP_BTN_CAT,HELP_BTN_STR));
4691 _DtHelpProcessUnlock();
4692 /*mnemonic = (char *)_DTGETMESSAGE(GSSET, 27,HELP_BTN_MNEM);*/
4695 XtSetArg (args[n], XmNlabelString, labelString); n++;
4696 /* L & R position set below */
4697 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4698 XtSetArg (args[n], XmNtopWidget, separator); n++;
4699 XtSetArg (args[n], XmNtopOffset, 5); n++;
4700 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4701 XtSetArg (args[n], XmNbottomOffset, 5); n++;
4702 XtSetArg (args[n], XmNmarginHeight, 3); n++;
4703 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4704 hw->help_dialog.srch.helpBtn =
4705 XmCreatePushButtonGadget (parentForm, "srchHelpBtn", args, n);
4706 XtManageChild (hw->help_dialog.srch.helpBtn);
4707 XmStringFree (labelString);
4709 pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexHelpBtn_STR,
4710 (Widget) hw, &hw->help_dialog.help,
4711 &hw->help_dialog.help.pHelpListHead);
4712 XtAddCallback(hw->help_dialog.srch.helpBtn, XmNactivateCallback,
4713 _DtHelpCB, (XtPointer) pHelpInfo);
4715 /*==============================================================*/
4716 /****** finishing touches *******/
4717 /* set the Form cancel button (for KCancel) */
4719 XtSetArg (args[n], XmNcancelButton, hw->help_dialog.srch.closeBtn); n++;
4720 XtSetValues (parentForm, args, n);
4722 { /* position buttons */
4723 /* This code adds up the sizes of the buttons to go into
4724 the bottom row and calculates the form position percentages.
4725 All buttons are the same size, and are able to hold all
4726 the strings that may be dynamically placed in them.
4727 All buttons are 5% apart. */
4728 /* This code is specifically written to handle 3 buttons
4729 and assumes that the first 3 strings are to the ActionBtn */
4731 Dimension maxWidth = 0;
4732 Dimension borderWidth = 0;
4733 Dimension sumWidth = 0;
4735 float posList[11]; /* need 11 due to algorithm, which uses index 10 */
4736 XmFontList fontList = NULL;
4739 /* get the fontList for the button */
4740 XtSetArg (args[0], XmNborderWidth, &borderWidth);
4741 XtSetArg (args[1], XmNfontList, &fontList);
4742 XtGetValues (hw->help_dialog.srch.actionBtn, args, 2);
4744 #define BETBUTSPACE 5 /* pixels */
4745 sumWidth = BETBUTSPACE; /* left side space */
4746 posList[0] = (float) sumWidth;
4747 for (i=0; i<NUMSTRS; i++)
4749 XmString labelString;
4751 _DtHelpProcessLock();
4752 s_GlobSrchDlgBtnStrs[i] = (char *) _DTGETMESSAGE(GSSET,
4753 s_GlobSrchDlgBtnCatNum[i],s_GlobSrchDlgBtnStrs[i]);
4754 labelString = XmStringCreateLocalized(s_GlobSrchDlgBtnStrs[i]);
4755 _DtHelpProcessUnlock();
4756 #define MARGINS 4 /* pixel margins: 2=L, 2=R */
4757 width = XmStringWidth(fontList,labelString) + borderWidth + MARGINS;
4758 if (i<=2) maxWidth = max(width,maxWidth);
4759 if (i==2) width = maxWidth; /* 1st three labels go in 1st button */
4760 if (i>=2) /* after scanning just labels, do buttons */
4763 posList[i*2+1] = (float) sumWidth;
4764 sumWidth += BETBUTSPACE;
4765 posList[i*2+2] = (float) sumWidth;
4767 XmStringFree(labelString);
4768 } /* for calcing widths */
4770 /* scale pixels to percent */
4771 scale = 100.0 / (float) sumWidth;
4774 XtSetArg (args[n], XmNwidth, maxWidth); n++;
4775 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
4776 XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[0]*scale)); n++;
4777 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
4778 XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[5]*scale)); n++;
4779 XtSetValues (hw->help_dialog.srch.actionBtn, args, n);
4782 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
4783 XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[6]*scale)); n++;
4784 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
4785 XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[7]*scale)); n++;
4786 XtSetValues (hw->help_dialog.srch.closeBtn, args, n);
4789 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
4790 XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[8]*scale)); n++;
4791 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
4792 XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[9]*scale)); n++;
4793 XtSetValues (hw->help_dialog.srch.helpBtn, args, n);
4796 { /* set the proper offset between the bottom of the results list
4797 and the bottom of the form to maintain a constant sized
4801 /* first calc offset of list to form bottom based on earlier sizes */
4802 #define KNOWN_OFFSETS_BELOW_LIST 20 /* actually only 15, but 15 fails */
4804 XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
4805 XtSetArg(args[n], XmNheight, &widgetHeight); n++;
4806 XtGetValues(hw->help_dialog.srch.actionBtn, args, n);
4807 offset = widgetHeight + 2 * widgetBorderHeight;
4808 XtGetValues(separator, args, n);
4809 offset += widgetHeight + 2 * widgetBorderHeight;
4810 XtGetValues(XtParent(hw->help_dialog.srch.resultList), args, 1);
4811 offset += widgetBorderHeight;
4812 offset += KNOWN_OFFSETS_BELOW_LIST;
4814 /* then set the offset */
4816 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4817 XtSetArg (args[n], XmNbottomOffset, offset); n++;
4818 XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
4821 /** force tabs to go to each widget and in right order **/
4822 XtSetArg (args[0], XmNnavigationType, XmSTICKY_TAB_GROUP);
4823 XtSetValues (hw->help_dialog.srch.curVolRadBtn,args,1);
4824 XtSetValues (hw->help_dialog.srch.allVolRadBtn,args,1);
4825 XtSetValues (hw->help_dialog.srch.selVolRadBtn,args,1);
4826 XtSetValues (hw->help_dialog.srch.selectBtn,args,1);
4827 XtSetValues (hw->help_dialog.srch.fullIndexRadBtn,args,1);
4828 XtSetValues (hw->help_dialog.srch.containsRadBtn,args,1);
4829 XtSetValues (hw->help_dialog.srch.wordField,args,1);
4830 XtSetValues (hw->help_dialog.srch.resultList,args,1);
4831 XtSetValues (hw->help_dialog.srch.actionBtn,args,1);
4832 XtSetValues (hw->help_dialog.srch.closeBtn,args,1);
4833 XtSetValues (hw->help_dialog.srch.helpBtn,args,1);
4835 /** put focus on the text field **/
4836 XtSetArg (args[0], XmNinitialFocus, hw->help_dialog.srch.wordField);
4837 XtSetValues (parentForm,args,1);
4839 /* Add the proper help callback to the print dialog shell "F1" support */
4840 pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexShell_STR,
4841 (Widget) hw, &hw->help_dialog.help,
4842 &hw->help_dialog.help.pHelpListHead);
4843 XtAddCallback(parentForm, XmNhelpCallback,
4844 _DtHelpCB, (XtPointer) pHelpInfo);
4848 /*****************************************************************************
4849 * Function: updateDisplay()
4852 * Parameters: hw: the help widget
4856 * Purpose: forces an update on index search dialog widgets
4858 *****************************************************************************/
4859 static int updateDisplay(
4860 DtHelpDialogWidget hw)
4862 XmUpdateDisplay((Widget)hw->help_dialog.srch.actionBtn);/*DBG*/
4863 XmUpdateDisplay((Widget)hw->help_dialog.srch.curVolRadBtn);/*DBG*/
4864 XmUpdateDisplay((Widget)hw->help_dialog.srch.allVolRadBtn);/*DBG*/
4865 XmUpdateDisplay((Widget)hw->help_dialog.srch.selVolRadBtn);/*DBG*/
4866 XmUpdateDisplay((Widget)hw->help_dialog.srch.selectBtn);/*DBG*/
4867 XmUpdateDisplay((Widget)hw->help_dialog.srch.fullIndexRadBtn);/*DBG*/
4868 XmUpdateDisplay((Widget)hw->help_dialog.srch.containsRadBtn);/*DBG*/
4869 XmUpdateDisplay((Widget)hw->help_dialog.srch.wordField);/*DBG*/
4870 XmUpdateDisplay((Widget)hw->help_dialog.srch.statusLabel);/*DBG*/
4871 XmUpdateDisplay((Widget)hw->help_dialog.srch.resultList);/*DBG*/
4872 XmUpdateDisplay((Widget)hw->help_dialog.srch.closeBtn);/*DBG*/
4873 XmUpdateDisplay((Widget)hw->help_dialog.srch.helpBtn);/*DBG*/
4874 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));/*DBG*/
4880 /*****************************************************************************
4881 * Function: void _DtHelpGlobSrchDisplayDialog()
4884 * Parameters: parent Specifies the parent widget
4885 * searchWord word to put into searchWord field
4886 * remove this when integrated into DtHelp:
4887 * curVolume volume considered the current volume
4891 * Purpose: Setsup the proper data in the search dialog and
4892 * displays an instance of the search dialog.
4894 *****************************************************************************/
4895 void _DtHelpGlobSrchDisplayDialog(
4900 DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
4901 XmToggleButtonCallbackStruct status; /* the call data */
4902 Widget sourceBtn; /* widget owning event */
4905 XmString labelString = NULL;
4909 /* make the dialog itself */
4910 if (NULL == hw->help_dialog.srch.srchForm)
4912 CreateGlobSrchDialog((Widget) hw,searchWord);
4914 /* create the button label */
4915 CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
4916 XtSetArg (args[0], XmNlabelString, labelString);
4917 XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, 1);
4918 XmStringFree (labelString);
4920 /*** map widget and update display before doing any searching ***/
4921 /* Make sure the Search Dialog is managed */
4922 XtManageChild(hw->help_dialog.srch.srchForm);
4923 XtMapWidget(hw->help_dialog.srch.srchForm);
4925 /* set focus to contains word */
4926 XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
4928 /* force several updates to make sure it is fully displayed and
4929 that height/width are correctly inited */
4930 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
4931 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
4932 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
4934 /*** now update settings, which may also invoke a search ***/
4935 /* set the cur vol btn sensitivity */
4936 UpdateCurVolBtnSens(hw,True);
4938 /* set default show index state */
4939 /* set full index if current vol has an index, contains word if not */
4940 if (hw->help_dialog.srch.curVolRadBtnSens) /* set in UpdateCurVolBtnSens*/
4941 sourceBtn = hw->help_dialog.srch.fullIndexRadBtn;
4943 sourceBtn = hw->help_dialog.srch.containsRadBtn;
4945 /* set the show index state */
4946 status.reason = XmCR_VALUE_CHANGED;
4948 status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
4949 UpdateIndexSelectionCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
4950 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
4952 updateDisplay(hw); /* DBG */
4954 #if 0 /* 11/23/94 */
4955 /** Set min size for the dialog **/
4957 XtSetArg(args[n], XmNheight, &height); ++n;
4958 XtSetArg(args[n], XmNwidth, &width); ++n;
4959 XtGetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
4961 XtSetArg(args[n], XmNminHeight, height - 200); ++n; /* 200: arbitrary */
4962 XtSetArg(args[n], XmNminWidth, width); ++n;
4963 XtSetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
4966 else /* properly update dialog to support new word and cur vol */
4968 /* fixup current volume, if need be */
4969 _DtHelpGlobSrchUpdateCurVol((Widget)hw);
4971 /* fixup search word, if need be */
4972 if (NULL != searchWord)
4974 String srchWord = XtNewString(searchWord);
4975 /* srchWord is freed or used in CheckSearchWord() */
4976 if (CheckSearchWord(hw,srchWord,True) == True)
4977 { /* words are different */
4978 /* free all hit-related data and reset flags */
4979 HitListFreeAllVolHits(hw,True); /*True=free everything*/
4983 /* if its not managed, manage it */
4984 if ( XtIsManaged(hw->help_dialog.srch.srchForm) == False )
4986 /* manage and map the Search Dialog */
4987 XtManageChild(hw->help_dialog.srch.srchForm);
4988 XtMapWidget((Widget)hw->help_dialog.srch.srchForm);
4990 /* see if the selection dialog was already open */
4991 if ( hw->help_dialog.srch.selectionDlg
4992 && XtIsManaged(hw->help_dialog.srch.selectionDlg) )
4994 XtManageChild(hw->help_dialog.srch.selectionDlg);
4995 XtMapWidget(hw->help_dialog.srch.selectionDlg);
4998 else /* if it is managed, bring it forward */
5000 Widget parent = XtParent(hw->help_dialog.srch.srchForm);
5001 XRaiseWindow ( XtDisplay(parent), XtWindow(parent) );
5006 if (hw->help_dialog.srch.hitsFound == True)
5007 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
5009 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
5013 } /* end if create a new dialog */
5018 /*****************************************************************************
5019 * Function: void _DtHelpGlobSrchUpdateCurVol()
5021 * Parameters: new the help widget
5025 * Purpose: Adjusts the current volume of the dialog
5027 *****************************************************************************/
5028 void _DtHelpGlobSrchUpdateCurVol(
5032 DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
5035 if ( NULL == hw->help_dialog.srch.srchForm )
5037 if ( NULL == hw->help_dialog.srch.srchForm
5038 || XtIsManaged(hw->help_dialog.srch.srchForm) == False )
5040 return; /* RETURN */
5042 /* get full pathname for the volume */
5044 if (hw->help_dialog.display.helpVolume)
5045 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE,
5046 /* FIX: will helpVolume have matching path? */
5047 hw->help_dialog.display.helpVolume,
5048 _DtHelpFileSuffixList,False,R_OK);
5050 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
5051 && hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC
5053 && NULL != hw->help_dialog.srch.curVolPath
5054 && _DtHelpFileIsSameP(path,hw->help_dialog.srch.curVolPath,
5055 GetVolumeInfoCB, _DtHELP_FILE_NAME,
5056 hw->help_dialog.help.pDisplayArea) )
5058 /* leave current status as is */
5060 return; /* RETURN */
5064 /* a different current volume or change of topic */
5066 XmString labelString;
5069 /* if still searching previous cur volume, stop any search in progress */
5070 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
5071 && hw->help_dialog.srch.workProcId)
5073 /* cancel the search */
5074 StopSearchCB(NULL,(XtPointer) hw, NULL);
5076 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
5077 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
5079 /* zero search data */
5080 hw->help_dialog.srch.volLeftCnt = 0;
5081 hw->help_dialog.srch.curSrchVol = NULL;
5083 /* assumption is, that even though the search was incomplete,
5084 nothing bad will happen if we don't free the hit data,
5085 and the search could resume where left off, if necessary. */
5088 CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
5089 XtSetArg(args[0],XmNlabelString,labelString);
5090 XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
5091 XmStringFree(labelString);
5093 /* set the cur vol btn sensitivity */
5094 UpdateCurVolBtnSens(hw,False);
5096 /* set state of start button correctly */
5097 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
5099 /* and search if needed */
5100 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources )
5102 /* if to search a volume, start the search */
5103 if (hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC)
5104 StartSearchCB(NULL,(XtPointer) hw, NULL);
5105 else /* if current isn't a volume, clear the display & update status */
5107 DeleteListContents(&hw->help_dialog.srch);
5108 StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
5116 /*****************************************************************************
5117 * Function: void _DtHelpGlobSrchInitVars()
5119 * Parameters: srch search main data structure
5123 * Purpose: Init the contents of the control data structure
5125 *****************************************************************************/
5126 void _DtHelpGlobSrchInitVars(
5127 _DtHelpGlobSearchStuff * srch)
5129 /* set the font resource */
5130 if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
5131 srch->hitPrefixFont = XtNewString(srch->hitPrefixFont);
5133 /* File Selection Dialog font list */
5134 srch->volTitlesFontList = NULL;
5136 /* Set our search dialog widgets to NULL */
5137 srch->srchForm = NULL;
5138 srch->actionBtn = NULL;
5139 srch->curVolRadBtn = NULL;
5140 srch->allVolRadBtn = NULL;
5141 srch->selVolRadBtn = NULL;
5142 srch->selectBtn = NULL;
5143 srch->fullIndexRadBtn = NULL;
5144 srch->containsRadBtn = NULL;
5145 srch->wordField = NULL;
5146 srch->statusLabel = NULL;
5147 srch->resultList = NULL;
5148 srch->gotoBtn = NULL;
5149 srch->closeBtn = NULL;
5150 srch->helpBtn = NULL;
5151 srch->selectionDlg = NULL;
5153 /* init dialog content variables */
5154 srch->curVolPath = NULL;
5155 srch->rawWordStr = NULL;
5156 srch->normWordStr = NULL;
5157 srch->localeWordStr = NULL;
5158 srch->wordFieldFirstChar = 0;
5159 srch->wordFieldLen = 0;
5160 srch->statusLineUsage = 0; /* empty */
5162 /* init srch processing variables */
5163 srch->iconv3Codeset = NULL; /* iconv(3)-compatible code set of current locale */
5164 srch->iconv3Context = NULL;
5165 srch->srchSources = _DtHelpGlobSrchVolumeUndef; /* radio btn usage */
5166 srch->curSrchVol = NULL; /* volume currently in search */
5167 srch->hitsFontLoaded= False; /* is font loaded? */
5168 srch->volScanDone = False; /* is the volume list complete? */
5169 srch->fullIndex = False;
5170 srch->hitsFound = False; /* state of search */
5171 srch->readyToStart = False; /* state of search */
5172 srch->searchInProgress= False; /* state of search */
5173 srch->curVolRadBtnSens = False;
5174 srch->volLeftCnt = 0;
5175 srch->volListHead = NULL; /* info on search topics found */
5176 srch->workProcId = NULL;
5180 /*****************************************************************************
5181 * Function: void _DtHelpGlobSrchCleanAndClose()
5183 * Parameters: srch search main data structure
5184 * destroy flag to signal srch dialog should be destroyed
5188 * Purpose: Free the contents of the control data structure
5190 *****************************************************************************/
5191 void _DtHelpGlobSrchCleanAndClose(
5192 _DtHelpGlobSearchStuff * srch,
5195 /* close conversion context */
5196 _DtHelpCeIconvClose(&srch->iconv3Context);
5198 /* free the font list */
5199 if(srch->volTitlesFontList)
5201 XmFontListFree(srch->volTitlesFontList);
5202 srch->volTitlesFontList = NULL;
5206 * Make sure CloseSearchCB does not try using an invalid
5207 * widget id in its XtUnmanageChild and XtUnmapWidget calls.
5210 srch->srchForm = NULL;
5212 /* make dialog invisible; update sensitivities */
5213 CloseSearchCB(NULL,(XtPointer)srch, NULL);
5215 /* Destroy our index search dialog? */
5218 /* set the font resource */
5219 if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
5220 XtFree(srch->hitPrefixFont);
5223 * mark widgets as destroyed.
5224 * The XtDestroyWidget that called me will have called the destroy
5225 * callback of the widgets. So I don't have to do anything except
5226 * make sure I know they are destroyed.
5228 srch->selectionDlg = NULL;
5229 srch->srchForm = NULL;
5230 srch->resultList = NULL;
5232 /* free other data released to search dialog */
5235 /* free the locale word string, if allocated
5236 * (i.e. diff from normWordStr) */
5237 if(srch->localeWordStr!=srch->normWordStr)
5239 XtFree(srch->localeWordStr);
5240 srch->localeWordStr=NULL;
5242 XtFree(srch->normWordStr);
5243 srch->normWordStr=NULL;
5244 XtFree(srch->rawWordStr);
5245 srch->rawWordStr=NULL;
5246 XtFree(srch->curVolPath);
5247 srch->curVolPath=NULL;
5248 XtFree(srch->iconv3Codeset);
5249 srch->iconv3Codeset = NULL;