2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: GlobSearch.c /main/21 1999/11/11 10:59:15 mgreess $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: DtHelp Project
31 ** Description: Builds and displays an instance of a DtHelp GlobSearch
34 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
35 ** (c) Copyright 1993, 1994 International Business Machines Corp.
36 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
37 ** (c) Copyright 1993, 1994 Novell, Inc.
41 ****************************************************************************
42 ************************************<+>*************************************/
43 #include <sys/param.h>
47 #include <sys/utsname.h>
50 #include <stdlib.h> /* for MB_CUR_MAX */
51 #include <unistd.h> /* R_OK */
52 #include <locale.h> /* getlocale(), LOCALE_STATUS */
56 # include <libgen.h> /* for regcmp, regex */
59 # include <regex.h> /* for regcomp, regexec */
68 #include <Xm/LabelG.h>
69 #include <Xm/ScrolledW.h>
70 #include <Xm/SeparatoG.h>
71 #include <Xm/PushBG.h>
73 #include <Xm/DialogS.h>
74 #include <Xm/MwmUtil.h>
75 #include <Xm/Protocols.h>
76 #include <Xm/RowColumn.h>
77 #include <Xm/SelectioB.h>
78 #include <Xm/ToggleBG.h>
80 #include <X11/Intrinsic.h>
81 #include <X11/Shell.h>
82 #include <X11/ShellP.h>
83 #include <X11/Xutil.h>
84 #include <X11/keysymdef.h>
87 #include <Dt/HelpDialog.h>
93 #include "StringFuncsI.h"
94 #include "DisplayAreaI.h"
95 #include "HelpDialogP.h"
96 #include "HelpDialogI.h"
97 #include "HelpAccessI.h"
98 #include "HelpUtilI.h"
100 #include "GlobSearchI.h"
101 #include "FileListUtilsI.h"
102 #include "FileUtilsI.h"
104 #include "HelpXlate.h"
105 #include "VolSelectI.h"
108 /******** TYPES ***********/
110 SEARCH_RESULTS_STATUS = 1,
115 FIRST_PROMPT_STATUS = 6
118 static Boolean VolumeHasIndexP (
119 _DtHelpGlobSrchSources srchSource,
122 static void DeleteListContents(
123 _DtHelpGlobSearchStuff * srch);
124 static void StatusLabelUpdate(
125 DtHelpDialogWidget hw,
126 ResultsStatus status,
129 static void ResultsListUpdate(
130 DtHelpDialogWidget hw,
131 _DtHelpFileEntry newFile);
132 static void StopSearchCB(
134 XtPointer clientData,
136 static void VolNameDisplay(
137 DtHelpDialogWidget hw,
138 _DtHelpFileEntry file,
140 static int VolHitsDisplay (
141 DtHelpDialogWidget hw,
142 _DtHelpFileEntry file);
143 static void UpdateSearchVolumesCB(
145 XtPointer clientData,
147 static void UpdateSearchStartStatusCB(
149 XtPointer clientData,
152 /********** CONSTANTS *************/
153 #define DIR_SLASH '/'
156 /* message catalog set number for GlobSearch.c */
159 #define DONT_SET (-1) /* used as third value of a Boolean */
161 #define HIT_FONT_RES_NAME "*helpSearchMonoFont"
162 #define HIT_FONT_RES_CLASS "*HelpSearchMonoFont"
163 #define PREFIX_FONT_SPEC "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
164 #define PREFIX_FONT_SPEC1 "-dt-application-bold-r-normal-*-*-140-*-*-m-*-iso8859-1"
165 #define PREFIX_FONT_SPEC2 "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
166 #define PREFIX_FONT_SPEC3 "courb14" /* non CDE platforms */
167 #define PREFIX_FONT_TAG "prefixFontTag"
169 #define START_SEARCH_CAT s_GlobSrchDlgBtnCatNum[0]
170 #define START_SEARCH_STR s_GlobSrchDlgBtnStrs[0]
171 #define START_SEARCH_MNEM "S"
172 #define CONT_SEARCH_CAT s_GlobSrchDlgBtnCatNum[1]
173 #define CONT_SEARCH_STR s_GlobSrchDlgBtnStrs[1]
174 #define CONT_SEARCH_MNEM "S"
175 #define STOP_SEARCH_CAT s_GlobSrchDlgBtnCatNum[2]
176 #define STOP_SEARCH_STR s_GlobSrchDlgBtnStrs[2]
177 #define STOP_SEARCH_MNEM "S"
178 #define CLOSE_BTN_CAT s_GlobSrchDlgBtnCatNum[3]
179 #define CLOSE_BTN_STR s_GlobSrchDlgBtnStrs[3]
180 #define CLOSE_BTN_MNEM "C"
181 #define HELP_BTN_CAT s_GlobSrchDlgBtnCatNum[4]
182 #define HELP_BTN_STR s_GlobSrchDlgBtnStrs[4]
183 #define HELP_BTN_MNEM "H"
186 /********** MACROS ************/
187 #define max(a,b) ((a) > (b) ? (a) : (b))
189 /********** Global VARIABLES ************/
190 char _DtHelpDefaultSrchHitPrefixFont[] = PREFIX_FONT_SPEC;
192 /********** VARIABLES ************/
193 static const char *DirSlash = "/";
194 static char * s_GlobSrchDlgBtnStrs[] = {
201 /* catalog index numbers for the strings */
202 static unsigned char s_GlobSrchDlgBtnCatNum[] = {
203 12, 13, 14, 15, 16 };
205 static char * s_PrefixFontListTag = NULL;
207 /* Setup for the Retrun Translation set for the text field */
208 static char defaultBtnTranslations[] = "<Key>Return: Activate()";
209 /* static char defaultListTranslations[] = "<Key>Return: Activate()"; */
210 /* static char defaultMgrTranslations[] = "<Key>Return: ManagerParentActivate()"; */
213 /************************************************************************
214 The startPosition and nextVolPosition values of the DtHelpGlobSrchVol
215 structure are used as follows:
217 startPosition: the position of the volume in the results list
218 if hitCnt == 0, startPosition is the same value as the
219 most recent volume with hits
220 nextVolPosition: the position of the next volume in the results list
221 if hitCnt == 0, nextVolPosition is the same value as the
222 most recent volume with hits
223 The value must be adjusted to include the positions
224 occupied by hits and topics that are listed for the volume
226 These variables are maintained using the AdjustPositionValues()
227 routine, which increment/decrement the position values of all
228 files after the start. So, when doing a search and display,
229 as results are added to the list, the position values of volumes
230 later in the list are always up to date.
231 ************************************************************************/
234 /*======================================================================*/
235 /*======================================================================*/
236 /*======================================================================*/
237 /*======================================================================*/
240 /*****************************************************************************
241 * Function: void MergeFontListIntoWidgetFonts()
243 * Parameters: widget a widget with a XmNfontList resource
244 * newFontsList font list with fonts to merge into widget
248 * Purpose: Merges the fonts from the newFontsList into the fontlist
251 *****************************************************************************/
252 static void MergeFontListIntoWidgetFonts(
254 XmFontList newFontsList)
256 XmFontList fontList = NULL;
257 XmFontContext context;
258 XmFontListEntry entry;
261 /* get current resultList fontlist */
262 XtSetArg(args[0], XmNfontList, &fontList);
263 XtGetValues(widget,args,1);
265 if (NULL == fontList) return; /* RETURN on error */
267 /* work with copy, because FontListAppendEntry() destroys input FL */
268 fontList = XmFontListCopy(fontList);
270 /* walk through the volTitlesFontList entries and add them in */
271 XmFontListInitFontContext(&context,newFontsList);
272 for ( entry = XmFontListNextEntry(context);
274 entry = XmFontListNextEntry(context) )
276 fontList = XmFontListAppendEntry(fontList,entry);
278 if (context) XmFontListFreeFontContext(context);
280 /* install the changed list */
281 XtSetArg(args[0], XmNfontList, fontList);
282 XtSetValues(widget,args,1);
284 if (fontList) XmFontListFree(fontList);
288 /*****************************************************************************
289 * Function: void UpdateCurVolBtnSens()
291 * Parameters: new the help widget
293 * Return Value: True if cur vol has an index
296 * Purpose: Checks on current volume for an index
297 and sets buttons appropriately
299 *****************************************************************************/
300 static Boolean UpdateCurVolBtnSens(
301 DtHelpDialogWidget hw,
302 Boolean selectVolBtn)
304 XmToggleButtonCallbackStruct status; /* the call data */
308 /* set the cur vol btn sensitivity */
309 /* set the volumes/show selection btns by generating a false event */
310 status.reason = XmCR_VALUE_CHANGED;
312 status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
315 if ( VolumeHasIndexP (
316 hw->help_dialog.srch.srchSources,
317 hw->help_dialog.display.helpType,
318 hw->help_dialog.display.helpVolume) )
321 sourceBtn = hw->help_dialog.srch.curVolRadBtn;
326 sourceBtn = hw->help_dialog.srch.allVolRadBtn;
328 /* ??? XtSetSensitive(hw->help_dialog.srch.curVolRadBtn,curState); */
329 hw->help_dialog.srch.curVolRadBtnSens = curState;
330 if (selectVolBtn) UpdateSearchVolumesCB(sourceBtn,hw,&status);
334 sourceBtn = hw->help_dialog.srch.curVolRadBtn;
336 hw->help_dialog.srch.curVolRadBtnSens = curState;
338 UpdateSearchVolumesCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
346 /************************************************************************
347 * Function: LoadPrefixFont()
349 * Loads the prefix font, if that hasn't yet occurred
351 ************************************************************************/
352 static void LoadPrefixFont(
353 DtHelpDialogWidget hw)
355 XmFontListEntry entry;
356 XmFontList curFontList = NULL;
357 XmFontList newFontList = NULL;
358 char * fontSpec = NULL;
361 if (hw->help_dialog.srch.hitsFontLoaded) return; /* RETURN */
363 /* this code is for when the resource is part of the widget */
364 fontSpec = hw->help_dialog.srch.hitPrefixFont;
366 /* get current font list */
367 XtSetArg(args[0], XmNfontList, &curFontList);
368 XtGetValues(hw->help_dialog.srch.resultList,args,1);
370 /* work with copy, because FontListAppendEntry() destroys input FL */
371 newFontList = XmFontListCopy(curFontList);
373 /* load and merge fonts */
374 s_PrefixFontListTag = PREFIX_FONT_TAG;
375 entry = XmFontListEntryLoad(XtDisplay(hw->help_dialog.srch.srchForm),
376 fontSpec,XmFONT_IS_FONT, s_PrefixFontListTag);
377 newFontList = XmFontListAppendEntry(newFontList,entry);
378 XmFontListEntryFree(&entry);
381 if (NULL == newFontList)
383 s_PrefixFontListTag = XmFONTLIST_DEFAULT_TAG;
387 /* set new font list */
388 XtSetArg(args[0], XmNfontList, newFontList);
389 XtSetValues(hw->help_dialog.srch.resultList,args,1);
390 if (newFontList) XmFontListFree(newFontList);
392 hw->help_dialog.srch.hitsFontLoaded = True;
397 /************************************************************************
398 * Function: VolumeHasIndexP()
400 * Looks for the specified volume in the file system and
401 * tests whether the volume has an index associated with it.
403 ************************************************************************/
404 static Boolean VolumeHasIndexP (
405 _DtHelpGlobSrchSources srchSource,
410 _DtHelpVolumeHdl vol;
411 int keyWordCount = 0;
412 char **currentKeyList = NULL;
414 /* if help content isn't a volume, it has no index */
415 if ( _DtHelpGlobSrchCurVolume == srchSource
416 && helpType != DtHELP_TYPE_TOPIC )
417 return False; /* RETURN */
419 /* try to locate file and its entry, if present */
420 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, baseName,
421 _DtHelpFileSuffixList,False,R_OK);
422 if (_DtHelpOpenVolume(path, &vol) == 0 )
424 /* Get the keyword list values */
425 keyWordCount = _DtHelpCeGetKeywordList(vol,&(currentKeyList));
427 /* no need to free currentKeyList because these are mgd by CE */
428 _DtHelpCloseVolume(vol);
432 return (keyWordCount > 0);
437 /************************************************************************
438 * Function: GetVolumeInfoCB()
440 * Get the info on the volume and return it
441 * Any of the 'out' parameters may be NULL.
443 ************************************************************************/
444 static Boolean GetVolumeInfoCB (
445 XtPointer pDisplayArea, /* in: display area in use */
446 char * volumePath, /* in: full path to file */
447 char ** ret_title, /* out: mallocd doc title text string */
448 XmString * ret_titleXmStr,/* out: mallocd doc title string */
449 char ** ret_docId, /* out: mallocd doc Id string */
450 char ** ret_timeStamp, /* out: mallocd doc time string */
451 int * ret_nameKey, /* out: hash value for fast discimination */
452 XmFontList * io_fontList, /* io: fontList for title */
453 Boolean * ret_mod) /* out: has font list been changed */
456 _DtHelpVolumeHdl vol;
457 char * baseName = volumePath; /* no path component */
460 if(_DtHelpCeStrrchr(volumePath, DirSlash, MB_CUR_MAX, &baseName)==0)
464 if ( _DtHelpOpenVolume(volumePath, &vol) != 0 )
465 { /* if can't open, do best possible */
467 *ret_titleXmStr = XmStringCreateLocalized(baseName);
468 if (ret_title) *ret_title= XtNewString(baseName);
469 if (ret_nameKey) *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
473 /** volume is open, now get the data **/
477 char * locTitle = NULL;
479 /* locTitle is owned by caller */
480 _DtHelpGetAsciiVolumeTitle(pDisplayArea, vol, &locTitle);
481 if (locTitle == NULL)
482 locTitle = XtNewString(baseName);
483 *ret_title = locTitle;
488 XmString locTitleXmStr = NULL;
490 /* locTitle is owned by caller */
491 _DtHelpFormatVolumeTitle(pDisplayArea,vol,
492 &locTitleXmStr,io_fontList,ret_mod);
493 if (locTitleXmStr == NULL)
494 locTitleXmStr = XmStringCreateLocalized(baseName);
495 *ret_titleXmStr = locTitleXmStr;
498 if (ret_docId || ret_timeStamp)
500 char * locDocId = NULL;
501 char * locTimeStamp = NULL;
503 /* locDocId & locTimeStamp will point to private memory; do not modify */
504 _DtHelpCeGetDocStamp(vol,&locDocId, &locTimeStamp);
507 *ret_docId = locDocId ? locDocId : XtNewString(&empty);
509 *ret_timeStamp = locTimeStamp?locTimeStamp:XtNewString(&empty);
514 *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
517 _DtHelpCloseVolume(vol);
523 /************************************************************************
524 * Function: AdjustPositionValues()
526 * Adjust the position values of all volumes in the list by the amount given
528 ************************************************************************/
529 static void AdjustPositionValues(
530 _DtHelpFileList fileList,
535 _DtHelpGlobSrchVol * curVol;
537 if ( NULL == fileList
538 || NULL == (curVol = (_DtHelpGlobSrchVol *) fileList->clientData) )
541 /* do we need to find first next file that has hits and is in list? */
542 if(False == adjustThisFile)
544 curVol->nextVolPosition += adjNextAmount;
545 for ( fileList = _DtHelpFileListGetNext(NULL,fileList); /* begin with next */
547 fileList = _DtHelpFileListGetNext(NULL,fileList) )
549 register _DtHelpGlobSrchVol * vol=(_DtHelpGlobSrchVol *)fileList->clientData;
550 if (vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
552 vol->nextVolPosition += adjNextAmount;
554 /* all further files require same adj amts */
555 adjStartAmount = adjNextAmount;
559 /* add in the adjust amount to all files */
560 for ( /* do nothing */;
562 fileList = _DtHelpFileListGetNext(NULL,fileList) )
564 register _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) fileList->clientData;
567 vol->startPosition += adjStartAmount;
568 vol->nextVolPosition += adjNextAmount;
570 /* overwrite, once we've done the first file, if haven't already */
571 adjStartAmount = adjNextAmount;
576 /************************************************************************
577 * Function: HitLoadTopics()
579 * Loads the topics referred to by a hit
580 * Returns: 0 if loaded ok, -1 otherwise
581 ************************************************************************/
582 static int HitLoadTopics (
583 DtHelpDialogWidget hw,
584 _DtHelpFileEntry file,
585 _DtHelpGlobSrchHit * hit)
587 _DtHelpVolumeHdl volHandle;
588 char * * origTopicIdList = NULL;
591 XmString * titlesList = NULL;
592 char * * idList = NULL;
593 char * * fileList = NULL;
594 XmFontList fontList = NULL;
596 Boolean allMods = False;
599 if (hit->topicsLoaded) return 0; /* RETURN: ok */
601 if (_DtHelpOpenVolume(file->fullFilePath, &volHandle) != 0 )
602 return -1; /* RETURN: error */
604 topicCnt = _DtHelpCeFindKeyword(volHandle,hit->indexEntry,&origTopicIdList);
605 if (topicCnt <= 0) return -1; /* RETURN: error */
607 /* get results font list */
608 XtSetArg(args[0], XmNfontList, &fontList);
609 XtGetValues(hw->help_dialog.srch.resultList,args,1);
611 #if defined(DONT_USE_CDExc22774)
612 /* Don't need to copy, _DtHelpFormatVolumeTitle copies
616 /* FIX: check whether this is a memory leak. It isn't if the
617 GetValues of XmFontList returns its own list, not a copy */
618 /* work with copy, because FontListAppendEntry() destroys input FL */
619 fontList = XmFontListCopy(fontList);
622 /* get the titles of all topics */
623 for (i=0; i<topicCnt; i++)
625 XmString titleStr = NULL;
626 Boolean valid = False;
627 XmFontList lastFontList = NULL;
630 * mod==True indicates _DtHelpFormatTopicTitle copied fontList
631 * once already. Save a pointer to it so we can free the font list
632 * if _DtHelpFormatTopicTitle copies it again.
634 lastFontList = fontList;
636 valid = _DtHelpFormatTopicTitle(hw->help_dialog.help.pDisplayArea,
637 volHandle,origTopicIdList[i], &titleStr, &fontList, &mod);
639 if (mod && NULL != lastFontList) XmFontListFree(lastFontList);
641 allMods |= mod; /* track for all iterations */
643 if(valid!=0 || NULL==titleStr)
645 titleStr=XmStringCreateLocalized(origTopicIdList[i]);
646 } /* if couldn't get title */
648 /* note that titleStr is an XmString, not an (Xt) String */
649 titlesList = (XmString *)_DtHelpCeAddPtrToArray (
650 (void **)titlesList, (void *) titleStr);
651 idList = (char **)_DtHelpCeAddPtrToArray (
653 (void *) XtNewString(origTopicIdList[i]));
654 fileList = (char **)_DtHelpCeAddPtrToArray (
656 (void *) XtNewString(file->fullFilePath));
657 } /* for all topics of this index entry */
659 /* install font list, if changed */
662 XtSetArg(args[0], XmNfontList, fontList);
663 XtSetValues(hw->help_dialog.srch.resultList,args,1);
664 if (fontList) XmFontListFree(fontList);
667 /* put results into hit */
668 hit->topicTitles = titlesList;
669 hit->topicIdList = idList;
670 hit->topicFileList = fileList;
671 hit->topicCnt = topicCnt;
672 hit->topicsLoaded = True;
674 _DtHelpCloseVolume(volHandle);
681 /************************************************************************
682 * Function: HitNameDisplay()
684 * Updates the name of the hit, not delete or insert
685 ************************************************************************/
686 static int HitNameDisplay (
687 DtHelpDialogWidget hw,
688 _DtHelpFileEntry file,
689 _DtHelpGlobSrchHit * hit,
694 char * contractPrefix;
696 XmString prefixString;
697 XmString labelString;
701 /* FIX: this method of getting/using the prefixes
702 is a performance nightmare; plus subject to font variability */
703 expandPrefix = (char *)_DTGETMESSAGE (GSSET, 28," +");
704 contractPrefix = (char *)_DTGETMESSAGE (GSSET, 29," -");
705 gotoPrefix = (char *)_DTGETMESSAGE (GSSET, 30," ");
707 /* if more than one topic for this index, signal it */
708 tmpStr = gotoPrefix; /* index entry has one topic */
709 if ( hit->topicCnt > 1 )
711 if (hit->topicsDisplayed) /* topics currently displayed */
712 tmpStr = contractPrefix;
713 else /* topics not displayed */
714 tmpStr = expandPrefix;
715 sprintf(buf, "%s%3d ", tmpStr, hit->topicCnt); /* 4d too spacy */
719 prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
720 XmCHARSET_TEXT, NULL);
721 labelString = XmStringConcat(prefixString,hit->indexTitle);
722 /* recall indexTitle is an XmString in the volume's indexXmStrsList */
724 /* install/insert the item */
726 XmListAddItemUnselected(hw->help_dialog.srch.resultList,
729 XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
730 &labelString,1,hitPos);
732 XmStringFree(prefixString);
733 XmStringFree(labelString);
734 return (insertHit ? 1 : 0);
739 /************************************************************************
740 * Function: HitTopicsDisplay()
742 * Loads the topics referred to by a hit and displays them
743 * Returns the number of topics displayed
744 ************************************************************************/
745 static int HitTopicsDisplay (
746 DtHelpDialogWidget hw,
747 _DtHelpFileEntry file,
748 _DtHelpGlobSrchHit * hit,
749 int firstTopicListPosition)
751 XmString * pTopicString;
752 XmString prefixString;
753 XmString labelString;
758 if ( False == hit->topicsLoaded && HitLoadTopics(hw,file,hit) < 0 )
759 return 0; /* RETURN: error */
760 if ( hit->topicsDisplayed ) return 0; /* RETURN: ok */
763 /*tmpStr = (char *)_DTGETMESSAGE (GSSET, 32," * ");*/
764 tmpStr = (char *)_DTGETMESSAGE (GSSET, 31," ");
765 prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
766 XmCHARSET_TEXT, NULL);
768 if (hit->topicCnt > 0)
770 items = (XmString *) XtMalloc (sizeof (XmString) * hit->topicCnt);
772 /* put XmString-formatted topic titles into list */
773 for (i = 0, pTopicString = hit->topicTitles; NULL != *pTopicString;
774 pTopicString++, i++ )
775 items[i] = XmStringConcat(prefixString,*pTopicString);
777 XmListAddItemsUnselected(hw->help_dialog.srch.resultList, items,
778 hit->topicCnt, firstTopicListPosition);
779 for (i = 0; i < hit->topicCnt; i++)
780 XmStringFree(items[i]);
781 XtFree((char *) items);
784 XmStringFree(prefixString);
787 hit->topicsDisplayed = True;
788 hit->showTopicsWithHit = True;
789 return hit->topicCnt;
795 /************************************************************************
796 * Function: HitTopicsUndisplay()
798 * Releases the topics referred to by a hit and undisplays them
799 * Returns number of topics removed from display and hit.
800 ************************************************************************/
801 static int HitTopicsUndisplay (
802 DtHelpDialogWidget hw,
803 _DtHelpFileEntry file,
804 _DtHelpGlobSrchHit * hit,
805 int firstTopicListPosition)
810 if ( False == hit->topicsDisplayed ) return 0; /* RETURN */
812 XtSetArg(args[0], XmNtopItemPosition, &topPos);
813 XtGetValues(hw->help_dialog.srch.resultList,args,1);
815 /* count the topics -- they are also being collapsed */
816 if (hit->topicCnt > 0)
817 XmListDeleteItemsPos(hw->help_dialog.srch.resultList,
818 hit->topicCnt, firstTopicListPosition);
820 hit->topicsDisplayed = False;
821 /* NOTE: don't reset hit->showTopicsWithHit here; require that
822 to be explicitly reset in ProcessResultSelection() */
824 XmListSetPos(hw->help_dialog.srch.resultList, topPos);
826 return hit->topicCnt;
832 /************************************************************************
833 * Function: HitFree()
835 * Frees the memory associated with a hit and returns the next hit
836 * member of the structure
837 ************************************************************************/
838 static _DtHelpGlobSrchHit * HitFree (
839 _DtHelpGlobSrchHit * hit,
840 Boolean freeHitItself)
843 _DtHelpGlobSrchHit * nextHit;
845 if (NULL == hit) return NULL;
849 /* Free the mem of the topics id list */
850 _DtHelpCeFreeStringArray(hit->topicIdList);
851 hit->topicIdList = NULL; /* mem not owned by me */
853 /* Free the mem of the topics files list */
854 _DtHelpCeFreeStringArray(hit->topicFileList);
855 hit->topicFileList = NULL;
857 /* topicTitles are XmStrings and we can't use FreeStringArray() */
858 for ( nextStr = hit->topicTitles;
859 NULL != nextStr && NULL != *nextStr;
861 XmStringFree (*nextStr);
862 XtFree((char *) hit->topicTitles); /* its an XmString * */
863 hit->topicTitles = NULL;
866 hit->topicsLoaded = False;
867 hit->topicsDisplayed = False;
871 /* Free the index entry */
872 XtFree(hit->indexEntry);
880 /************************************************************************
881 * Function: HitListFree()
883 * Walks along a hit list and frees its contents
884 ************************************************************************/
885 static void HitListFree(
886 _DtHelpGlobSrchVol * vol,
887 Boolean freeHitsThemselves)
889 register _DtHelpGlobSrchHit * hit;
891 if (NULL == vol) return; /* RETURN */
893 for ( hit = vol->hitListHead;
895 hit = HitFree(hit,freeHitsThemselves) )
898 /* reset search flags */
899 vol->nothingDone = True;
900 vol->topicSearchDone = False;
901 vol->indexSearchDone = False;
902 vol->searchCompleted = False;
903 vol->searchedCnt = 0;
904 vol->gatheredFullIndex = False;
906 /* reset hit flags */
907 vol->hitsDisplayed = False;
908 vol->showHitsWithVol = False;
909 vol->zeroHitsOk = False;
912 /* reset list display flags */
913 vol->startPosition = 1;
914 vol->nextVolPosition = 1;
916 /* dont free indexXmStrsList here because they
917 are reused for every search on this volume */
918 vol->curIndexXmStr = vol->indexXmStrsList;
920 /* indexEntriesList,volhandle inited elsewhere */
922 if (freeHitsThemselves)
924 vol->hitListHead = NULL;
925 vol->hitListTail = NULL;
930 /************************************************************************
931 * Function: HitListFreeAllVolHits()
933 * Walks along all the volumes and frees their hits
934 ************************************************************************/
936 HitListFreeAllVolHits (
937 DtHelpDialogWidget hw,
938 Boolean freeFullIndex)
940 _DtHelpGlobSrchVol * vol;
941 _DtHelpFileEntry curFile;
943 /* walk the files, freeing all hits and their data */
944 for ( curFile = hw->help_dialog.srch.volListHead;
946 curFile = _DtHelpFileListGetNext(NULL,curFile) )
948 vol = (_DtHelpGlobSrchVol *) curFile->clientData;
950 if (NULL == vol) continue; /* CONTINUE */
951 if (vol->gatheredFullIndex && freeFullIndex == False) continue;
952 HitListFree(vol,True); /* True: free hits themselves */
954 hw->help_dialog.srch.hitsFound = False;
958 /************************************************************************
959 * Function: HitListGetNth()
961 * Retrieves the Nth entry from the hits contained in the VolList
963 * This code follows the same counting paradigm used when adding
964 * the items to the srchResultList widget, so that we can just use the
965 * position value returned by it to retrieve the selected item.
967 * This paradigm also counts the presence of a volume as an item
968 * if it contains any hits, and doesn't count it if it contains
969 * no hits. It also counts the topicTitles that are associated
970 * with a hit and displayed indented beneath it.
972 * The position count is 1 based, which corresponds with the
976 * ret_hit: retuns NULL if an error or a pointer to the hit structure.
977 * ret_locationId: returns NULL is position is for the hit
978 * structure itself, returns a pointer to private
979 * memory containing the location id if position
980 * is a topic belonging to the hit.
982 * Returns: 0 if ok, -1 if error
983 ************************************************************************/
984 static int HitListGetNth (
985 _DtHelpFileList volListHead,
987 _DtHelpFileEntry * ret_file,
988 _DtHelpGlobSrchHit * * ret_hit,
989 char * * ret_locationId,
990 char * * ret_helpFile)
992 _DtHelpGlobSrchHit * hit = NULL;
993 _DtHelpGlobSrchVol * curVol;
994 _DtHelpFileEntry curFile = NULL;
995 _DtHelpFileEntry posFile = NULL;
996 char * * locationIdList = NULL;
997 char * * fileNameList = NULL;
1000 if (NULL == volListHead) goto done; /* GOTO on error */
1002 /* walk along the volumes to find the one containing the position
1003 Because we need the most recent file with hits before the
1004 nextFile that has too high a position, only set posFile when
1005 we aren't ready to stop yet and we're on a file with hits. */
1006 for ( curFile = volListHead;
1008 curFile = _DtHelpFileListGetNext(curFile,curFile) )
1010 /* it is impt to use > test so that multiple volumes with the same
1011 start position are properly handled. This occurs when they
1012 have no hits in them. */
1013 curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
1014 if (NULL == curVol) continue;
1016 if (curVol->startPosition > position) break; /* BREAK */
1017 if (curVol->hitCnt > 0) posFile = curFile; /* recent with hits */
1019 if (curVol->showVolInList && curVol->nextVolPosition > position)
1026 if(NULL == posFile) goto done; /* GOTO on error */
1028 /*** walk along the hits to find the one matching the position ***/
1029 curVol = (_DtHelpGlobSrchVol *) posFile->clientData;
1030 curPos = curVol->startPosition;
1032 locationIdList = NULL;
1033 fileNameList = NULL;
1035 /* (position == curPos) ==> volume name itself was selected */
1036 if ( curPos < position )
1037 { /* a hit inside the volume */
1038 if ( curVol->hitsDisplayed )
1040 for ( curPos++, hit = curVol->hitListHead;
1041 curPos < position && NULL != hit;
1042 curPos++, hit = hit->next )
1044 if (False == hit->topicsDisplayed) continue; /* CONTINUE */
1046 /* walk all displayed topics to see if the position is here */
1047 for ( locationIdList=hit->topicIdList,fileNameList=hit->topicFileList;
1048 NULL != locationIdList[0];
1049 locationIdList++, fileNameList++ )
1051 /* use GOTO to escape with all pointers correct and
1052 without introducing an additional flag variable */
1053 if (++curPos == position) goto done; /* GOTO */
1054 } /* for all locations of a hit before the position */
1055 } /* for all members of the hit list before the position */
1056 } /* if hits are currently shown */
1057 else posFile = NULL; /* an error occurred */
1058 } /* if position is in the hit list */
1061 if (ret_hit) *ret_hit = hit;
1062 if (ret_file) *ret_file = posFile;
1065 if ( locationIdList ) *ret_locationId = locationIdList[0];
1066 else *ret_locationId = NULL;
1070 if ( fileNameList ) *ret_helpFile = fileNameList[0];
1071 else *ret_helpFile = NULL;
1073 /* WARNING: depends on pointers and integers the same size */
1075 return (NULL == ((ulong_t)hit|(ulong_t)posFile|(ulong_t)locationIdList)) ? -1 : 0;
1077 return (0 == ((int)hit|(int)posFile|(int)locationIdList)) ? -1 : 0;
1083 /************************************************************************
1084 * Function: HitListAddFound()
1086 * Adds a hit to the hit list of the specified volume
1087 * The hits are added either to the end of the list,
1088 * so that the srchResultList presents the items in the order found,
1089 * or in a sorted order.
1090 * If a hit on that topic already exists, just the existing
1091 * hit structure is returned.
1093 * Return Parameters:
1094 * Ret_hit points to the hit data. This is not a copy--do not
1098 * Returns 0 if no error, -1 if an error occurred.
1099 ************************************************************************/
1100 static int HitListAddFound (
1101 _DtHelpFileEntry curFile,
1102 XmString indexTitle,
1104 Boolean insertSorted,
1105 _DtHelpGlobSrchHit **ret_hit)
1107 _DtHelpGlobSrchHit * prev;
1108 _DtHelpGlobSrchHit * next;
1109 _DtHelpGlobSrchHit * srcHit;
1110 _DtHelpGlobSrchVol * vol;
1112 extern _CEStrcollProc _DtHelpCeGetStrcollProc();
1113 _CEStrcollProc strcollfn = _DtHelpCeGetStrcollProc();
1115 if (NULL == curFile) return -1; /* RETURN */
1116 vol = (_DtHelpGlobSrchVol *) curFile->clientData;
1117 if (NULL == vol) return -1; /* RETURN */
1119 /* walk along the hits, looking for one matching the new hit */
1120 /* recall that position is 1-based */
1121 newKey = _DtHelpCeStrHashToKey(indexEntry);
1123 if ( insertSorted ) /* find position and check for duplicates */
1125 /* walk along list */
1126 for( next = vol->hitListHead;
1128 prev = next, next = next->next )
1132 /* do a NLS case insensitive compare using NLS collating */
1133 if ( (ret = (*strcollfn)(next->indexEntry,indexEntry)) >= 0 )
1137 if(ret_hit) *ret_hit = next;
1138 return 0; /* RETURN */
1140 /* prev and next are set correctly */
1145 else /* check for duplicates */
1147 /* walk along list */
1148 for( next = vol->hitListHead;
1150 prev = next, next = next->next )
1152 if ( newKey == next->indexKey /* quick compare */
1153 && strcmp(indexEntry,next->indexEntry) == 0 ) /* long compare */
1155 if(ret_hit) *ret_hit = next;
1156 return 0; /* RETURN */
1159 /* prev and next are set correctly (at end of list) */
1162 /* handle a new hit */
1163 srcHit = (_DtHelpGlobSrchHit *)XtCalloc(1,sizeof(_DtHelpGlobSrchHit));
1164 if (NULL == srcHit) return -1; /* RETURN */
1166 /* init hit values */
1167 /* leave srcHit->hitCnt == 0 here */
1168 if (NULL == indexTitle)
1169 srcHit->indexTitle = XmStringCreateLocalized(indexEntry);
1171 srcHit->indexTitle = indexTitle;
1172 srcHit->indexEntry = XtNewString(indexEntry);
1173 srcHit->indexKey = newKey;
1174 srcHit->volume = curFile;
1176 /* integrate hit into the list */
1177 srcHit->next = next;
1178 if (prev) prev->next = srcHit;
1179 else vol->hitListHead = srcHit;
1180 if (!next) vol->hitListTail = srcHit;
1182 /* add in the volume contribution */
1186 if(ret_hit) *ret_hit = srcHit;
1192 /************************************************************************
1193 * Function: CountSelectedVolumes()
1195 * Counts the number volumes with the searchThisVolume flag set
1196 * for which the search has yet to complete
1198 ************************************************************************/
1199 static int CountSelectedVolumes (
1200 _DtHelpFileList volListHead,
1201 Boolean countSearchCompletedVolumes)
1205 /* walk all volumes */
1206 for ( /* nothing */;
1207 NULL != volListHead;
1208 volListHead = _DtHelpFileListGetNext(NULL, volListHead) )
1210 register _DtHelpGlobSrchVol * vol;
1212 /* get the volume info */
1213 vol = (_DtHelpGlobSrchVol *) volListHead->clientData;
1214 /* if (NULL != vol && vol->searchThisVolume && False == vol->searchCompleted)*/
1215 if (vol && vol->searchThisVolume)
1217 if ( (False == vol->searchCompleted)
1218 || (countSearchCompletedVolumes && vol->searchCompleted) )
1221 } /* walk all volumes */
1227 /************************************************************************
1228 * Function: GetNextSearchFileAndDisplayCompleted()
1230 * Scans list for next file ready for searching
1231 * If it encounters a file that has completed it's search
1232 * and for which the results should be displayed, they are displayed
1234 ************************************************************************/
1235 static _DtHelpFileEntry GetNextSearchFileAndDisplayCompleted(
1236 DtHelpDialogWidget hw,
1237 _DtHelpFileList listHead,
1238 _DtHelpFileEntry curFile)
1240 /* get first file needing work */
1241 for ( curFile = _DtHelpFileListGetNext(listHead, curFile);
1243 curFile = _DtHelpFileListGetNext(NULL, curFile) )
1245 register _DtHelpGlobSrchVol * vol;
1247 vol = (_DtHelpGlobSrchVol *) curFile->clientData;
1248 if (NULL == vol) continue; /* CONTINUE */
1250 /* if file already searched and should be displayed, then do so */
1251 if ( vol->searchThisVolume && vol->searchCompleted
1252 && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
1254 /* record that a hit found */
1255 if ( vol->hitCnt > 0
1256 || ( vol->zeroHitsOk
1257 && _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
1258 hw->help_dialog.srch.hitsFound = True;
1260 /* True: adjust count beginning with this file */
1261 AdjustPositionValues(curFile,0,1,True);
1262 ResultsListUpdate(hw,curFile);
1264 /* display the hits as well? */
1265 if ( vol->showHitsWithVol
1266 || hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
1268 VolHitsDisplay(hw,curFile);
1270 /* update the volume label to show state; False--dont insert */
1271 VolNameDisplay(hw,curFile,False);
1275 /* if want to search, and need to, then return it */
1276 if ( vol->searchThisVolume && False == vol->searchCompleted
1277 && vol->showVolInList ) /* don' search unless results will be shown */
1281 XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
1287 /************************************************************************
1288 * Function: AddVolInfoToFile
1290 * Creates a volume info entry for each member of the list
1291 * and initializes its values
1292 * If searchStatus is False, all volumes are set. If its True,
1293 * all are set if selectedFilesOnly is false, otherwise only
1294 * selected files are set to true.
1296 ************************************************************************/
1297 static void AddVolInfoToFile(
1298 _DtHelpFileEntry file,
1299 Boolean initialSearchStatus,
1300 Boolean displayStatus,
1301 Boolean selectedFilesOnly)
1303 _DtHelpGlobSrchVol * vol;
1305 if (NULL == file) return; /* RETURN */
1307 vol = (_DtHelpGlobSrchVol *) file->clientData;
1310 vol = (_DtHelpGlobSrchVol *) XtCalloc(1,sizeof(_DtHelpGlobSrchVol));
1311 file->clientData = (XtPointer) vol;
1312 if (NULL == vol) return; /* RETURN: memory alloc error */
1314 /* calloc() inited almost everything inside to 0 */
1315 /* set first time creation values */
1316 vol->nothingDone = True;
1319 /* now set search and display flags */
1320 vol->searchThisVolume = initialSearchStatus;
1321 vol->showVolInList = displayStatus;
1322 if ( False == file->fileSelected && True == selectedFilesOnly )
1324 vol->searchThisVolume = False;
1325 vol->showVolInList = False;
1330 /************************************************************************
1331 * Function: AddVolInfoToList
1333 * Creates a volume info entry for each member of the list
1334 * and initializes its values
1335 * If searchStatus is False, all volumes are set. If its True,
1336 * all are set if selectedFilesOnly is false, otherwise only
1337 * selected files are set to true.
1339 ************************************************************************/
1340 static void AddVolInfoToList(
1341 _DtHelpFileList listHead,
1342 Boolean initialSearchStatus,
1343 Boolean displayStatus,
1344 Boolean selectedFilesOnly)
1346 /* walk the files and allocate the vol info as needed */
1349 listHead = _DtHelpFileListGetNext(listHead,listHead) )
1351 AddVolInfoToFile(listHead,
1352 initialSearchStatus, displayStatus, selectedFilesOnly);
1358 /************************************************************************
1359 * Function: SetVolStatus()
1361 * Sets all volumes in the list to the specified search and/or display
1364 * If searchThisVolume is False, all volumes are set. If its True,
1365 * all are set if selectedFilesOnly is false, otherwise only
1366 * selected files are set to true. If searchThisVolume is False,
1367 * then the settings remain unchanged in all volumes.
1369 ************************************************************************/
1370 static void SetVolStatus(
1371 _DtHelpFileList listHead,
1372 Boolean searchThisVolume,
1373 Boolean showVolInList,
1375 Boolean selectedFilesOnly)
1377 /* walk the files and set the status */
1380 listHead = _DtHelpFileListGetNext(listHead,listHead) )
1382 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
1384 if (NULL == vol) continue;
1386 if ( (False == selectedFilesOnly)
1387 || (True == listHead->fileSelected && True == selectedFilesOnly) )
1389 /* just set the inclusion and/or display flags;
1390 don't reset the search progress flags */
1391 vol->searchThisVolume = searchThisVolume;
1392 vol->showVolInList = showVolInList;
1393 vol->zeroHitsOk = zeroHitsOk;
1399 /************************************************************************
1400 * Function: VolNameDisplay()
1402 * Updates the display of the volume name
1403 ************************************************************************/
1404 static void VolNameDisplay(
1405 DtHelpDialogWidget hw,
1406 _DtHelpFileEntry file,
1409 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
1410 XmString prefixString;
1411 XmString labelString;
1415 if ( NULL == vol || (False == vol->zeroHitsOk && 0 == vol->hitCnt) )
1416 return; /* RETURN */
1418 /* put volume name into list */
1419 if (vol->hitCnt <= 0) tmpStr = (char *)_DTGETMESSAGE (GSSET, 25," ");
1420 else if (vol->hitsDisplayed) tmpStr = (char *)_DTGETMESSAGE (GSSET, 27,"-");
1421 else tmpStr = (char *)_DTGETMESSAGE (GSSET, 26,"+"); /* >0 hits */
1422 sprintf(buf, "%s%3d ", tmpStr, vol->hitCnt); /* 4d too spacy */
1425 prefixString = XmStringGenerate(buf, s_PrefixFontListTag,
1426 XmCHARSET_TEXT, NULL);
1427 labelString = XmStringConcat(prefixString,file->fileTitleXmStr);
1429 /* replace or insert to reflect changed contents */
1431 XmListAddItemUnselected(hw->help_dialog.srch.resultList,
1432 labelString, vol->startPosition);
1434 XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
1435 &labelString, 1, vol->startPosition);
1437 XmStringFree(prefixString);
1438 XmStringFree(labelString);
1442 /************************************************************************
1443 * Function: VolHitsDisplay()
1445 * displays the hits associated with a volume
1446 * Returns the number of new items added to the list
1447 ************************************************************************/
1448 static int VolHitsDisplay (
1449 DtHelpDialogWidget hw,
1450 _DtHelpFileEntry file)
1452 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
1453 _DtHelpGlobSrchHit * hit;
1454 int listPos = vol->startPosition; /* vol item position */
1457 if (True == vol->hitsDisplayed ) return 0; /* RETURN */
1459 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1460 if (hw->help_dialog.srch.selectionDlg)
1461 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1463 /*** walk through the hits and count and display any open hits ***/
1464 for ( hit = vol->hitListHead, itemCnt = 0;
1468 itemCnt++; /* True: insert Hit into list */
1469 HitNameDisplay (hw,file,hit,listPos + itemCnt,True);
1471 /* display topics too? */
1472 if (hit->showTopicsWithHit)
1475 newItems = HitTopicsDisplay(hw,file,hit, listPos + itemCnt + 1);
1476 HitNameDisplay (hw,file,hit,listPos + itemCnt,False);
1477 itemCnt += newItems;
1482 vol->hitsDisplayed = True;
1483 vol->showHitsWithVol = True;
1485 /* adjust count beginning with next file with hits */
1486 AdjustPositionValues(file, 0, itemCnt, True);
1488 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1489 if (hw->help_dialog.srch.selectionDlg)
1490 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1497 /************************************************************************
1498 * Function: VolHitsUndisplay()
1500 * undisplays the hits associated with a volume
1501 ************************************************************************/
1502 static int VolHitsUndisplay (
1503 DtHelpDialogWidget hw,
1504 _DtHelpFileEntry file)
1506 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
1507 _DtHelpGlobSrchHit * hit;
1508 Boolean nonVisibleItems;
1509 int listPos = vol->startPosition; /* vol item position */
1518 if (False == vol->hitsDisplayed) return 0; /* RETURN */
1520 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1521 if (hw->help_dialog.srch.selectionDlg)
1522 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1524 XtSetArg(args[0], XmNtopItemPosition, &topPos);
1525 XtSetArg(args[1], XmNvisibleItemCount, &visItemCnt);
1526 XtGetValues(hw->help_dialog.srch.resultList,args,2);
1528 /* these are the num visible items below the volume name */
1529 topNonVisPos = topPos + visItemCnt; /* 1st non vis pos */
1531 /* num of items that will be undisplayed */
1532 undisItemCnt = vol->nextVolPosition - (vol->startPosition + 1);
1534 /* find out if any items aren't visible */
1535 nonVisibleItems = False;
1536 if ( vol->nextVolPosition > topNonVisPos )
1537 nonVisibleItems = True;
1539 /*** walk through the hits and count and delete any open topics ***/
1540 /* Make two passes: the first pass deletes all non-visible
1541 items. The second pass deletes the remaining visible items.
1542 The objective is to make collapse as fast and smooth as expand. */
1543 if (nonVisibleItems)
1544 { /* delete all items with a position > topNonVisPos */
1545 curDelPos = listPos + 1; /* starting position */
1546 for ( hit = vol->hitListHead, itemCnt = 0;
1550 /* are we still in the visible region? */
1551 if (curDelPos < topNonVisPos)
1553 /* move down the list to next hit */
1554 curDelPos++; /* this hit's item */
1555 /* plus any open topics */
1556 if (hit->topicsDisplayed) curDelPos += hit->topicCnt;
1557 continue; /* CONTINUE */
1559 /* we're in non-visible region--undisplay hit */
1560 XmListDeletePos(hw->help_dialog.srch.resultList, curDelPos);
1561 /* undisplay any topics */
1562 if ( hit->topicsDisplayed )
1563 itemCnt += HitTopicsUndisplay(hw,file,hit,curDelPos);
1565 } /* if non visible items */
1567 /* now delete the remaining visible items */
1568 /* Note that curDelPos is a virtual cursor that helps us
1569 figure out when to stop undisplaying. Virtually, we''re
1570 moving the cursor down the list with every delete. Actually,
1571 the rest of the list bumps up one--that''s why we delete
1574 curDelPos = listPos + 1; /* starting position */
1575 for ( hit = vol->hitListHead, itemCnt = 0;
1576 (NULL != hit) && (curDelPos < topNonVisPos);
1579 curDelPos++; /* undisplay hit item */
1580 XmListDeletePos(hw->help_dialog.srch.resultList, listPos + 1);
1581 /* undipslay any open topics */
1582 if ( hit->topicsDisplayed )
1584 curDelPos += HitTopicsUndisplay(hw,file,hit,listPos + 1);
1585 XmListSetPos(hw->help_dialog.srch.resultList, topPos);
1590 vol->hitsDisplayed = False;
1591 /* NOTE: don't reset vol->showHitsWithVol here; require that
1592 to be explicitly reset in ProcessResultSelection() */
1594 /* adjust count beginning with next file with hits */
1595 AdjustPositionValues(file, 0, -undisItemCnt, True);
1597 XmListSetPos(hw->help_dialog.srch.resultList, topPos);
1599 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1600 if (hw->help_dialog.srch.selectionDlg)
1601 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1603 return undisItemCnt;
1608 /************************************************************************
1609 * Function: VolListFree()
1611 * Releases all memory used by the volume list
1613 ************************************************************************/
1614 static void VolListFree (
1615 _DtHelpGlobSearchStuff * srch)
1617 _DtHelpFileList nextFile;
1619 /* walk all volumes */
1620 nextFile = srch->volListHead;
1621 while ( NULL != nextFile )
1623 _DtHelpGlobSrchVol * vol;
1624 _DtHelpFileList tmpFile;
1627 /* get the volume info */
1628 vol = (_DtHelpGlobSrchVol *) nextFile->clientData;
1630 /** free vol entry contents and container **/
1631 XtFree(vol->stdLocale);
1632 XtFree(vol->iconv3Codeset);
1633 HitListFree(vol,True); /* True: free hits themselves */
1635 /* no need to free indexEntriesList because these aren't owned by vol */
1636 vol->indexEntriesList = NULL;
1638 /* free indexXmStrsList */
1639 /* indexXmStrs are XmStrings and we can't use FreeStringArray() */
1640 for ( nextStr = vol->indexXmStrsList;
1641 NULL != nextStr && NULL != *nextStr;
1643 XmStringFree (*nextStr);
1644 XtFree((char *) vol->indexXmStrsList); /* its a XmString * */
1645 vol->indexXmStrsList = NULL;
1648 nextFile = _DtHelpFileListGetNext(NULL, nextFile);
1649 _DtHelpFileFreeEntry(tmpFile); /* also frees the clientData (vol) */
1650 } /* walk all volumes */
1652 /* reset related values */
1653 srch->volListHead = NULL;
1654 srch->curSrchVol = NULL;
1655 srch->volLeftCnt = 0;
1657 /* delete the results */
1658 DeleteListContents(srch);
1663 /************************************************************************
1664 * Function: ScanStatusCB
1666 * Updates the status display with the number of volumes found
1667 * as the scan progresses
1669 ************************************************************************/
1670 static void ScanStatusCB(
1672 XtPointer clientData)
1674 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
1676 StatusLabelUpdate(hw,SCANNING_STATUS,True,count);
1680 /************************************************************************
1681 * Function: VolListBuild
1683 * Frees the old list and builds a new one by scanning the
1684 * help directories for volumes and adding the associated
1685 * volume information used for searching.
1687 ************************************************************************/
1688 static void VolListBuild(
1689 DtHelpDialogWidget hw,
1690 Boolean searchStatus,
1691 Boolean displayStatus,
1692 Boolean selectedVolumesOnly)
1695 XmFontList origFontList;
1697 /* turn on hour glass */
1698 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1699 if (hw->help_dialog.srch.selectionDlg)
1700 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1702 StatusLabelUpdate(hw,SCANNING_STATUS,True,0);
1704 origFontList = hw->help_dialog.srch.volTitlesFontList;
1706 /* and rescan the volumes for the new list */
1707 _DtHelpFileListScanPaths( &hw->help_dialog.srch.volListHead,
1708 &hw->help_dialog.srch.volTitlesFontList,&mod,
1709 DtHelpVOLUME_TYPE, _DtHelpFileSuffixList, False,
1710 GetVolumeInfoCB,hw->help_dialog.help.pDisplayArea,
1711 /* sysPathCompare */ _DtHELP_FILE_NAME,
1712 /*otherPathCompare*/ _DtHELP_FILE_NAME|_DtHELP_FILE_TIME| _DtHELP_FILE_IDSTR,
1713 /* sortBy */ _DtHELP_FILE_TITLE, ScanStatusCB, (XtPointer)hw);
1715 /* if new fonts added to list, add them to the resultList */
1718 MergeFontListIntoWidgetFonts(
1719 hw->help_dialog.srch.resultList,
1720 hw->help_dialog.srch.volTitlesFontList);
1722 if (origFontList) XmFontListFree(origFontList);
1725 /* Add on the Vol info and (T,F) allow search on all volumes */
1726 AddVolInfoToList(hw->help_dialog.srch.volListHead,
1727 searchStatus, displayStatus, selectedVolumesOnly);
1729 hw->help_dialog.srch.volScanDone = True;
1731 StatusLabelUpdate(hw,BLANK_STATUS,True,0);
1733 /* turn off hour glass */
1734 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
1735 if (hw->help_dialog.srch.selectionDlg)
1736 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
1741 #if 0 || defined(DEBUG) /* for debug, set to 1 */
1742 /************************************************************************
1743 * Function: OutputVolInfo()
1745 * Output info on all volumes in the list
1747 ************************************************************************/
1748 static void OutputVolInfo(
1749 _DtHelpFileList listHead)
1753 listHead = _DtHelpFileListGetNext(listHead,listHead) )
1755 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
1756 if (NULL == vol) continue;
1758 /* output the info */
1759 printf("==================\n");
1760 printf("fileName: %s, %s\npathName: %s\n",
1761 listHead->fileName, listHead->fileTitle, listHead->fullFilePath);
1762 printf("searchThisVolume = %d, hitCnt = %d, startPos = %d\n",
1763 (int) listHead->fileSelected,
1765 (int) vol->startPosition);
1771 /************************************************************************
1772 * Function: SearchContinuePossible()
1774 * Test whether the search can be continued from the
1777 ************************************************************************/
1778 static Boolean SearchContinuePossible(
1779 DtHelpDialogWidget hw,
1782 char * normSrchWord;
1783 Boolean possible = False;
1785 normSrchWord = XtNewString(srchWord);
1786 _DtHelpCeCompressSpace(normSrchWord);
1787 _DtHelpCeUpperCase(normSrchWord);
1789 /* are we searching on the same word as previous search ? */
1790 /* comparison with srchNormWordStr is correct, given calls to this fn */
1791 /* FIX: use CheckSearchWord()? */
1792 if ( ( hw->help_dialog.srch.fullIndex
1793 || ( NULL != hw->help_dialog.srch.normWordStr
1794 && NULL != normSrchWord
1795 && strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
1796 && NULL != hw->help_dialog.srch.volListHead
1797 && hw->help_dialog.srch.volLeftCnt > 0 )
1800 XtFree(normSrchWord);
1806 /************************************************************************
1807 * Function: SearchOnSameCriteria()
1809 * Test whether the search criteria have changed
1811 ************************************************************************/
1812 static Boolean SearchOnSameCriteria(
1813 DtHelpDialogWidget hw,
1816 char * normSrchWord;
1817 Boolean sameCrit = False;
1819 normSrchWord = XtNewString(srchWord);
1820 _DtHelpCeCompressSpace(normSrchWord);
1821 _DtHelpCeUpperCase(normSrchWord);
1823 /* are we searching on the same word as previous search ? */
1824 /* comparison with srchNormWordStr is correct, given calls to this fn */
1825 if ( hw->help_dialog.srch.fullIndex
1826 || ( NULL != hw->help_dialog.srch.normWordStr
1827 && NULL != normSrchWord
1828 && strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
1831 XtFree(normSrchWord);
1834 #endif /* not_used */
1839 /************************************************************************
1840 * Function: UpdateActionButtonLabel()
1842 * Sets the start button label properly
1844 ************************************************************************/
1845 static void UpdateActionButtonLabel(
1846 DtHelpDialogWidget hw,
1848 Boolean startContAction)
1851 XmString labelString;
1852 XmString curLabelString;
1854 /* char * mnemonic; */
1856 /* if action label is to start or continue */
1857 _DtHelpProcessLock();
1858 if (startContAction)
1860 if ( SearchContinuePossible(hw,srchWord) )
1861 { /* then continue search */
1862 textString=(char *)_DTGETMESSAGE (GSSET,
1863 CONT_SEARCH_CAT,CONT_SEARCH_STR);
1864 labelString = XmStringCreateLocalized(textString);
1865 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 22,CONT_SEARCH_MNEM));*/
1868 { /* otherwise start it */
1869 textString=(char *)_DTGETMESSAGE (GSSET,
1870 START_SEARCH_CAT,START_SEARCH_STR);
1871 labelString = XmStringCreateLocalized(textString);
1872 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
1875 else /* action label is to stop */
1877 textString = (char *)_DTGETMESSAGE (GSSET,
1878 STOP_SEARCH_CAT,STOP_SEARCH_STR);
1879 labelString = XmStringCreateLocalized(textString);
1880 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, ??,STOP_SEARCH_MNEM));*/
1882 _DtHelpProcessUnlock();
1884 /* get the current state of the button */
1885 XtSetArg(args[0],XmNlabelString,&curLabelString);
1886 XtGetValues (hw->help_dialog.srch.actionBtn, args, 1);
1888 /* update label if it is different; avoid flashing this way */
1889 if ( XmStringCompare(labelString,curLabelString) == False )
1891 XtSetArg(args[0],XmNlabelString,labelString);
1892 XtSetArg(args[1], XmNalignment, XmALIGNMENT_CENTER);
1893 /* XtSetArg(args[2], XmNmnemonic, mnemonic[0]);*/
1894 XtSetValues (hw->help_dialog.srch.actionBtn, args, 2);
1895 XmUpdateDisplay(hw->help_dialog.srch.actionBtn);
1898 /* release the memory */
1899 XmStringFree(labelString);
1900 XmStringFree(curLabelString);
1904 /*****************************************************************************
1905 * Function: CheckSearchWord()
1909 * Return Value: True: word has changed
1910 * False: word is same
1912 * Purpose: Checks whether the search word is a new
1913 * one or the same as before. If the same, it frees
1914 * the word and returns False. If new, it moves the
1915 * previous word to another variable and installs
1916 * the new word in its place, using the srchWord mem.
1917 * ...but only if updateWidgetFields is True
1919 *****************************************************************************/
1920 static Boolean CheckSearchWord(
1921 DtHelpDialogWidget hw,
1923 Boolean updateWidgetFields)
1928 /* avoid a core dump */
1929 if ( NULL == srchWord )
1931 if ( NULL == hw->help_dialog.srch.normWordStr
1932 || hw->help_dialog.srch.normWordStr[0] == 0)
1933 return False; /* word hasn't changed */
1934 return True; /* RETURN: word has changed */
1937 _DtHelpCeCompressSpace(srchWord);
1938 rawSrchWord = XtNewString(srchWord);
1939 _DtHelpCeUpperCase(srchWord);
1940 /* FIX: to support regcomp(3), do that here */
1942 /* are we searching on the same word? */
1943 if ( NULL != hw->help_dialog.srch.normWordStr
1944 && strcmp(srchWord, hw->help_dialog.srch.normWordStr) == 0 )
1947 XtFree(rawSrchWord);
1949 /* output a message */
1950 if ( NULL != hw->help_dialog.srch.normWordStr
1951 && EOS != hw->help_dialog.srch.normWordStr[0])
1952 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
1955 return False; /* RETURN: no change */
1958 if (False == updateWidgetFields) return True; /* RETURN */
1960 /* update search word fields */
1961 XtFree(hw->help_dialog.srch.normWordStr);
1962 XtFree(hw->help_dialog.srch.rawWordStr);
1963 hw->help_dialog.srch.normWordStr = srchWord;
1964 hw->help_dialog.srch.rawWordStr = rawSrchWord;
1965 hw->help_dialog.srch.wordFieldLen = strlen(srchWord); /* note: not nl_strlen
1966 because used on strncmp not nl_strncmp */
1968 /* convert first char to a value for easy access for _DtHelpStrchr() */
1969 if ( mbtowc(&firstChar,srchWord,1) <= 0 ) firstChar = 0;
1970 hw->help_dialog.srch.wordFieldFirstChar = firstChar;
1972 /* output a message */
1973 if ( NULL != hw->help_dialog.srch.normWordStr
1974 && EOS != hw->help_dialog.srch.normWordStr[0])
1975 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
1977 return True; /* word changed */
1982 /*****************************************************************************
1983 * Function: PrepSearchSourceData()
1987 * Return Value: Void.
1989 * Purpose: Based on the current settings of the volume
1990 * selection buttons construct or utilitize an
1991 * existing volume list for processing.
1992 * Determine whether to continue search or
1993 * restart by comparing search words and states.
1995 *****************************************************************************/
1996 static void PrepSearchSourceData(
1997 DtHelpDialogWidget hw,
2000 /* try to install the new word; if returns False, word is same
2001 as before. True = also update widget fields. */
2002 /* This test determines whether we might need to continue. */
2003 if ( hw->help_dialog.srch.fullIndex
2004 || CheckSearchWord(hw,srchWord,True) == False )
2006 /* check to see if CheckSearchWord() was called. If it wasn't
2007 then srchWord has not been freed or saved. We will lose the
2008 memory unless we free it here. */
2009 if (hw->help_dialog.srch.fullIndex)
2012 /* are we continuing an interrupted search? */
2013 if ( hw->help_dialog.srch.volLeftCnt > 0
2014 && NULL != hw->help_dialog.srch.volListHead )
2015 return; /* RETURN: continue with search */
2017 /* if searching full index, False=dont free vol with full index */
2018 if (hw->help_dialog.srch.fullIndex)
2019 HitListFreeAllVolHits(hw,False);
2020 /* else we're searching on the same word, but completed
2021 previous search. So reset the volumes to search/display
2022 according to the current settings of the Volumes radio buttons,
2023 but leave the results intact.
2025 /* fall thru to do prep */
2027 else /* searching for a different word */
2029 /* free all hit-related data and reset flags */
2030 HitListFreeAllVolHits(hw,True); /*True=free everything*/
2033 /*** It's not just a continue. So, we may be beginning a new search
2034 or continuing a search based on new volume selection params ***/
2036 /* update display area */
2037 DeleteListContents(&hw->help_dialog.srch);
2038 StatusLabelUpdate(hw,WORKING_STATUS,False,0);
2040 /*** update the volumes list according to sources selected ***/
2041 if ( _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources )
2043 /* volume list already built when opening selection dialog */
2044 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
2045 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
2046 /* (T,T,T,T): enable search, enable display,
2047 zero hits ok, only for selected volumes */
2048 SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
2049 } /* if selected volumes button */
2050 else if ( _DtHelpGlobSrchAllVolumes == hw->help_dialog.srch.srchSources )
2052 /* Scan directories for volumes if necessary */
2053 if ( False == hw->help_dialog.srch.volScanDone
2054 || NULL == hw->help_dialog.srch.volListHead)
2056 /* Add on the Vol info; (T,T,F) search, display, all */
2057 VolListBuild(hw,True,True,False);
2060 /* (T,T,F,F): enable search,enable display,no 0 hits,for all vols */
2061 SetVolStatus(hw->help_dialog.srch.volListHead,True,True,False,False);
2062 } /* if all volumes button */
2063 else /*** current volume button ***/
2066 _DtHelpFileEntry cur;
2068 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
2069 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
2071 /* try to locate file and its entry, if present */
2072 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
2073 _DtHelpFileSuffixList,False,R_OK);
2074 cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
2075 GetVolumeInfoCB, _DtHELP_FILE_NAME,
2076 hw->help_dialog.help.pDisplayArea);
2078 if (NULL == cur && NULL != path) /*file was located but isn't in list*/
2079 { /* add it to the list */
2081 XmFontList origFontList;
2083 origFontList = hw->help_dialog.srch.volTitlesFontList;
2085 _DtHelpFileListAddFile(&hw->help_dialog.srch.volListHead,
2086 &hw->help_dialog.srch.volTitlesFontList,&mod,path,NULL,
2087 GetVolumeInfoCB, _DtHELP_FILE_NAME, _DtHELP_FILE_TITLE,
2088 hw->help_dialog.help.pDisplayArea);
2091 MergeFontListIntoWidgetFonts(
2092 hw->help_dialog.srch.resultList,
2093 hw->help_dialog.srch.volTitlesFontList);
2095 if (origFontList) XmFontListFree(origFontList);
2098 /* (F,F,F): disable search, disable display, for all volumes */
2099 AddVolInfoToList(hw->help_dialog.srch.volListHead,False,False,False);
2100 cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
2101 GetVolumeInfoCB, _DtHELP_FILE_NAME,
2102 hw->help_dialog.help.pDisplayArea);
2105 if (cur) /* file present in list */
2107 /* enable search and display on this volume */
2108 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) cur->clientData;
2110 vol->searchThisVolume = True;
2111 vol->showVolInList = True;
2112 vol->zeroHitsOk = True; /* show zero hits for search of cur vol */
2114 else /* file not found */
2116 /* FIX: put up error dialog and disable the button */
2117 /*printf("Current volume %s not found\n",
2118 hw->help_dialog.display.helpVolume);*/
2119 } /* if file found */
2121 XtFree(path); /* tests for NULL */
2122 } /* if selected/all/cur volumes sources */
2124 #if 0 || defined(DEBUG) /* for debug, set to 1 */
2125 OutputVolInfo(hw->help_dialog.srch.volListHead);
2128 /* get num volumes to process */
2129 hw->help_dialog.srch.volLeftCnt =
2130 CountSelectedVolumes(hw->help_dialog.srch.volListHead,True);
2132 /* empty the results list */
2133 XmUpdateDisplay(hw->help_dialog.srch.resultList);
2137 /************************************************************************
2138 * Function: CloseSearchCB()
2140 * Close the Global Search Dialog
2142 ************************************************************************/
2143 static void CloseSearchCB (
2145 XtPointer clientData,
2148 _DtHelpGlobSearchStuff * srch = (_DtHelpGlobSearchStuff *) clientData;
2150 /* stop any work proc */
2151 if(srch->workProcId)
2153 XtRemoveWorkProc(srch->workProcId);
2154 srch->workProcId = 0;
2157 /* unmanage the srchForm dialog but dont destroy it */
2158 if (NULL != srch->srchForm)
2160 XtUnmanageChild(srch->srchForm);
2161 XtUnmapWidget(srch->srchForm);
2166 /*****************************************************************************
2167 * Function: void DeleteListContents()
2171 * Return Value: Void.
2173 * Purpose: empties list and resets position values
2175 *****************************************************************************/
2176 static void DeleteListContents(
2177 _DtHelpGlobSearchStuff * srch)
2179 _DtHelpFileEntry curFile;
2181 if (NULL != srch->resultList)
2182 XmListDeleteAllItems(srch->resultList);
2184 for ( curFile = srch->volListHead;
2186 curFile = _DtHelpFileListGetNext(NULL,curFile) )
2188 register _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) curFile->clientData;
2189 if (NULL == vol) continue; /* CONTINUE */
2191 /* if any hits are displayed and any have open topics,
2192 walk through and close them */
2193 if ( vol->hitsDisplayed
2194 && ((vol->nextVolPosition - vol->startPosition) != vol->hitCnt) )
2196 register _DtHelpGlobSrchHit * hit;
2197 for ( hit = vol->hitListHead;
2201 hit->topicsDisplayed = False;
2205 vol->startPosition = 1;
2206 vol->nextVolPosition = 1;
2207 vol->hitsDisplayed = False;
2212 /*****************************************************************************
2213 * Function: void StatusLabelUpdate()
2217 * Return Value: Void.
2219 * Purpose: Installs proper label over results list
2221 *****************************************************************************/
2222 static void StatusLabelUpdate(
2223 DtHelpDialogWidget hw,
2224 ResultsStatus status,
2225 Boolean forceUpdate,
2229 XmString labelString;
2230 XmString curLabelString;
2235 /* only update if necessary */
2236 if (status == hw->help_dialog.srch.statusLineUsage && !forceUpdate)
2240 /* order up the right message */
2241 hw->help_dialog.srch.statusLineUsage = status;
2244 case SCANNING_STATUS:
2245 labelMsg = (char *)_DTGETMESSAGE(GSSET, 17,"Scanning for volumes... Found %d");
2246 sprintf(buf,labelMsg,intArg);
2249 case WORKING_STATUS:
2250 labelMsg = (char *)_DTGETMESSAGE(GSSET, 18,
2251 "Searching... Volumes remaining: %d");
2252 /* we need +1 because of when this message is used */
2253 sprintf(buf,labelMsg,hw->help_dialog.srch.volLeftCnt + 1);
2256 case SEARCH_RESULTS_STATUS:
2257 /* if no hits found */
2258 if (hw->help_dialog.srch.hitsFound == False) /*dont use == True*/
2260 if (hw->help_dialog.srch.fullIndex)
2262 if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchAllVolumes)
2263 labelMsg = (char *)_DTGETMESSAGE (GSSET,19,
2264 "No index entries found.");
2266 labelMsg = (char *)_DTGETMESSAGE (GSSET,50,
2267 "No index entries found. Try All Volumes.");
2269 else /* searched on a pattern */
2271 labelMsg = (char *)_DTGETMESSAGE (GSSET,51,
2272 "No index entries found. Try another word.");
2274 /* change focus to the search word. Traversal is ignored
2275 if srchWord is desensitized (Contains btn not selected) */
2277 if (XtIsSensitive(hw->help_dialog.srch.wordField))
2280 * make sure the text field is editable before sending
2281 * the traversal there.
2283 XtSetArg(args[0],XmNeditable,True);
2284 XtSetValues(hw->help_dialog.srch.wordField, args, 1);
2286 (hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
2290 (hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
2293 else /* if hits found */
2295 /* select the appropriate message */
2296 if (hw->help_dialog.srch.fullIndex)
2298 labelMsg = (char *)_DTGETMESSAGE(GSSET, 20,"Complete Index");
2303 labelMsg = (char *)_DTGETMESSAGE(GSSET, 21,"Entries with \"%s\"");
2304 sprintf(buf,labelMsg,hw->help_dialog.srch.rawWordStr);
2308 /* change focus to the results list */
2310 hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
2313 } /* if no hits found else */
2317 labelMsg = (char *)_DTGETMESSAGE (GSSET, 22,"No volumes selected");
2319 case FIRST_PROMPT_STATUS:
2320 labelMsg = (char *)_DTGETMESSAGE(GSSET,23,"Select search options above");
2324 /* DBG: when an empty string, form constraints are wrong; make a space */
2329 /* make a label string */
2330 labelString = XmStringCreateLocalized(labelMsg);
2332 /* get the current string of the label */
2333 curLabelString = NULL;
2334 XtSetArg(args[0],XmNlabelString,&curLabelString);
2335 XtGetValues (hw->help_dialog.srch.statusLabel, args, 1);
2337 /* update label if it is different; avoid flashing this way */
2338 if ( NULL != curLabelString && NULL != labelString
2339 && XmStringCompare(labelString,curLabelString) == False )
2341 /* update msg over results list */
2342 XtSetArg(args[0],XmNlabelString,labelString);
2343 XtSetValues(hw->help_dialog.srch.statusLabel,args,1);
2346 XmStringFree(labelString);
2347 XmStringFree(curLabelString);
2349 XmUpdateDisplay(hw->help_dialog.srch.statusLabel);
2355 /*****************************************************************************
2356 * Function: void ResultsListUpdate()
2360 * Return Value: Void.
2362 * Purpose: empty list and display results status message
2364 *****************************************************************************/
2365 static void ResultsListUpdate(
2366 DtHelpDialogWidget hw,
2367 _DtHelpFileEntry newFile)
2369 _DtHelpFileEntry testFile;
2371 /* check that in fact, there are no results that will be overwritten */
2372 for ( testFile = hw->help_dialog.srch.volListHead;
2374 testFile = _DtHelpFileListGetNext(NULL,testFile) )
2376 register _DtHelpGlobSrchVol * vol;
2377 vol = (_DtHelpGlobSrchVol *)testFile->clientData;
2378 if (vol && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk))
2382 /* clean the list out if this is the first new result */
2383 /* this presumes that files are processed in order in the list */
2384 if (testFile == newFile)
2386 DeleteListContents(&hw->help_dialog.srch);
2387 AdjustPositionValues(newFile,0,1,True);
2389 /* True: insert new item */
2390 VolNameDisplay(hw,newFile,True);
2392 /* Update status label */
2393 StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0); /* FIX: False */
2398 /*****************************************************************************
2399 * Function: void SearchForPattern()
2403 * Return Value: True if pattern found, False if not found
2405 * Purpose: Find a pattern in a string
2407 * WARNING: may convert string to uppercase in place
2408 * depending on which code is compiled.
2409 *****************************************************************************/
2410 static Boolean SearchForPattern(
2415 #if defined(NO_REGEX) /* don't support regex in string searches */
2418 _DtHelpCeUpperCase(string);
2419 /* FIX: make this code much faster by using an improved
2420 pattern search algorithm, such as Rabin-Karp. */
2421 /* hit is set to NULL if no matching char is found */
2422 while (_DtHelpCeStrchr(string, pattern, MB_CUR_MAX, &hit) == 0)
2424 if ( strncmp(hit,pattern,patternLen) == 0 )
2427 string = hit + mblen(hit,1);
2429 return (NULL != hit); /* RETURN True or False */
2430 #else /* if NO_REGEX */
2435 /* use regexec to pattern match */
2436 /* a 0 return value indicates success */
2437 if ( regcomp(&re,pattern,REG_NOSUB|REG_ICASE|REG_EXTENDED) == 0 )
2439 /* a 0 return value indicates success */
2440 ret = regexec(&re,string,0,NULL,0);
2443 return (ret == 0); /* RETURN True or False */
2444 # else /* NO_REGCOMP */
2448 /* a non NULL return value indicates success */
2449 compiledRE = (char *)regcmp(pattern, (char *) NULL);
2452 /* a non NULL return value indicates success */
2453 ret = regex(compiledRE, string);
2456 return (ret != NULL); /* RETURN True or False */
2457 # endif /* NO_REGCOMP */
2458 #endif /* if NO_REGEX */
2462 /*****************************************************************************
2463 * Function: void OpenVolForSearch()
2467 * Return Value: False if an error
2470 * Purpose: Opens a volume for searching,
2471 * gets the volume locale, if
2472 * different from system locale,
2473 * saves system locale in vol,
2474 * installs volume locale
2476 * Note that the system locale
2477 *****************************************************************************/
2478 static Boolean OpenVolForSearch(
2479 DtHelpDialogWidget hw,
2480 char * fullFilePath,
2481 _DtHelpGlobSrchVol * curVol)
2483 Boolean openedVolume = False;
2485 /* open the volume if not open */
2486 if ( NULL == curVol->volHandle )
2488 _DtHelpOpenVolume(fullFilePath, &curVol->volHandle);
2489 if (NULL == curVol->volHandle) return False; /* RETURN */
2491 if (curVol->gotLocale == False)
2493 curVol->stdLocale = _DtHelpGetVolumeLocale(curVol->volHandle);
2494 /* get the op-specific locales; the strings are default values */
2495 _DtHelpCeXlateStdToOpLocale(DtLCX_OPER_ICONV3,curVol->stdLocale,
2496 "iso88591",&curVol->iconv3Codeset);
2497 curVol->gotLocale = True;
2499 openedVolume = True;
2501 /* get the codeset of the application's locale, if haven't gotten it */
2502 if ( NULL == hw->help_dialog.srch.iconv3Codeset )
2504 char * locale = NULL;
2505 _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,
2506 setlocale(LC_CTYPE,NULL),&locale,NULL,NULL);
2507 /* get the op-specific locales; the strings are default values */
2508 /* impt: XlateStdToOpLocale() call requires a locale, not a codeset */
2509 _DtHelpCeXlateStdToOpLocale(DtLCX_OPER_ICONV3,locale,
2510 "iso88591",&hw->help_dialog.srch.iconv3Codeset);
2514 /** only saves or changes the locale if necessary **/
2515 /* create an iconv3 context to convert codeset of */
2516 /* the volume to the codeset of the application */
2517 if ( _DtHelpCeIconvContextSuitable(hw->help_dialog.srch.iconv3Context,
2518 curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset) == False )
2520 /* close old, open new */
2521 _DtHelpCeIconvClose(&hw->help_dialog.srch.iconv3Context);
2522 _DtHelpCeIconvOpen(&hw->help_dialog.srch.iconv3Context,
2523 curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset,' ',' ');
2526 /* else volume already open */
2528 /* if just opened volume */
2531 /* we just share pointers; when freeing localeWordStr, we need to
2532 test whether they are different before freeing */
2533 hw->help_dialog.srch.localeWordStr = hw->help_dialog.srch.normWordStr;
2536 /* get the str coll function, iff needed */
2537 if (NULL == curVol->strcollProc)
2539 /* get strcollProc for vol locale */
2540 curVol->strcollProc = _DtHelpCeGetStrcollProc();
2547 /*****************************************************************************
2548 * Function: void CloseVolAfterSearch()
2552 * Return Value: Void.
2554 * Purpose: Closes a volume opened for searching,
2555 * installs system locale, if diff from volume.
2557 *****************************************************************************/
2558 static void CloseVolAfterSearch(
2559 DtHelpDialogWidget hw,
2560 _DtHelpGlobSrchVol * curVol)
2562 /* close the volume if open */
2563 if ( NULL != curVol->volHandle )
2565 _DtHelpCloseVolume(curVol->volHandle);
2566 curVol->volHandle = NULL;
2567 /* free the locale word string, if allocated */
2568 if(hw->help_dialog.srch.localeWordStr!=hw->help_dialog.srch.normWordStr)
2570 XtFree(hw->help_dialog.srch.localeWordStr);
2571 hw->help_dialog.srch.localeWordStr = NULL;
2575 /* don't free the iconv context...may apply to the next volume */
2580 /*****************************************************************************
2581 * Function: void SearchTopic()
2585 * Return Value: Void.
2587 * Purpose: Get a single topic and search for the search word in it
2589 *****************************************************************************/
2590 static void SearchTopic(
2591 DtHelpDialogWidget hw,
2592 _DtHelpFileEntry curFile,
2593 _DtHelpGlobSrchVol * curVol,
2601 /* if the volume is not open; don't continue */
2602 if ( NULL == curVol->volHandle )
2603 return; /* RETURN */
2605 if ( NULL == curVol->indexEntriesList )
2606 _CEVolumeTopicList(curVol->volHandle,&curVol->indexEntriesList);
2607 if ( NULL == curVol->volHandle || NULL == curVol->indexEntriesList )
2609 curVol->topicSearchInProgress = False;
2610 curVol->topicSearchDone = True;
2611 curVol->indexSearchInProgress = True;
2612 if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
2613 return; /* RETURN */
2616 curVol->topicSearchInProgress = True;
2619 /* search the topics */
2620 /* note that indexEntriesList[0] is correct; ptr is incremented */
2621 /* we can increment the pointer because we don't own this memory;
2622 the open volume does. */
2624 i < numSearches && NULL != curVol->indexEntriesList[0];
2625 i++, curVol->indexEntriesList++ )
2627 char * topicTitle = NULL;
2630 validTopic = _DtHelpGetTopicTitle( curVol->volHandle,
2631 curVol->indexEntriesList[0],&topicTitle);
2634 /* look for a hit and process if there was one */
2635 if (SearchForPattern(topicTitle,srchWord,srchWordLen) == True)
2637 HitListAddFound(curFile, curVol->indexEntriesList[0], True, NULL);
2641 /* clean up and advance to next topic */
2643 curVol->searchedCnt++;
2644 } /* for all topics to search */
2647 if ( NULL == curVol->indexEntriesList /* no topics queried */
2648 || NULL == curVol->indexEntriesList[0] ) /* no more topics available */
2650 /* hand off to next stage */
2651 curVol->indexEntriesList = NULL;
2652 curVol->topicSearchInProgress = False;
2653 curVol->topicSearchDone = True;
2654 curVol->indexSearchInProgress = True;
2661 /*****************************************************************************
2662 * Function: void SearchIndex()
2666 * Return Value: void
2668 * Purpose: Get a single Index and search for the search word in it
2670 * Commentary: There are two strings for each index entry.
2671 * One string is the straight text in
2672 * the codeset of the volume. The
2673 * other string is a XmString that
2674 * has a font tag that will allow
2675 * it to be displayed in the
2678 * Preconditions: This code requires that the volume to be search
2679 * has already been opened [OpenVolForSearch()],
2680 * that the locale of the volume has been installed,
2681 * and that the search word is in the same code
2682 * set as the volume and has been converted to
2685 *****************************************************************************/
2686 static void SearchIndex(
2687 DtHelpDialogWidget hw,
2688 _DtHelpFileEntry curFile,
2689 _DtHelpGlobSrchVol * curVol,
2690 _DtHelpCeIconvContext iconvContext,
2696 char * indexEntry = NULL;
2697 size_t entryLen = 100; /* starting size */
2700 /* if the volume is not open; don't continue */
2701 if ( NULL == curVol->volHandle )
2702 return; /* RETURN */
2704 /* get the XmStrings of the entries */
2705 if ( NULL == curVol->indexXmStrsList )
2707 XmFontList fontList = NULL;
2708 Boolean mod = False;
2711 /* get results font list */
2712 XtSetArg(args[0], XmNfontList, &fontList);
2713 XtGetValues(hw->help_dialog.srch.resultList,args,1);
2716 /* Don't need to copy, _DtHelpFormatVolumeTitle copies
2720 /* work with copy, because FontListAppendEntry() destroys input FL */
2721 fontList = XmFontListCopy(fontList);
2724 /* get the entries */
2725 _DtHelpFormatIndexEntries(hw->help_dialog.help.pDisplayArea,
2726 curVol->volHandle,&numEntries, &curVol->indexXmStrsList,
2729 /* install the changed list */
2732 XtSetArg(args[0], XmNfontList, fontList);
2733 XtSetValues(hw->help_dialog.srch.resultList,args,1);
2734 if (fontList) XmFontListFree(fontList);
2738 /* get the pure strings for searching */
2739 if ( NULL == curVol->indexEntriesList )
2741 /* recall that the array and strings pointed to by
2742 the indexEntriesList is owned by the open volume */
2743 _DtHelpCeGetKeywordList(curVol->volHandle,&curVol->indexEntriesList);
2745 /* and re-init curIndexXmStr */
2746 curVol->curIndexXmStr = curVol->indexXmStrsList;
2749 if ( NULL == curVol->volHandle
2750 || NULL == curVol->indexEntriesList
2751 || NULL == curVol->indexXmStrsList )
2753 curVol->indexSearchInProgress = False;
2754 curVol->indexSearchDone = True;
2755 curVol->searchCompleted = True;
2756 if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
2757 return; /* RETURN */
2760 curVol->indexSearchInProgress = True;
2762 /* alloc memory for index processing */
2763 indexEntry = XtMalloc(sizeof(char)*(entryLen+1));
2764 if (NULL == indexEntry) return; /* RETURN */
2766 /* get a index entry */
2768 i < numSearches && NULL != curVol->indexEntriesList[0];
2769 i++, curVol->indexEntriesList++, curVol->curIndexXmStr++ )
2771 /* prevent overflow of buffer */
2772 if (strlen(curVol->indexEntriesList[0]) > entryLen)
2774 entryLen = strlen(curVol->indexEntriesList[0]) + 50;
2775 indexEntry = XtRealloc(indexEntry,entryLen+1);
2776 if (NULL == indexEntry) break; /* BREAK */
2778 indexEntry[0] = EOS; /* init to empty string */
2780 /* look for a hit and process if there was one */
2781 /* if srchWord is NULL, all entries are hits */
2782 /* copy, and possible iconv, the index string into the */
2783 /* the codeset of srchWord (the application) */
2784 if ( NULL == srchWord
2785 || ( _DtHelpCeIconvStr(iconvContext,curVol->indexEntriesList[0],
2786 &indexEntry, &entryLen,indexEntry,entryLen) == 0
2787 && SearchForPattern(indexEntry, srchWord, srchWordLen) == True ) )
2789 _DtHelpGlobSrchHit * hit;
2790 char * * topicIdList;
2792 HitListAddFound ( curFile, curVol->curIndexXmStr[0],
2793 curVol->indexEntriesList[0], True, &hit);
2795 /* topicIdList is set but not allocated & need not be freed */
2796 hit->topicCnt = _DtHelpCeFindKeyword(curVol->volHandle,
2797 hit->indexEntry,&topicIdList);
2800 /* clean up and advance to next topic */
2801 curVol->searchedCnt++;
2804 if ( NULL == curVol->indexEntriesList /*no topics queried*/
2805 || NULL == curVol->indexEntriesList[0] )/*no more index entries avail*/
2807 /* hand off to next stage */
2808 curVol->indexEntriesList = NULL; /* init */
2809 curVol->curIndexXmStr = curVol->indexXmStrsList; /* re-init */
2810 curVol->indexSearchInProgress = False;
2811 curVol->indexSearchDone = True;
2812 curVol->searchCompleted = True;
2819 /*****************************************************************************
2820 * Function: void SearchVolume()
2824 * Return Value: Void.
2826 * Purpose: do the search operation
2827 * This routine does incremental search--it searchs
2828 * a little, then returns to allow further processing.
2829 * It is called whenever Xt detects no other events.
2831 *****************************************************************************/
2832 static void SearchVolume(
2833 DtHelpDialogWidget hw,
2834 _DtHelpFileEntry curFile,
2835 _DtHelpGlobSrchVol * curVol,
2838 XmString labelString;
2842 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
2843 if (hw->help_dialog.srch.selectionDlg)
2844 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
2846 /* Process according to state */
2847 if ( curVol->nothingDone )
2849 curVol->nothingDone = False;
2850 curVol->topicSearchInProgress = True;
2852 /* Update the search status string */
2853 sprintf(buf,(char *)_DTGETMESSAGE(GSSET,18,
2854 "Searching... Volumes remaining: %d"),
2855 hw->help_dialog.srch.volLeftCnt);
2856 labelString = XmStringCreateLocalized(buf);
2857 XtSetArg(args[0],XmNlabelString,labelString);
2858 XtSetValues (hw->help_dialog.srch.statusLabel, args, 1);
2859 XmStringFree(labelString);
2861 XmUpdateDisplay((Widget) hw->help_dialog.srch.statusLabel);
2864 OpenVolForSearch(hw,curFile->fullFilePath,curVol);
2866 if ( curVol->topicSearchInProgress )
2868 SearchTopic(hw, curFile,curVol,hw->help_dialog.srch.localeWordStr,
2869 hw->help_dialog.srch.wordFieldLen, numSearches);
2872 /* NOTE: because this isn't an "else if", we could potentially
2873 search for 2*numSearches; but I know that I've disabled the
2874 topic search. Furthermore, my code depends upon the possibility
2875 of searching an entire volume in one call to the routine, if
2876 desired, and having an else if would break that.
2878 if ( curVol->indexSearchInProgress )
2881 srchWord = hw->help_dialog.srch.localeWordStr;
2882 /* FullIndex search indicated by a null search word string */
2883 if (hw->help_dialog.srch.fullIndex) srchWord = NULL;
2884 SearchIndex(hw, curFile, curVol, hw->help_dialog.srch.iconv3Context,
2885 srchWord, hw->help_dialog.srch.wordFieldLen, numSearches);
2888 /* If search was completed, update dependent stuff */
2889 if (curVol->searchCompleted)
2891 /* handle completion */
2892 CloseVolAfterSearch(hw,curVol);
2893 curVol->indexEntriesList = NULL; /* mem not owned by GlobSrch */
2894 if (hw->help_dialog.srch.fullIndex)
2895 curVol->gatheredFullIndex = True;
2896 hw->help_dialog.srch.volLeftCnt--;
2897 if (hw->help_dialog.srch.volLeftCnt < 0)
2898 hw->help_dialog.srch.volLeftCnt = 0;
2901 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
2902 if (hw->help_dialog.srch.selectionDlg)
2903 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
2908 /*****************************************************************************
2909 * Function: void SearchFile()
2913 * Return Value: Void.
2915 * Purpose: do the search operation on an entire file
2916 * It searches the entire file at once
2917 * and displays the results in the list.
2919 *****************************************************************************/
2920 static void SearchFile(
2921 DtHelpDialogWidget hw,
2922 _DtHelpFileEntry file)
2924 register _DtHelpGlobSrchVol * vol;
2926 /* get volume info, adding if necessary */
2927 vol = (_DtHelpGlobSrchVol *) file->clientData;
2928 /* (T,T,F): enable search, enable display, any volume */
2929 if (NULL == vol) AddVolInfoToFile(file, True, True, False);
2930 vol = (_DtHelpGlobSrchVol *) file->clientData;
2931 if (NULL == vol) return;
2933 /* conduct search of entire volume in one call */
2934 hw->help_dialog.srch.volLeftCnt = 1;
2935 vol->searchThisVolume = True;
2936 vol->showVolInList = True;
2937 vol->zeroHitsOk = True;
2938 SearchVolume(hw,file,vol,INT_MAX);
2941 StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);/*FIX: False*/
2943 /* update the list to show the volume */
2944 AdjustPositionValues(file,0,1,True);
2945 /* True: do insert new item */
2946 VolNameDisplay(hw,file,True);
2948 if (vol->showHitsWithVol)
2950 VolHitsDisplay(hw,file);
2951 /* False: don't insert new item */
2952 VolNameDisplay(hw,file,False);
2959 /*****************************************************************************
2960 * Function: void DoBackgroundSearchWP(
2961 * XtPointer clientData)
2967 * Return Value: Void.
2969 * Purpose: do the search operation in the background
2970 * This routine does incremental search--it searchs
2971 * a little, then returns to allow further processing.
2972 * It is called whenever Xt detects no other events.
2974 *****************************************************************************/
2975 static Boolean DoBackgroundSearchWP(
2976 XtPointer clientData)
2978 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
2979 _DtHelpFileEntry curFile;
2980 _DtHelpGlobSrchVol * curVol = NULL;
2982 if ( 0 == hw->help_dialog.srch.volLeftCnt )
2983 goto searchComplete; /* GOTO: done! */
2985 /* get file to work on */
2986 curFile = hw->help_dialog.srch.curSrchVol;
2987 if ( NULL == curFile )
2989 curFile = GetNextSearchFileAndDisplayCompleted(
2990 hw, hw->help_dialog.srch.volListHead, NULL);
2991 if ( NULL == curFile ) goto searchComplete; /* GOTO: done */
2992 hw->help_dialog.srch.curSrchVol = curFile;
2993 } /* if no current file */
2995 /* get volume info */
2996 curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
2998 #define NUM_SEARCHES_PER_CALL 30
2999 SearchVolume(hw,curFile,curVol,NUM_SEARCHES_PER_CALL);
3001 /* If search was completed, update dependent stuff */
3002 if (curVol->searchCompleted)
3004 /* update the search results list */
3005 /* True: adjust count beginning with this file */
3006 if (curVol->hitCnt > 0 || curVol->zeroHitsOk)
3008 /* record that a hit found */
3009 if ( curVol->hitCnt > 0
3010 || ( curVol->zeroHitsOk
3011 && _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
3012 hw->help_dialog.srch.hitsFound = True;
3014 /* update the list to show the volume */
3015 AdjustPositionValues(curFile,0,1,True);
3016 ResultsListUpdate(hw,curFile);
3018 /* update the list to show the hits? */
3019 if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
3021 VolHitsDisplay(hw,curFile);
3022 /* False: don't insert new item */
3023 VolNameDisplay(hw,curFile,False);
3025 XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
3028 /* prepare for next search */
3029 hw->help_dialog.srch.curSrchVol =
3030 GetNextSearchFileAndDisplayCompleted(hw,NULL,curFile);
3032 } /* if search completed */
3035 if ( hw->help_dialog.srch.volLeftCnt > 0
3036 || False == curVol->searchCompleted )
3037 return False; /* RETURN: False ==> continue processing */
3039 /* Do this when no more files are left to search */
3042 XmPushButtonCallbackStruct status;
3044 /* zero search data before stopping */
3045 hw->help_dialog.srch.volLeftCnt = 0; /* just in case */
3046 hw->help_dialog.srch.curSrchVol = NULL; /* just in case */
3048 /* generate a fake event to reset the dialog */
3049 status.reason = XmCR_ACTIVATE;
3050 status.event = NULL;
3051 status.click_count = 1;
3052 StopSearchCB(hw->help_dialog.srch.actionBtn,
3053 (XtPointer)hw,(XtPointer)&status);
3055 return True; /* RETURN: True ==> stop processing */
3061 /*****************************************************************************
3062 * Function: void StartSearchCB(Widget w,
3063 * XtPointer clientData,
3064 * XtPointer callData);
3070 * Return Value: Void.
3072 * Purpose: Create a new user bookmark
3074 * Warning: This CB is also used by the volume selection buttons
3075 * to activate a search when they are selected. The routine
3076 * cannot rely upon the w or callData params. The clientData
3077 * will always be the help widget.
3078 *****************************************************************************/
3079 static void StartSearchCB(
3080 Widget w, /* dont use */
3081 XtPointer clientData,
3082 XtPointer callData) /* dont use */
3084 char *srchWord = NULL;
3085 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3086 XtAppContext appCntx;
3090 /* set state of start button correctly */
3091 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
3093 /* if help content isn't a volume, it has no index */
3094 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
3095 && hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC )
3096 return; /* RETURN */
3098 /* retrieve the name */
3099 srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
3101 /* test for empty (also emtpy spaces) and only process if not emtpy */
3102 _DtHelpCeCompressSpace(srchWord);
3103 if ( (strlen(srchWord) > (size_t) 0 || hw->help_dialog.srch.fullIndex)
3104 && hw->help_dialog.srch.workProcId == 0)
3105 /* test on workProcId prevents multiple activations due to
3106 race condition on desensitizing the start button */
3108 _DtHelpTurnOnHourGlass(XtParent(hw));
3109 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3110 if (hw->help_dialog.srch.selectionDlg)
3111 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3113 /*XtSetSensitive (hw->help_dialog.srch.actionBtn,False);*/
3114 XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False);
3115 XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,False);
3116 XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,False);
3117 XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
3119 /* 9/26/94: these two XtSetArgs (and following SetValues) cause a core dump
3120 for the SunOS 5.3 optimized executable. It isn't a problem for the
3121 non-optimized or debuggable versions or any versions on AIX 3.2 or
3123 #if !defined(sun) && !defined(__osf__)
3125 XtSetArg(args[n],XmNeditable,False); n++;
3126 XtSetArg(args[n],XmNcursorPositionVisible,False); n++;
3127 XtSetValues (hw->help_dialog.srch.wordField, args, n);
3129 XmUpdateDisplay(hw->help_dialog.srch.srchForm);
3131 /* process the source selection and retain in widget srchWord memory */
3132 PrepSearchSourceData(hw, srchWord);
3134 /* activate search thread; do it even with a 0 count, because the
3135 process reactivates the dialog after search is completed */
3136 appCntx = XtWidgetToApplicationContext((Widget) hw);
3137 hw->help_dialog.srch.workProcId =
3138 XtAppAddWorkProc(appCntx,DoBackgroundSearchWP, (XtPointer) hw);
3140 hw->help_dialog.srch.searchInProgress = True;
3142 /* dont free srchWord */
3144 /* turn on "Stop" label */
3145 UpdateActionButtonLabel(hw,NULL,False);
3147 _DtHelpTurnOffHourGlass(XtParent(hw));
3148 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3149 if (hw->help_dialog.srch.selectionDlg)
3150 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3154 if ( strlen(srchWord) == 0 )
3155 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
3163 /*****************************************************************************
3164 * Function: void StartSelectedVolumeSearchCB(Widget w,
3165 * XtPointer clientData,
3166 * XtPointer callData);
3172 * Return Value: Void.
3174 * Purpose: Begin a search on the selected volume
3176 *****************************************************************************/
3177 static void StartSelectedVolumeSearchCB(
3179 XtPointer clientData,
3182 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3183 _DtHelpFileEntry file;
3185 Boolean noSelectedFiles = True;
3187 /* if not full index search */
3188 if (hw->help_dialog.srch.fullIndex == False)
3190 /* get the current contents of the search word field */
3191 srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
3193 /* test the word ; False=dontUpdate--do this in PrepSearchSourceData() */
3194 if ( CheckSearchWord(hw,srchWord,False) == True )
3195 { /* word has changed since last search; do a whole new search */
3196 StartSearchCB(NULL,(XtPointer) hw, NULL);
3197 return; /* RETURN */
3200 /* if the text field is empty, do nothing */
3201 if ( strlen(hw->help_dialog.srch.normWordStr) == 0 )
3202 return; /* RETURN */
3205 /* set this to true to counteract False if no hits */
3206 hw->help_dialog.srch.hitsFound = True;
3208 /* Word is the same, just the selection has changed. */
3209 /* Determine which one was selected or deselected */
3210 for ( file = hw->help_dialog.srch.volListHead;
3212 file = _DtHelpFileListGetNext(NULL,file) )
3214 register _DtHelpGlobSrchVol * vol;
3215 vol = (_DtHelpGlobSrchVol *) file->clientData;
3216 if (NULL == vol) continue;
3219 if (file->fileSelected) noSelectedFiles = False;
3221 /* test for contradictory flags; fileSelected reflects dialog list */
3222 if (file->fileSelected != vol->showVolInList)
3224 /* file has been deselected */
3225 if (False == file->fileSelected)
3227 if (vol->showVolInList)
3229 /* update list: delete hits, topics, and volume title */
3230 if (vol->hitsDisplayed) VolHitsUndisplay(hw,file);
3232 /* delete hits first, then volume */
3234 hw->help_dialog.srch.resultList,vol->startPosition);
3235 AdjustPositionValues(file, 0, -1, True);
3236 vol->showVolInList = False;
3237 vol->searchThisVolume = False;
3240 else /* file has been selected */
3242 SearchFile(hw,file);
3243 } /* if file de/selected */
3244 } /* if contradictory flags */
3245 } /* for all volumes */
3248 if (noSelectedFiles) StatusLabelUpdate(hw,NO_VOL_STATUS,True,0);
3253 /*****************************************************************************
3254 * Function: void UpdateSearchStartStatusCB(Widget w,
3255 * XtPointer clientData,
3256 * XtPointer callData);
3262 * Return Value: Void.
3264 * Purpose: update the status of the search status button
3265 * Routine is called whenever text is changed in the search
3268 *****************************************************************************/
3269 static void UpdateSearchStartStatusCB(
3271 XtPointer clientData,
3274 char *srchWord = NULL;
3275 /*XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) callData;*/
3276 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3279 /* retrieve the name */
3280 srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
3282 /* test for empty (also emtpy spaces) */
3283 _DtHelpCeCompressSpace(srchWord);
3285 /* FIX: change the locale from the volume locale back to the system
3286 locale temporarily (if not already in that locale) */
3287 _DtHelpCeUpperCase(srchWord);
3289 /* only sensitize if working on a help volume and word is not emtpy
3292 if ( ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
3293 && hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC)
3294 || ( strlen(srchWord) == (size_t) 0
3295 && hw->help_dialog.srch.fullIndex == False))
3297 XtSetSensitive (hw->help_dialog.srch.actionBtn,newState);
3299 /* if word has changed from word of previous search, change to Start */
3300 UpdateActionButtonLabel(hw,srchWord,True);
3306 /*****************************************************************************
3307 * Function: void StopSearchCB(Widget w,
3308 * XtPointer clientData,
3309 * XtPointer callData);
3315 * Return Value: Void.
3317 * Purpose: Stop the search
3319 *****************************************************************************/
3320 static void StopSearchCB(
3322 XtPointer clientData,
3325 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3330 /* stop the search thread */
3331 if(hw->help_dialog.srch.workProcId != 0)
3332 XtRemoveWorkProc(hw->help_dialog.srch.workProcId);
3333 hw->help_dialog.srch.workProcId = 0;
3335 hw->help_dialog.srch.searchInProgress = False;
3337 /* update statuses */
3339 XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,
3340 hw->help_dialog.srch.curVolRadBtnSens);
3342 XtSetSensitive (hw->help_dialog.srch.curVolRadBtn, TRUE);
3345 XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,True);
3346 XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,True);
3348 XtSetArg(args[n],XmNeditable,True); n++;
3349 XtSetArg(args[n],XmNcursorPositionVisible,True); n++;
3350 XtSetValues (hw->help_dialog.srch.wordField, args, n);
3352 /* update select btn status; only when selected and dialog closed */
3353 XtSetArg(args[0],XmNset,&cur);
3354 XtGetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
3355 XtSetSensitive(hw->help_dialog.srch.selectBtn,
3356 cur && ( NULL == hw->help_dialog.srch.selectionDlg
3357 || !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
3359 /* set the action button label appropriately */
3360 UpdateActionButtonLabel(hw,hw->help_dialog.srch.normWordStr,True);
3362 /* post message of results */
3363 StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);
3369 /*****************************************************************************
3370 * Function: void ActionButtonCB(Widget w,
3371 * XtPointer clientData,
3372 * XtPointer callData);
3378 * Return Value: Void.
3380 * Purpose: Act upon the action
3382 *****************************************************************************/
3383 static void ActionButtonCB(
3385 XtPointer clientData,
3388 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3390 if ( hw->help_dialog.srch.searchInProgress == False )
3391 StartSearchCB(w,clientData,callData);
3393 StopSearchCB(w,clientData,callData);
3399 /*****************************************************************************
3400 * Function: void GotoResultCB(Widget w,
3401 * XtPointer clientData,
3402 * XtPointer callData);
3408 * Return Value: Void.
3410 * Purpose: Goto a result topic
3412 *****************************************************************************/
3413 static void GotoResultCB(
3415 XtPointer clientData,
3418 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3419 char * helpFile = NULL;
3420 int * topicPosList=NULL;
3425 /* Determine the item selected and find that item in our list */
3426 status = XmListGetSelectedPos(hw->help_dialog.srch.resultList, &topicPosList,&i);
3428 /* if true, an item selected */
3429 if (status && topicPosList)
3431 _DtHelpGlobSrchHit * entry = NULL;
3432 _DtHelpFileEntry file = NULL;
3433 char * locationId = NULL;
3434 topicPosition = topicPosList[0] - 1; /* convert to 0 based */
3435 XtFree((String)topicPosList);
3438 HitListGetNth(hw->help_dialog.srch.volListHead,
3439 topicPosition,&file,&entry,&locationId,&helpFile);
3441 /* jump to selected location */
3442 XtFree(hw->help_dialog.display.locationId);
3443 hw->help_dialog.display.locationId = XtNewString(locationId);
3444 XtFree(hw->help_dialog.display.helpVolume);
3445 hw->help_dialog.display.helpVolume = XtNewString(helpFile);
3446 hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
3447 hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
3449 _DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
3453 if (topicPosList) XtFree((String)topicPosList);
3455 /* FIX: Put up a message to suggest selecting an item first */
3456 /* Don't close the dialog */
3459 #endif /* not_used */
3461 #if 0 /* save--used in code commented out elsewhere in this file */
3463 /*****************************************************************************
3464 * Function: void CloseHelpCB()
3468 * Return Value: Void.
3470 * Purpose: Close and destroy the help widget
3472 *****************************************************************************/
3473 static void CloseHelpCB(
3475 XtPointer clientData,
3481 #endif /* save--used in code commented out elsewhere in this file */
3484 /*****************************************************************************
3485 * Function: void GotoLocation(hw,helpVolume,location)
3489 * Return Value: Void.
3491 * Purpose: Goto a topic by opening a new help dialog window
3493 *****************************************************************************/
3494 static void GotoLocation(
3495 DtHelpDialogWidget hw,
3499 #if 0 /* don't delete...useful as reference */
3505 /* This opens a new help window on the topic */
3507 XtSetArg( args[n], XmNtitle, "Help" ); n++;
3508 XtSetArg( args[n], DtNhelpType, DtHELP_TYPE_TOPIC ); n++;
3509 XtSetArg( args[n], DtNlocationId, locationId ); n++;
3510 XtSetArg( args[n], DtNhelpVolume, helpVolume ); n++;
3511 helpDlg = DtCreateHelpDialog(XtParent(hw),"mainHelpDialog",args,n);
3512 XtAddCallback(helpDlg,DtNcloseCallback,CloseHelpCB,helpDlg);
3513 XtManageChild(helpDlg);
3517 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3518 if (hw->help_dialog.srch.selectionDlg)
3519 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3521 /* jump to selected location in same window */
3522 XtFree(hw->help_dialog.display.locationId);
3523 hw->help_dialog.display.locationId = XtNewString(locationId);
3524 XtFree(hw->help_dialog.display.helpVolume);
3525 hw->help_dialog.display.helpVolume = XtNewString(helpVolume);
3526 hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
3527 hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
3529 _DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
3531 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3532 if (hw->help_dialog.srch.selectionDlg)
3533 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
3540 /*****************************************************************************
3541 * Function: void ProcessResultSelectionCB(Widget w,
3542 * XtPointer clientData,
3543 * XtPointer callData);
3549 * Return Value: Void.
3551 * Purpose: Process user selection of an item in the result List.
3553 *****************************************************************************/
3554 static void ProcessResultSelectionCB(
3556 XtPointer clientData,
3559 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3560 int * topicPosList = NULL;
3565 /* Determine the item selected and find that item in our list */
3566 status = XmListGetSelectedPos(
3567 hw->help_dialog.srch.resultList, &topicPosList,&n);
3569 /* if true, an item selected */
3570 if (status && topicPosList)
3572 _DtHelpFileEntry file = NULL;
3573 _DtHelpGlobSrchHit * hit = NULL;
3574 char * locationId = NULL;
3575 char * helpFile = NULL;
3577 topicPosition = topicPosList[0]; /* 1 based */
3578 XtFree((String)topicPosList);
3581 if ( HitListGetNth(hw->help_dialog.srch.volListHead,
3582 topicPosition,&file,&hit,&locationId,&helpFile) == 0 )
3584 _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3587 XmListDeselectPos(hw->help_dialog.srch.resultList,topicPosition);
3589 /* was a volume item selected? */
3592 _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
3593 if (vol->hitCnt > 0)
3595 if (False == vol->hitsDisplayed)
3597 VolHitsDisplay(hw,file); /* toggle state */
3601 VolHitsUndisplay(hw,file);
3602 vol->showHitsWithVol = False;
3604 /* update the volume label to show the state */
3605 /* False: dont insert hw item */
3606 VolNameDisplay(hw,file,False);
3608 /* else don't otherwise handle a 0-hits volume */
3610 /* was an expandable index selected */
3611 else if (NULL == locationId && hit->topicCnt > 1)
3615 /* if we're turning them on, build a list */
3616 if (False == hit->topicsDisplayed)
3618 topicCnt = HitTopicsDisplay(hw,file,hit,topicPosition+1);
3622 topicCnt = - HitTopicsUndisplay(hw,file,hit,topicPosition+1);
3623 hit->showTopicsWithHit = False;
3625 /* update the hit label to show the state; False--dont insert */
3626 HitNameDisplay(hw,file,hit,topicPosition,False);
3628 /* add to all the following */
3631 /* adjust count beginning with next file with hits */
3632 AdjustPositionValues(file, 0, topicCnt, True);
3635 /* a location or index with one topic was selected */
3638 /* if a single click, goto the location */
3639 if (hit->topicCnt == 1)
3641 if ( HitLoadTopics(hw,file,hit) == 0 )
3643 GotoLocation(hw, file->fullFilePath, hit->topicIdList[0]);
3644 HitFree(hit,False); /*release what was loaded 3 lines up*/
3647 { /* volume couldn't be opened or some other error */
3648 /* FIX: error message */
3650 } /* if an index with a single topic */
3652 { /* a location from an open multi-topic index entry */
3653 GotoLocation(hw, file->fullFilePath, locationId);
3655 } /* else index with one topic or topic was selected */
3657 /* finish up processing a selection */
3658 _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
3660 } /* got the nth item */
3662 else /* could not find the nth hit */
3664 if (topicPosList) XtFree((String)topicPosList);
3671 /*****************************************************************************
3672 * Function: void CloseVolSelDialogCB(Widget w,
3673 * XtPointer clientData,
3674 * XtPointer callData);
3678 * Return Value: Void.
3680 * Purpose: Resets the selection dialog variable to NULL
3682 *****************************************************************************/
3683 static void CloseVolSelDialogCB(
3685 XtPointer clientData,
3688 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3690 /* unmanage & destroy the dialog zero the variable */
3691 if ( hw->help_dialog.srch.selectionDlg
3692 && XtIsManaged(hw->help_dialog.srch.selectionDlg) )
3693 XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
3695 /* start a search to be sure we got all changes; FIX: need this??? */
3696 /*StartSearchCB(NULL,hw,NULL);*/
3697 XtSetSensitive(hw->help_dialog.srch.selectBtn,True);
3700 if (hw->help_dialog.srch.hitsFound == True)
3701 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
3703 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
3708 /*****************************************************************************
3709 * Function: void CreateVolSelDialog(
3713 * Return Value: Void.
3715 * Purpose: Creates selection dialog to chose volumes
3717 *****************************************************************************/
3718 static void CreateVolSelDialog(
3719 DtHelpDialogWidget hw)
3722 _DtHelpFileDlgChildren dlgChld;
3723 Atom wm_delete_window;
3726 /* desensitize the button */
3727 XtSetSensitive(hw->help_dialog.srch.selectBtn,False);
3729 /* only create one */
3730 if ( NULL != hw->help_dialog.srch.selectionDlg )
3732 XtManageChild(hw->help_dialog.srch.selectionDlg);
3736 /* open the modal dialog and let user select the volumes */
3737 selDlg = _DtHelpFileListCreateSelectionDialog(
3738 hw, hw->help_dialog.srch.srchForm, False,
3739 (char *)_DTGETMESSAGE (GSSET, 40,
3740 "Help - Search Volume Selection"),
3741 &hw->help_dialog.srch.volTitlesFontList,
3742 hw->help_dialog.srch.volListHead, &dlgChld);
3743 hw->help_dialog.srch.selectionDlg = selDlg;
3745 XtAddCallback(dlgChld.closeBtn, XmNactivateCallback,
3746 CloseVolSelDialogCB,(XtPointer)hw);
3747 XtAddCallback(dlgChld.form, XmNunmapCallback,
3748 CloseVolSelDialogCB,(XtPointer)hw);
3750 /* set the default response to a WM_DELETE_WINDOW message
3751 to no response instead of UNMAP. */
3752 XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
3753 XtSetValues(dlgChld.shell, args, 1);
3754 wm_delete_window = XmInternAtom(XtDisplay(dlgChld.shell),
3755 "WM_DELETE_WINDOW", FALSE);
3756 XmAddWMProtocolCallback(dlgChld.shell,wm_delete_window,
3757 (XtCallbackProc)CloseVolSelDialogCB, (XtPointer)hw);
3759 XtAddCallback(dlgChld.list, XmNsingleSelectionCallback,
3760 StartSelectedVolumeSearchCB, (XtPointer) hw);
3761 XtAddCallback(dlgChld.list, XmNmultipleSelectionCallback,
3762 StartSelectedVolumeSearchCB, (XtPointer) hw);
3763 XtAddCallback(dlgChld.list, XmNextendedSelectionCallback,
3764 StartSelectedVolumeSearchCB, (XtPointer) hw);
3765 XtAddCallback(dlgChld.list, XmNdefaultActionCallback,
3766 StartSelectedVolumeSearchCB, (XtPointer) hw);
3771 /*****************************************************************************
3772 * Function: void OpenSelectDialogCB(Widget w,
3773 * XtPointer clientData,
3774 * XtPointer callData);
3780 * Return Value: Void.
3782 * Purpose: Process user selection of the select button
3784 *****************************************************************************/
3785 static void OpenSelectDialogCB(
3787 XtPointer clientData,
3790 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3792 /* only build the list of files if it hasn't been done */
3793 if ( False == hw->help_dialog.srch.volScanDone
3794 || NULL == hw->help_dialog.srch.volListHead)
3796 /* Add on the Vol info; (T,T,T) search, display, selected only */
3797 VolListBuild(hw,True,True,True);
3800 /* FIX: the modal behaviour doesn't seem to be set; is it desired/needed? */
3801 /* don't need to worry about having open twice, since
3802 the dialog is always opened in modal mode from the search dialog */
3803 /* open the dialog and let user select the volumes */
3804 CreateVolSelDialog(hw);
3808 /*****************************************************************************
3809 * Function: void UpdateSearchVolumesCB(Widget w,
3810 * XtPointer clientData,
3811 * XtPointer callData);
3817 * Return Value: Void.
3819 * Purpose: Process user selection of a button in the Volumes Radio box
3821 *****************************************************************************/
3822 static void UpdateSearchVolumesCB(
3824 XtPointer clientData,
3827 XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
3828 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3834 if (hw->help_dialog.srch.hitsFound == True)
3835 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
3837 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
3841 /* if turning off the button, just reinforce the current settings.
3842 This message occurs when an on button is hit again. */
3843 if ( False == status->set )
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.selVolRadBtn == widget);
3848 XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
3849 XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
3850 XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
3854 /*** if work when something is turned on; ignore the off messages
3855 except when the button is the selected volumes button; we
3856 want to catch every click on that button */
3857 if ( XmCR_VALUE_CHANGED == status->reason
3858 && True == status->set
3859 && NULL != status->event ) /* event is NULL for 1st of the two calls
3860 to this routine that are made when a
3861 button is pressed. */
3863 /*** now update the sources value according to button selected ***/
3864 hw->help_dialog.srch.volLeftCnt = 0; /* change invalidates prior search */
3865 UpdateActionButtonLabel(hw,NULL,True);
3867 XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
3868 XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
3869 XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
3870 XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
3871 XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
3872 XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
3874 /*** selected volumes button activated ***/
3875 if (hw->help_dialog.srch.selVolRadBtn == widget)
3878 hw->help_dialog.srch.srchSources = _DtHelpGlobSrchSelectedVolumes;
3880 /* only build the list of files if it hasn't been done */
3881 if ( False == hw->help_dialog.srch.volScanDone
3882 || NULL == hw->help_dialog.srch.volListHead)
3884 /* Add on the Vol info; (T,T,T) search, display, selected only */
3885 VolListBuild(hw,True,True,True);
3888 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
3889 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
3890 /* (T,T,T,T): enable search, enable display,
3891 zero hits ok, only for selected volumes */
3892 /* Set these here so that the CountSelectedVolumes() works right */
3893 SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
3895 /* count all volumes selected, including those already searched */
3896 if (CountSelectedVolumes(hw->help_dialog.srch.volListHead,True)==0)
3898 StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
3899 DeleteListContents(&hw->help_dialog.srch);
3900 CreateVolSelDialog(hw);
3901 /* NOTE: don't start search here, start it from the callback */
3902 /* set state of start button correctly */
3903 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
3905 else /* volumes already selected; just display */
3907 hw->help_dialog.srch.hitsFound = False; /*DBG*/
3908 StartSearchCB(NULL,(XtPointer) hw, NULL);
3910 } /* if selected volumes button */
3912 /*** all volumes button ***/
3913 else if (hw->help_dialog.srch.allVolRadBtn == widget)
3915 /* close the selection dialog, if open */
3916 if (hw->help_dialog.srch.selectionDlg)
3917 XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
3919 /* set sources state */
3920 hw->help_dialog.srch.srchSources = _DtHelpGlobSrchAllVolumes;
3921 hw->help_dialog.srch.hitsFound = False; /*DBG*/
3922 StartSearchCB(NULL,(XtPointer) hw, NULL);
3924 /*** current volume button ***/
3927 /* close the selection dialog, if open */
3928 if (hw->help_dialog.srch.selectionDlg)
3929 XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
3931 /* set sources state */
3932 hw->help_dialog.srch.srchSources = _DtHelpGlobSrchCurVolume;
3933 hw->help_dialog.srch.hitsFound = False; /*DBG*/
3934 StartSearchCB(NULL,(XtPointer) hw, NULL);
3937 /* update the Select... button status */
3938 /* do this last, so that while searching for volumes (VolListBuild),
3939 the button is not active. */
3940 XtSetSensitive(hw->help_dialog.srch.selectBtn,
3941 (hw->help_dialog.srch.selVolRadBtn == widget)
3942 && ( NULL == hw->help_dialog.srch.selectionDlg
3943 || !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
3945 } /* if value changed */
3950 /*****************************************************************************
3951 * Function: void UpdateIndexSelectionCB(Widget w,
3952 * XtPointer clientData,
3953 * XtPointer callData);
3959 * Return Value: Void.
3961 * Purpose: Process user selection of a button in the Entries Radio box
3963 *****************************************************************************/
3964 static void UpdateIndexSelectionCB(
3966 XtPointer clientData,
3969 XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
3970 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
3971 Boolean containsState;
3976 if (hw->help_dialog.srch.hitsFound == True)
3977 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
3979 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
3982 /* if turning off the button, just reinforce the current settings.
3983 This message occurs when an on button is hit again. */
3984 if ( False == status->set )
3986 containsState = (hw->help_dialog.srch.containsRadBtn == widget);
3987 XtSetArg(args[0], XmNset, !containsState);
3988 XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
3989 XtSetArg(args[0], XmNset, containsState);
3990 XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
3994 /*** if work when something is turned on; ignore the off messages
3995 except when the button is the selected volumes button; we
3996 want to catch every click on that button */
3997 if ( XmCR_VALUE_CHANGED == status->reason
3998 && True == status->set
3999 && NULL != status->event ) /* event is NULL for 1st of the two calls
4000 to this routine that are made when a
4001 button is pressed. */
4003 /* if search in progress, stop it */
4004 if(hw->help_dialog.srch.searchInProgress||hw->help_dialog.srch.workProcId)
4006 XmPushButtonCallbackStruct status;
4008 /* generate a fake event to reset the dialog */
4009 status.reason = XmCR_ACTIVATE;
4010 status.event = NULL;
4011 status.click_count = 1;
4012 StopSearchCB(hw->help_dialog.srch.actionBtn,
4013 (XtPointer)hw,(XtPointer)&status);
4016 containsState = (hw->help_dialog.srch.containsRadBtn == widget);
4017 XtSetArg(args[0], XmNset, !containsState);
4018 XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
4019 XtSetArg(args[0], XmNset, containsState);
4020 XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
4022 /* sensitize/desensitize the Contains text field */
4023 XtSetSensitive(hw->help_dialog.srch.wordField,containsState);
4025 XtSetArg(args[n],XmNeditable,containsState); n++;
4026 XtSetArg(args[n],XmNcursorPositionVisible,containsState); n++;
4027 XtSetValues(hw->help_dialog.srch.wordField,args,n);
4029 /* set widget status here; do this way bec. srchFullIndex is a bit flag */
4030 hw->help_dialog.srch.fullIndex = (containsState ? False : True); /*flag*/
4032 /* set state of start button correctly */
4033 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
4036 { /* if changing to "Containing" */
4037 /* change focus to the search word */
4038 XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
4039 /* user will need to hit CR to initiate search */
4042 { /* if changing to full index */
4043 /* indicate that no contains word is valid by deleting it */
4044 /* FIX: I'm concerned that normWordStr & localeWordStr aren't in synch */
4045 XtFree(hw->help_dialog.srch.normWordStr);
4046 hw->help_dialog.srch.normWordStr = NULL;
4047 /* search full index */
4048 StartSearchCB(NULL,(XtPointer) hw, NULL);
4051 /* and search to update results to the new state */
4052 } /* if value changed */
4057 /*****************************************************************************
4058 * Function: void ContainsDisarmCB(Widget w,
4059 * XtPointer clientData,
4060 * XtPointer callData);
4066 * Return Value: Void.
4068 * Purpose: Process disarm of the contains radio button
4070 *****************************************************************************/
4071 static void ContainsDisarmCB(
4073 XtPointer clientData,
4076 XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
4077 DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
4079 /* Force focus to the word field if set. */
4080 if (True==status->set)
4081 XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
4086 /*****************************************************************************
4087 * Function: CreateCurVolBtnLabel()
4092 * Return Value: True or False if current vol has an index
4094 * Purpose: Creates the label for the current volume button
4096 *****************************************************************************/
4097 static Boolean CreateCurVolBtnLabel(
4098 DtHelpDialogWidget hw,
4099 Boolean * out_curVolAvailable,
4100 XmString * out_labelString,
4101 char * * out_mnemonic)
4106 XmString volTitleString = NULL;
4107 XmString preTitleString = NULL;
4108 XmString postTitleString = NULL;
4110 XmString labelString;
4112 Boolean curVolAvail;
4117 if (out_curVolAvailable)
4118 *out_curVolAvailable = False;
4119 if (out_labelString)
4120 *out_labelString = XmStringCreateLocalized("dum");
4126 /* if help content is a volume, get the title */
4127 if ( hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC )
4129 /* determine whether a current volume index is available */
4130 curVolAvail = VolumeHasIndexP(
4131 hw->help_dialog.srch.srchSources,
4132 hw->help_dialog.display.helpType,
4133 hw->help_dialog.display.helpVolume);
4135 /* change False to True to search home dir; may want this */
4136 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
4137 _DtHelpFileSuffixList,False,R_OK);
4139 /* title needs to be an XmString to use volume's font */
4142 XmFontList fontList = NULL;
4143 Boolean mod = False;
4145 /* get the font list of the btn */
4147 XtSetArg (args[n], XmNfontList, &fontList); n++;
4148 XtGetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
4150 #if defined(DONT_USE_CDExc22774)
4151 /* copy the list before passing it in for modification */
4152 fontList = XmFontListCopy (fontList);
4155 GetVolumeInfoCB(hw->help_dialog.help.pDisplayArea,path,
4156 NULL,&volTitleString,NULL,NULL,NULL,&fontList,&mod);
4158 /* if font list was changed, install it */
4161 /* set the font list of the btn */
4163 XtSetArg (args[n], XmNfontList, fontList); n++;
4164 XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
4165 if (fontList) XmFontListFree (fontList);
4170 if (NULL == volTitleString)
4171 volTitleString = XmStringCreateLocalized(
4172 hw->help_dialog.display.helpVolume);
4173 } /* if helpType == TOPIC */
4175 { /* if helpType != TOPIC */
4176 curVolAvail = False;
4177 switch (hw->help_dialog.display.helpType)
4179 case DtHELP_TYPE_STRING:
4180 case DtHELP_TYPE_DYNAMIC_STRING:
4181 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4182 (GSSET, 32,"Help Message")));
4184 case DtHELP_TYPE_FILE:
4185 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4186 (GSSET, 33,"Help File")));
4188 case DtHELP_TYPE_MAN_PAGE:
4189 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4190 (GSSET, 34,"Manual Page")));
4193 volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4194 (GSSET, 35,"Unknown Format")));
4196 } /* switch on helpType */
4197 } /* if helpType != TOPIC */
4199 /* record path in the widget */
4200 XtFree(hw->help_dialog.srch.curVolPath);
4201 hw->help_dialog.srch.curVolPath = path;
4204 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4205 (GSSET, 3,"Current")));
4206 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 4,"r"));*/
4209 /* append volume name to title */
4210 preTitle = (char *)_DTGETMESSAGE(GSSET, 60," (");
4211 preTitleString = XmStringCreateLocalized(preTitle);
4212 postTitle = (char *)_DTGETMESSAGE(GSSET, 61,")");
4213 postTitleString = XmStringCreateLocalized(postTitle);
4215 newTitle = XmStringConcat(labelString,preTitleString);
4216 XmStringFree(labelString);
4217 XmStringFree(preTitleString);
4218 labelString = newTitle;
4220 newTitle = XmStringConcat(labelString,volTitleString);
4221 XmStringFree(labelString);
4222 XmStringFree(volTitleString);
4223 labelString = newTitle;
4225 newTitle = XmStringConcat(labelString,postTitleString);
4226 XmStringFree(labelString);
4227 XmStringFree(postTitleString);
4228 labelString = newTitle;
4230 /* set the out values */
4231 if (out_curVolAvailable) *out_curVolAvailable = curVolAvail;
4232 if (out_mnemonic) *out_mnemonic = mnemonic;
4233 if (out_labelString) *out_labelString = labelString;
4234 else XmStringFree(labelString);
4242 /*****************************************************************************
4243 * Function: void CreateGlobSrchDialog()
4250 * Purpose: Creates and displays an instance of the search dialog.
4252 *****************************************************************************/
4253 static void CreateGlobSrchDialog(
4260 /* Widget topWidget; */
4261 Widget volumesFrame;
4266 XmString labelString;
4267 /* char * mnemonic; */
4268 Dimension widgetHeight;
4269 Dimension widgetBorderHeight;
4271 DtHelpListStruct *pHelpInfo;
4272 Atom wm_delete_window;
4273 DtHelpDialogWidget hw = (DtHelpDialogWidget) nw ;
4274 XtTranslations btnTransTable;
4275 /* XtTranslations listTransTable; */
4276 /* XtTranslations mgrTransTable; */
4277 Boolean curVolAvailable;
4281 /* get state of the volume */
4282 curVolAvailable = VolumeHasIndexP (
4283 hw->help_dialog.srch.srchSources,
4284 hw->help_dialog.display.helpType,
4285 hw->help_dialog.display.helpVolume);
4287 /* Set up the translations table stuff */
4288 btnTransTable = XtParseTranslationTable(defaultBtnTranslations);
4289 /* listTransTable = XtParseTranslationTable(defaultListTranslations); */
4290 /* mgrTransTable = XtParseTranslationTable(defaultMgrTranslations); */
4292 /* Create the shell used for the dialog. */
4293 title = XtNewString(((char *)_DTGETMESSAGE(GSSET,1,"Help - Index Search")));
4295 XtSetArg (args[n], XmNtitle, title); n++;
4296 XtSetArg (args[n], XmNallowShellResize, True); n++;
4297 srchShell = XmCreateDialogShell((Widget) hw, "searchShell", args, n);
4300 /* Set the useAsyncGeo on the shell */
4302 XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
4303 XtSetValues (XtParent(srchShell), args, n); /* parent is new's shell */
4305 /* Adjust the decorations for the dialog shell of the dialog */
4307 XtSetArg(args[n], XmNmwmFunctions, 0); n++;
4308 XtSetArg (args[n], XmNmwmDecorations,
4309 MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
4310 XtSetValues (srchShell, args, n);
4313 /* Grab the window mgr close and install a close dialog
4314 callback when closed from dialog WM menu; this prevents
4315 the dialog from closing the host application. */
4316 wm_delete_window = XmInternAtom(XtDisplay(srchShell),
4317 "WM_DELETE_WINDOW", FALSE);
4318 XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
4319 XmAddWMProtocolCallback(srchShell,wm_delete_window,
4320 CloseSearchCB, (XtPointer)&hw->help_dialog.srch);
4321 XtSetValues(srchShell, args, 1);
4323 /* set the callback that positions the dialog when popped up */
4324 XtAddCallback (srchShell, XmNpopupCallback,
4325 (XtCallbackProc)_DtHelpMapCB, (XtPointer) XtParent(hw));
4327 /*** Create the form used for the dialog. ***/
4328 /* setting RESIZE_NONE is important to prevent the resultList from
4329 dynamically resizing as items with various fonts are added and
4332 XtSetArg (args[n], XmNmarginWidth, 1); n++;
4333 XtSetArg (args[n], XmNmarginHeight, 1); n++;
4334 XtSetArg (args[n], XmNshadowThickness, 1); n++;
4335 XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT); n++;
4336 XtSetArg (args[n], XmNautoUnmanage, False); n++;
4337 XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
4338 parentForm = XmCreateForm (srchShell, "parentForm", args, n);
4339 hw->help_dialog.srch.srchForm = parentForm;
4341 /*==============================================================*/
4342 /****** Create the volumes region ******/
4344 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
4345 XtSetArg (args[n], XmNtopOffset, 5); n++;
4346 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4347 XtSetArg (args[n], XmNrightOffset, 5); n++;
4348 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4349 XtSetArg (args[n], XmNleftOffset, 5); n++;
4350 XtSetArg (args[n], XmNmarginWidth, 5); n++;
4351 XtSetArg (args[n], XmNmarginHeight, 2); n++;
4352 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
4353 volumesFrame = XmCreateFrame(parentForm, "volFrame", args, n);
4354 XtManageChild (volumesFrame);
4356 /* put form inside frame */
4357 volumesForm = XmCreateForm (volumesFrame, "volumesForm", args, 0);
4358 XtManageChild (volumesForm);
4360 /* create the frame title */
4361 labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,2, "Search")));
4363 XtSetArg (args[n], XmNlabelString, labelString); n++;
4364 XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
4365 XtSetArg (args[n], XmNtraversalOn, False); n++;
4366 frameTitle = XmCreateLabelGadget(volumesFrame, "volFrameTitle", args, n);
4367 XtManageChild (frameTitle);
4368 XmStringFree (labelString);
4370 /* create Current Volume radio button */
4371 /* Use a dummy label until CreateCurVolBtnLabel can be used.
4372 It refs the srchCurVolRadBtn widget and other things that need
4375 labelString = XmStringCreateLocalized (" ");
4377 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4378 XtSetArg (args[n], XmNset, TRUE); n++;
4380 XtSetArg(args[n], XmNlabelString, labelString); n++;
4381 XtSetArg (args[n], XmNmarginHeight, 0); n++;
4382 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
4383 XtSetArg (args[n], XmNtopOffset, 0); n++;
4384 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4385 XtSetArg (args[n], XmNleftOffset, 5); n++;
4386 /* Attaching to form causes the hilite outline of the button to
4387 stretch to the form edge when selected. But it also forces
4388 the form to resize when the current volume title is too big
4389 for the available space. */
4390 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4391 XtSetArg (args[n], XmNrightOffset, 10); n++;
4392 XtSetArg (args[n], XmNbottomOffset, 0); n++;
4393 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4394 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4395 hw->help_dialog.srch.curVolRadBtn =
4396 XmCreateToggleButtonGadget(volumesForm,"srchCurVolRadBtn",args,n);
4397 XtAddCallback(hw->help_dialog.srch.curVolRadBtn,XmNvalueChangedCallback,
4398 UpdateSearchVolumesCB, (XtPointer) hw);
4399 /* ??? XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False); */
4400 XtManageChild (hw->help_dialog.srch.curVolRadBtn);
4401 XmStringFree (labelString);
4403 /* create All Volumes radio button */
4404 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4405 (GSSET, 5,"All Volumes")));
4406 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 7,"A"));*/
4409 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4410 XtSetArg (args[n], XmNset, FALSE); n++;
4411 XtSetArg (args[n], XmNlabelString, labelString); n++;
4412 XtSetArg (args[n], XmNmarginHeight, 0); n++;
4413 XtSetArg (args[n], XmNmarginWidth, 2); n++;
4414 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4415 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.curVolRadBtn); 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], XmNhighlightOnEnter, True); n++;
4420 hw->help_dialog.srch.allVolRadBtn =
4421 XmCreateToggleButtonGadget(volumesForm,"srchAllVolRadBtn",args, n);
4422 XtAddCallback(hw->help_dialog.srch.allVolRadBtn,XmNvalueChangedCallback,
4423 UpdateSearchVolumesCB, (XtPointer) hw);
4424 XtManageChild (hw->help_dialog.srch.allVolRadBtn);
4425 XmStringFree (labelString);
4427 /* create Selected Volumes radio button */
4428 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4429 (GSSET, 6,"Selected")));
4430 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 9,"d"));*/
4433 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4434 XtSetArg (args[n], XmNlabelString, labelString); n++;
4435 XtSetArg (args[n], XmNmarginHeight, 0); n++;
4436 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4437 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
4438 XtSetArg (args[n], XmNtopOffset, 1); n++;
4439 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4440 XtSetArg (args[n], XmNleftOffset, 5); n++;
4441 XtSetArg (args[n], XmNbottomOffset, 2); n++;
4442 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4443 hw->help_dialog.srch.selVolRadBtn =
4444 XmCreateToggleButtonGadget(volumesForm,"srchSelVolRadBtn", args, n);
4445 XtAddCallback(hw->help_dialog.srch.selVolRadBtn,XmNvalueChangedCallback,
4446 UpdateSearchVolumesCB, (XtPointer) hw);
4447 XtManageChild (hw->help_dialog.srch.selVolRadBtn);
4448 XmStringFree (labelString);
4451 /* Create Selected... button */
4452 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4453 (GSSET, 7,"Select Volumes...")));
4456 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4457 XtSetArg (args[n], XmNtopOffset, 0); n++;
4458 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
4459 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4460 XtSetArg (args[n], XmNrightOffset, 10); n++;
4461 XtSetArg (args[n], XmNbottomOffset, 2); n++;
4462 XtSetArg (args[n], XmNmarginTop, 0); n++;
4463 XtSetArg (args[n], XmNmarginHeight, 3); n++;
4464 XtSetArg (args[n], XmNlabelString, labelString); n++;
4465 hw->help_dialog.srch.selectBtn =
4466 XmCreatePushButtonGadget(volumesForm,"selectBtn", args, n);
4467 XtAddCallback (hw->help_dialog.srch.selectBtn, XmNactivateCallback,
4468 OpenSelectDialogCB, (XtPointer) hw);
4469 XtManageChild (hw->help_dialog.srch.selectBtn);
4470 XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
4471 XmStringFree (labelString);
4473 /****** Create the show selection region ******/
4475 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4476 XtSetArg (args[n], XmNtopWidget, volumesFrame); n++;
4477 XtSetArg (args[n], XmNtopOffset, 5); n++;
4478 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4479 XtSetArg (args[n], XmNrightOffset, 5); n++;
4480 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4481 XtSetArg (args[n], XmNleftOffset, 5); n++;
4482 XtSetArg (args[n], XmNmarginWidth, 5); n++;
4483 XtSetArg (args[n], XmNmarginHeight, 2); n++;
4484 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
4485 showFrame = XmCreateFrame(parentForm, "showFrame", args, n);
4486 XtManageChild (showFrame);
4488 /* FIX: is this doing enough? Goal: CR activation of FullIndex */
4489 /* Setup the proper translation on the title box widget */
4490 /* XtAugmentTranslations(showFrame, mgrTransTable); */
4492 /* put form inside frame */
4493 showForm = XmCreateForm (showFrame, "showForm", args, 0);
4494 XtManageChild (showForm);
4496 /* create the frame title */
4497 labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,8, "Show")));
4499 XtSetArg (args[n], XmNlabelString, labelString); n++;
4500 XtSetArg (args[n], XmNtraversalOn, False); n++;
4501 XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
4502 frameTitle = XmCreateLabelGadget(showFrame, "showFrameTitle", args, n);
4503 XtManageChild (frameTitle);
4504 XmStringFree (labelString);
4506 /* create the All Entries button */
4507 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4508 (GSSET, 9,"Complete Index")));
4511 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4512 XtSetArg (args[n], XmNset, True); n++;
4513 XtSetArg (args[n], XmNlabelString, labelString); n++;
4514 XtSetArg (args[n], XmNmarginHeight, 1); n++;
4515 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
4516 XtSetArg (args[n], XmNtopOffset, 0); n++;
4517 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4518 XtSetArg (args[n], XmNleftOffset, 5); n++;
4519 XtSetArg (args[n], XmNbottomOffset, 0); n++;
4520 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4521 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4522 hw->help_dialog.srch.fullIndexRadBtn =
4523 XmCreateToggleButtonGadget(showForm,"srchFullIndexRadBtn",args,n);
4524 XtAddCallback(hw->help_dialog.srch.fullIndexRadBtn,XmNvalueChangedCallback,
4525 UpdateIndexSelectionCB, (XtPointer) hw);
4526 XtManageChild (hw->help_dialog.srch.fullIndexRadBtn);
4527 XmStringFree (labelString);
4529 /* create Contains radio button */
4530 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4531 (GSSET, 10,"Entries with:")));
4532 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 16,"n"));*/
4535 XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
4536 XtSetArg (args[n], XmNset, False); n++;
4537 XtSetArg (args[n], XmNlabelString, labelString); n++;
4538 XtSetArg (args[n], XmNmarginHeight, 1); n++;
4539 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4540 XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn);n++;
4541 XtSetArg (args[n], XmNtopOffset, 1); n++;
4542 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4543 XtSetArg (args[n], XmNleftOffset, 5); n++;
4544 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4545 XtSetArg (args[n], XmNbottomOffset, 4); n++;
4546 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4547 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4548 hw->help_dialog.srch.containsRadBtn =
4549 XmCreateToggleButtonGadget(showForm,"srchContainsRadBtn",args,n);
4550 XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNvalueChangedCallback,
4551 UpdateIndexSelectionCB, (XtPointer) hw);
4552 XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNdisarmCallback,
4553 ContainsDisarmCB, (XtPointer) hw);
4554 XtManageChild (hw->help_dialog.srch.containsRadBtn);
4555 XmStringFree (labelString);
4557 /* create the search name text field */
4559 XtSetArg (args[n], XmNvalue, ""); n++;
4560 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4561 XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn); n++;
4562 XtSetArg (args[n], XmNtopOffset, 0); n++;
4563 XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
4564 XtSetArg (args[n], XmNleftWidget,hw->help_dialog.srch.containsRadBtn); n++;
4565 XtSetArg (args[n], XmNleftOffset, 5); n++;
4566 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4567 XtSetArg (args[n], XmNrightOffset, 10); n++;
4568 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4569 XtSetArg (args[n], XmNbottomOffset, 3); n++;
4570 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4571 XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
4572 hw->help_dialog.srch.wordField =
4573 XmCreateTextField (showForm,"srchWord",args, n);
4574 XtSetSensitive(hw->help_dialog.srch.wordField,False);
4575 XtManageChild (hw->help_dialog.srch.wordField);
4576 /* Because the actionBtn is the default button on the form,
4577 and it activates a search, we do not need to (nor do we want
4578 to, since ActionButtonCB toggles between states) make it
4579 a callback on activation of the text field */
4580 XtAddCallback (hw->help_dialog.srch.wordField, XmNvalueChangedCallback,
4581 UpdateSearchStartStatusCB, (XtPointer) hw);
4583 /* Setup the proper translation on the text field widget */
4584 XtAugmentTranslations(hw->help_dialog.srch.wordField, btnTransTable);
4587 /* Create a separator search specs and result area */
4589 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4590 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4591 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4592 XtSetArg (args[n], XmNtopWidget, showFrame); n++;
4593 XtSetArg (args[n], XmNtopOffset, 10); n++;
4594 separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
4595 XtManageChild (separator);
4597 /*==============================================================*/
4598 /****** result related stuff *******/
4599 /* Create result List Label */
4601 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4602 XtSetArg (args[n], XmNtopWidget, separator); n++;
4603 XtSetArg (args[n], XmNtopOffset, 10); n++;
4604 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4605 XtSetArg (args[n], XmNleftOffset, 10); n++;
4606 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4607 XtSetArg (args[n], XmNrightOffset, 10); n++;
4608 XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
4609 hw->help_dialog.srch.statusLabel =
4610 XmCreateLabelGadget (parentForm, "resultListLabel", args, n);
4611 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,True,0); /* installs a label */
4612 XtManageChild (hw->help_dialog.srch.statusLabel);
4614 /* Create our result topics scrolled list (not placed on form) */
4616 XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
4617 XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
4618 XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
4619 XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
4620 hw->help_dialog.srch.resultList =
4621 XmCreateScrolledList (parentForm, "resultList", args, n);
4622 XtManageChild (hw->help_dialog.srch.resultList);
4624 XtAddCallback (hw->help_dialog.srch.resultList, XmNsingleSelectionCallback,
4625 ProcessResultSelectionCB, (XtPointer) hw);
4626 XtAddCallback (hw->help_dialog.srch.resultList, XmNdefaultActionCallback,
4627 ProcessResultSelectionCB, (XtPointer) hw);
4629 /* Set the constraints on our scrolled list (place on form) */
4631 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4632 XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.statusLabel); n++;
4633 XtSetArg (args[n], XmNtopOffset, 5); n++;
4634 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4635 XtSetArg (args[n], XmNleftOffset, 10); n++;
4636 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4637 XtSetArg (args[n], XmNrightOffset, 10); n++;
4638 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4639 XtSetArg (args[n], XmNbottomOffset, 70); n++;
4640 /* 70 is just a rough value that will be updated with a calculated
4641 value below, after we know the height of the buttons */
4642 XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
4644 /* Create a separator between the buttons */
4646 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
4647 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
4648 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4649 XtSetArg (args[n], XmNtopWidget,
4650 XtParent (hw->help_dialog.srch.resultList)); n++;
4651 XtSetArg (args[n], XmNtopOffset, 5); n++;
4652 separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
4653 XtManageChild (separator);
4655 /***** search spec-related stuff *****/
4656 /* Create start button (left of stop button)*/
4657 _DtHelpProcessLock();
4658 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4659 (GSSET, START_SEARCH_CAT,START_SEARCH_STR)));
4660 _DtHelpProcessUnlock();
4661 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
4664 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4665 XtSetArg (args[n], XmNtopWidget, separator); n++;
4666 XtSetArg (args[n], XmNtopOffset, 5); n++;
4667 /* L & R position set below */
4668 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4669 XtSetArg (args[n], XmNbottomOffset, 5); n++;
4670 /*XtSetArg (args[n], XmNmarginHeight, 3); n++;*/
4671 XtSetArg (args[n], XmNlabelString, labelString); n++;
4672 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4673 hw->help_dialog.srch.actionBtn =
4674 XmCreatePushButtonGadget(parentForm,"actionBtn", args, n);
4675 XtAddCallback (hw->help_dialog.srch.actionBtn, XmNactivateCallback,
4676 ActionButtonCB, (XtPointer) hw);
4677 XtSetSensitive (hw->help_dialog.srch.actionBtn,False);
4678 XtManageChild (hw->help_dialog.srch.actionBtn);
4679 XmStringFree (labelString);
4681 XtSetArg (args[0], XmNdefaultButton, hw->help_dialog.srch.actionBtn);
4682 XtSetValues (parentForm, args, 1);
4684 /* Build the Cancel Button */
4685 _DtHelpProcessLock();
4686 labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
4687 (GSSET, CLOSE_BTN_CAT,CLOSE_BTN_STR)));
4688 _DtHelpProcessUnlock();
4689 /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 25,CLOSE_BTN_MNEM));*/
4691 XtSetArg (args[n], XmNlabelString, labelString); n++;
4692 /* L & R position set below */
4693 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4694 XtSetArg (args[n], XmNtopWidget, separator); n++;
4695 XtSetArg (args[n], XmNtopOffset, 5); n++;
4696 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4697 XtSetArg (args[n], XmNbottomOffset, 5); n++;
4698 XtSetArg (args[n], XmNmarginHeight, 3); n++;
4699 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4700 hw->help_dialog.srch.closeBtn =
4701 XmCreatePushButtonGadget (parentForm, "srchCloseBtn", args, n);
4703 XtAddCallback(hw->help_dialog.srch.closeBtn,
4704 XmNactivateCallback, CloseSearchCB,(XtPointer) &hw->help_dialog.srch);
4706 XtManageChild (hw->help_dialog.srch.closeBtn);
4707 XmStringFree (labelString);
4709 /* Build the Help button */
4710 _DtHelpProcessLock();
4711 labelString = XmStringCreateLocalized((char *)_DTGETMESSAGE
4712 (GSSET, HELP_BTN_CAT,HELP_BTN_STR));
4713 _DtHelpProcessUnlock();
4714 /*mnemonic = (char *)_DTGETMESSAGE(GSSET, 27,HELP_BTN_MNEM);*/
4717 XtSetArg (args[n], XmNlabelString, labelString); n++;
4718 /* L & R position set below */
4719 XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
4720 XtSetArg (args[n], XmNtopWidget, separator); n++;
4721 XtSetArg (args[n], XmNtopOffset, 5); n++;
4722 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4723 XtSetArg (args[n], XmNbottomOffset, 5); n++;
4724 XtSetArg (args[n], XmNmarginHeight, 3); n++;
4725 XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
4726 hw->help_dialog.srch.helpBtn =
4727 XmCreatePushButtonGadget (parentForm, "srchHelpBtn", args, n);
4728 XtManageChild (hw->help_dialog.srch.helpBtn);
4729 XmStringFree (labelString);
4731 pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexHelpBtn_STR,
4732 (Widget) hw, &hw->help_dialog.help,
4733 &hw->help_dialog.help.pHelpListHead);
4734 XtAddCallback(hw->help_dialog.srch.helpBtn, XmNactivateCallback,
4735 _DtHelpCB, (XtPointer) pHelpInfo);
4737 /*==============================================================*/
4738 /****** finishing touches *******/
4739 /* set the Form cancel button (for KCancel) */
4741 XtSetArg (args[n], XmNcancelButton, hw->help_dialog.srch.closeBtn); n++;
4742 XtSetValues (parentForm, args, n);
4744 { /* position buttons */
4745 /* This code adds up the sizes of the buttons to go into
4746 the bottom row and calculates the form position percentages.
4747 All buttons are the same size, and are able to hold all
4748 the strings that may be dynamically placed in them.
4749 All buttons are 5% apart. */
4750 /* This code is specifically written to handle 3 buttons
4751 and assumes that the first 3 strings are to the ActionBtn */
4753 Dimension maxWidth = 0;
4754 Dimension borderWidth = 0;
4755 Dimension sumWidth = 0;
4757 float posList[11]; /* need 11 due to algorithm, which uses index 10 */
4758 XmFontList fontList = NULL;
4761 /* get the fontList for the button */
4762 XtSetArg (args[0], XmNborderWidth, &borderWidth);
4763 XtSetArg (args[1], XmNfontList, &fontList);
4764 XtGetValues (hw->help_dialog.srch.actionBtn, args, 2);
4766 #define BETBUTSPACE 5 /* pixels */
4767 sumWidth = BETBUTSPACE; /* left side space */
4768 posList[0] = (float) sumWidth;
4769 for (i=0; i<NUMSTRS; i++)
4771 XmString labelString;
4773 _DtHelpProcessLock();
4774 s_GlobSrchDlgBtnStrs[i] = (char *) _DTGETMESSAGE(GSSET,
4775 s_GlobSrchDlgBtnCatNum[i],s_GlobSrchDlgBtnStrs[i]);
4776 labelString = XmStringCreateLocalized(s_GlobSrchDlgBtnStrs[i]);
4777 _DtHelpProcessUnlock();
4778 #define MARGINS 4 /* pixel margins: 2=L, 2=R */
4779 width = XmStringWidth(fontList,labelString) + borderWidth + MARGINS;
4780 if (i<=2) maxWidth = max(width,maxWidth);
4781 if (i==2) width = maxWidth; /* 1st three labels go in 1st button */
4782 if (i>=2) /* after scanning just labels, do buttons */
4785 posList[i*2+1] = (float) sumWidth;
4786 sumWidth += BETBUTSPACE;
4787 posList[i*2+2] = (float) sumWidth;
4789 XmStringFree(labelString);
4790 } /* for calcing widths */
4792 /* scale pixels to percent */
4793 scale = 100.0 / (float) sumWidth;
4796 XtSetArg (args[n], XmNwidth, maxWidth); n++;
4797 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
4798 XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[0]*scale)); n++;
4799 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
4800 XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[5]*scale)); n++;
4801 XtSetValues (hw->help_dialog.srch.actionBtn, args, n);
4804 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
4805 XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[6]*scale)); n++;
4806 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
4807 XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[7]*scale)); n++;
4808 XtSetValues (hw->help_dialog.srch.closeBtn, args, n);
4811 XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
4812 XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[8]*scale)); n++;
4813 XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
4814 XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[9]*scale)); n++;
4815 XtSetValues (hw->help_dialog.srch.helpBtn, args, n);
4818 { /* set the proper offset between the bottom of the results list
4819 and the bottom of the form to maintain a constant sized
4823 /* first calc offset of list to form bottom based on earlier sizes */
4824 #define KNOWN_OFFSETS_BELOW_LIST 20 /* actually only 15, but 15 fails */
4826 XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
4827 XtSetArg(args[n], XmNheight, &widgetHeight); n++;
4828 XtGetValues(hw->help_dialog.srch.actionBtn, args, n);
4829 offset = widgetHeight + 2 * widgetBorderHeight;
4830 XtGetValues(separator, args, n);
4831 offset += widgetHeight + 2 * widgetBorderHeight;
4832 XtGetValues(XtParent(hw->help_dialog.srch.resultList), args, 1);
4833 offset += widgetBorderHeight;
4834 offset += KNOWN_OFFSETS_BELOW_LIST;
4836 /* then set the offset */
4838 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
4839 XtSetArg (args[n], XmNbottomOffset, offset); n++;
4840 XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
4843 /** force tabs to go to each widget and in right order **/
4844 XtSetArg (args[0], XmNnavigationType, XmSTICKY_TAB_GROUP);
4845 XtSetValues (hw->help_dialog.srch.curVolRadBtn,args,1);
4846 XtSetValues (hw->help_dialog.srch.allVolRadBtn,args,1);
4847 XtSetValues (hw->help_dialog.srch.selVolRadBtn,args,1);
4848 XtSetValues (hw->help_dialog.srch.selectBtn,args,1);
4849 XtSetValues (hw->help_dialog.srch.fullIndexRadBtn,args,1);
4850 XtSetValues (hw->help_dialog.srch.containsRadBtn,args,1);
4851 XtSetValues (hw->help_dialog.srch.wordField,args,1);
4852 XtSetValues (hw->help_dialog.srch.resultList,args,1);
4853 XtSetValues (hw->help_dialog.srch.actionBtn,args,1);
4854 XtSetValues (hw->help_dialog.srch.closeBtn,args,1);
4855 XtSetValues (hw->help_dialog.srch.helpBtn,args,1);
4857 /** put focus on the text field **/
4858 XtSetArg (args[0], XmNinitialFocus, hw->help_dialog.srch.wordField);
4859 XtSetValues (parentForm,args,1);
4861 /* Add the proper help callback to the print dialog shell "F1" support */
4862 pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexShell_STR,
4863 (Widget) hw, &hw->help_dialog.help,
4864 &hw->help_dialog.help.pHelpListHead);
4865 XtAddCallback(parentForm, XmNhelpCallback,
4866 _DtHelpCB, (XtPointer) pHelpInfo);
4870 /*****************************************************************************
4871 * Function: updateDisplay()
4874 * Parameters: hw: the help widget
4878 * Purpose: forces an update on index search dialog widgets
4880 *****************************************************************************/
4881 static int updateDisplay(
4882 DtHelpDialogWidget hw)
4884 XmUpdateDisplay((Widget)hw->help_dialog.srch.actionBtn);/*DBG*/
4885 XmUpdateDisplay((Widget)hw->help_dialog.srch.curVolRadBtn);/*DBG*/
4886 XmUpdateDisplay((Widget)hw->help_dialog.srch.allVolRadBtn);/*DBG*/
4887 XmUpdateDisplay((Widget)hw->help_dialog.srch.selVolRadBtn);/*DBG*/
4888 XmUpdateDisplay((Widget)hw->help_dialog.srch.selectBtn);/*DBG*/
4889 XmUpdateDisplay((Widget)hw->help_dialog.srch.fullIndexRadBtn);/*DBG*/
4890 XmUpdateDisplay((Widget)hw->help_dialog.srch.containsRadBtn);/*DBG*/
4891 XmUpdateDisplay((Widget)hw->help_dialog.srch.wordField);/*DBG*/
4892 XmUpdateDisplay((Widget)hw->help_dialog.srch.statusLabel);/*DBG*/
4893 XmUpdateDisplay((Widget)hw->help_dialog.srch.resultList);/*DBG*/
4894 XmUpdateDisplay((Widget)hw->help_dialog.srch.closeBtn);/*DBG*/
4895 XmUpdateDisplay((Widget)hw->help_dialog.srch.helpBtn);/*DBG*/
4896 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));/*DBG*/
4902 /*****************************************************************************
4903 * Function: void _DtHelpGlobSrchDisplayDialog()
4906 * Parameters: parent Specifies the parent widget
4907 * searchWord word to put into searchWord field
4908 * remove this when integrated into DtHelp:
4909 * curVolume volume considered the current volume
4913 * Purpose: Setsup the proper data in the search dialog and
4914 * displays an instance of the search dialog.
4916 *****************************************************************************/
4917 void _DtHelpGlobSrchDisplayDialog(
4922 DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
4923 XmToggleButtonCallbackStruct status; /* the call data */
4924 Widget sourceBtn; /* widget owning event */
4927 XmString labelString = NULL;
4931 /* make the dialog itself */
4932 if (NULL == hw->help_dialog.srch.srchForm)
4934 CreateGlobSrchDialog((Widget) hw,searchWord);
4936 /* create the button label */
4937 CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
4938 XtSetArg (args[0], XmNlabelString, labelString);
4939 XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, 1);
4940 XmStringFree (labelString);
4942 /*** map widget and update display before doing any searching ***/
4943 /* Make sure the Search Dialog is managed */
4944 XtManageChild(hw->help_dialog.srch.srchForm);
4945 XtMapWidget(hw->help_dialog.srch.srchForm);
4947 /* set focus to contains word */
4948 XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
4950 /* force several updates to make sure it is fully displayed and
4951 that height/width are correctly inited */
4952 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
4953 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
4954 XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
4956 /*** now update settings, which may also invoke a search ***/
4957 /* set the cur vol btn sensitivity */
4958 UpdateCurVolBtnSens(hw,True);
4960 /* set default show index state */
4961 /* set full index if current vol has an index, contains word if not */
4962 if (hw->help_dialog.srch.curVolRadBtnSens) /* set in UpdateCurVolBtnSens*/
4963 sourceBtn = hw->help_dialog.srch.fullIndexRadBtn;
4965 sourceBtn = hw->help_dialog.srch.containsRadBtn;
4967 /* set the show index state */
4968 status.reason = XmCR_VALUE_CHANGED;
4970 status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
4971 UpdateIndexSelectionCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
4972 StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
4974 updateDisplay(hw); /* DBG */
4976 #if 0 /* 11/23/94 */
4977 /** Set min size for the dialog **/
4979 XtSetArg(args[n], XmNheight, &height); ++n;
4980 XtSetArg(args[n], XmNwidth, &width); ++n;
4981 XtGetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
4983 XtSetArg(args[n], XmNminHeight, height - 200); ++n; /* 200: arbitrary */
4984 XtSetArg(args[n], XmNminWidth, width); ++n;
4985 XtSetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
4988 else /* properly update dialog to support new word and cur vol */
4990 /* fixup current volume, if need be */
4991 _DtHelpGlobSrchUpdateCurVol((Widget)hw);
4993 /* fixup search word, if need be */
4994 if (NULL != searchWord)
4996 String srchWord = XtNewString(searchWord);
4997 /* srchWord is freed or used in CheckSearchWord() */
4998 if (CheckSearchWord(hw,srchWord,True) == True)
4999 { /* words are different */
5000 /* free all hit-related data and reset flags */
5001 HitListFreeAllVolHits(hw,True); /*True=free everything*/
5005 /* if its not managed, manage it */
5006 if ( XtIsManaged(hw->help_dialog.srch.srchForm) == False )
5008 /* manage and map the Search Dialog */
5009 XtManageChild(hw->help_dialog.srch.srchForm);
5010 XtMapWidget((Widget)hw->help_dialog.srch.srchForm);
5012 /* see if the selection dialog was already open */
5013 if ( hw->help_dialog.srch.selectionDlg
5014 && XtIsManaged(hw->help_dialog.srch.selectionDlg) )
5016 XtManageChild(hw->help_dialog.srch.selectionDlg);
5017 XtMapWidget(hw->help_dialog.srch.selectionDlg);
5020 else /* if it is managed, bring it forward */
5022 Widget parent = XtParent(hw->help_dialog.srch.srchForm);
5023 XRaiseWindow ( XtDisplay(parent), XtWindow(parent) );
5028 if (hw->help_dialog.srch.hitsFound == True)
5029 XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
5031 XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
5035 } /* end if create a new dialog */
5040 /*****************************************************************************
5041 * Function: void _DtHelpGlobSrchUpdateCurVol()
5043 * Parameters: new the help widget
5047 * Purpose: Adjusts the current volume of the dialog
5049 *****************************************************************************/
5050 void _DtHelpGlobSrchUpdateCurVol(
5054 DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
5057 if ( NULL == hw->help_dialog.srch.srchForm )
5059 if ( NULL == hw->help_dialog.srch.srchForm
5060 || XtIsManaged(hw->help_dialog.srch.srchForm) == False )
5062 return; /* RETURN */
5064 /* get full pathname for the volume */
5066 if (hw->help_dialog.display.helpVolume)
5067 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE,
5068 /* FIX: will helpVolume have matching path? */
5069 hw->help_dialog.display.helpVolume,
5070 _DtHelpFileSuffixList,False,R_OK);
5072 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
5073 && hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC
5075 && NULL != hw->help_dialog.srch.curVolPath
5076 && _DtHelpFileIsSameP(path,hw->help_dialog.srch.curVolPath,
5077 GetVolumeInfoCB, _DtHELP_FILE_NAME,
5078 hw->help_dialog.help.pDisplayArea) )
5080 /* leave current status as is */
5082 return; /* RETURN */
5086 /* a different current volume or change of topic */
5088 XmString labelString;
5091 /* if still searching previous cur volume, stop any search in progress */
5092 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
5093 && hw->help_dialog.srch.workProcId)
5095 /* cancel the search */
5096 StopSearchCB(NULL,(XtPointer) hw, NULL);
5098 /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
5099 SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
5101 /* zero search data */
5102 hw->help_dialog.srch.volLeftCnt = 0;
5103 hw->help_dialog.srch.curSrchVol = NULL;
5105 /* assumption is, that even though the search was incomplete,
5106 nothing bad will happen if we don't free the hit data,
5107 and the search could resume where left off, if necessary. */
5110 CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
5111 XtSetArg(args[0],XmNlabelString,labelString);
5112 XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
5113 XmStringFree(labelString);
5115 /* set the cur vol btn sensitivity */
5116 UpdateCurVolBtnSens(hw,False);
5118 /* set state of start button correctly */
5119 UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
5121 /* and search if needed */
5122 if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources )
5124 /* if to search a volume, start the search */
5125 if (hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC)
5126 StartSearchCB(NULL,(XtPointer) hw, NULL);
5127 else /* if current isn't a volume, clear the display & update status */
5129 DeleteListContents(&hw->help_dialog.srch);
5130 StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
5138 /*****************************************************************************
5139 * Function: void _DtHelpGlobSrchInitVars()
5141 * Parameters: srch search main data structure
5145 * Purpose: Init the contents of the control data structure
5147 *****************************************************************************/
5148 void _DtHelpGlobSrchInitVars(
5149 _DtHelpGlobSearchStuff * srch)
5151 /* set the font resource */
5152 if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
5153 srch->hitPrefixFont = XtNewString(srch->hitPrefixFont);
5155 /* File Selection Dialog font list */
5156 srch->volTitlesFontList = NULL;
5158 /* Set our search dialog widgets to NULL */
5159 srch->srchForm = NULL;
5160 srch->actionBtn = NULL;
5161 srch->curVolRadBtn = NULL;
5162 srch->allVolRadBtn = NULL;
5163 srch->selVolRadBtn = NULL;
5164 srch->selectBtn = NULL;
5165 srch->fullIndexRadBtn = NULL;
5166 srch->containsRadBtn = NULL;
5167 srch->wordField = NULL;
5168 srch->statusLabel = NULL;
5169 srch->resultList = NULL;
5170 srch->gotoBtn = NULL;
5171 srch->closeBtn = NULL;
5172 srch->helpBtn = NULL;
5173 srch->selectionDlg = NULL;
5175 /* init dialog content variables */
5176 srch->curVolPath = NULL;
5177 srch->rawWordStr = NULL;
5178 srch->normWordStr = NULL;
5179 srch->localeWordStr = NULL;
5180 srch->wordFieldFirstChar = 0;
5181 srch->wordFieldLen = 0;
5182 srch->statusLineUsage = 0; /* empty */
5184 /* init srch processing variables */
5185 srch->iconv3Codeset = NULL; /* iconv(3)-compatible code set of current locale */
5186 srch->iconv3Context = NULL;
5187 srch->srchSources = _DtHelpGlobSrchVolumeUndef; /* radio btn usage */
5188 srch->curSrchVol = NULL; /* volume currently in search */
5189 srch->hitsFontLoaded= False; /* is font loaded? */
5190 srch->volScanDone = False; /* is the volume list complete? */
5191 srch->fullIndex = False;
5192 srch->hitsFound = False; /* state of search */
5193 srch->readyToStart = False; /* state of search */
5194 srch->searchInProgress= False; /* state of search */
5195 srch->curVolRadBtnSens = False;
5196 srch->volLeftCnt = 0;
5197 srch->volListHead = NULL; /* info on search topics found */
5198 srch->workProcId = NULL;
5202 /*****************************************************************************
5203 * Function: void _DtHelpGlobSrchCleanAndClose()
5205 * Parameters: srch search main data structure
5206 * destroy flag to signal srch dialog should be destroyed
5210 * Purpose: Free the contents of the control data structure
5212 *****************************************************************************/
5213 void _DtHelpGlobSrchCleanAndClose(
5214 _DtHelpGlobSearchStuff * srch,
5217 /* close conversion context */
5218 _DtHelpCeIconvClose(&srch->iconv3Context);
5220 /* free the font list */
5221 if(srch->volTitlesFontList)
5223 XmFontListFree(srch->volTitlesFontList);
5224 srch->volTitlesFontList = NULL;
5228 * Make sure CloseSearchCB does not try using an invalid
5229 * widget id in its XtUnmanageChild and XtUnmapWidget calls.
5232 srch->srchForm = NULL;
5234 /* make dialog invisible; update sensitivities */
5235 CloseSearchCB(NULL,(XtPointer)srch, NULL);
5237 /* Destroy our index search dialog? */
5240 /* set the font resource */
5241 if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
5242 XtFree(srch->hitPrefixFont);
5245 * mark widgets as destroyed.
5246 * The XtDestroyWidget that called me will have called the destroy
5247 * callback of the widgets. So I don't have to do anything except
5248 * make sure I know they are destroyed.
5250 srch->selectionDlg = NULL;
5251 srch->srchForm = NULL;
5252 srch->resultList = NULL;
5254 /* free other data released to search dialog */
5257 /* free the locale word string, if allocated
5258 * (i.e. diff from normWordStr) */
5259 if(srch->localeWordStr!=srch->normWordStr)
5261 XtFree(srch->localeWordStr);
5262 srch->localeWordStr=NULL;
5264 XtFree(srch->normWordStr);
5265 srch->normWordStr=NULL;
5266 XtFree(srch->rawWordStr);
5267 srch->rawWordStr=NULL;
5268 XtFree(srch->curVolPath);
5269 srch->curVolPath=NULL;
5270 XtFree(srch->iconv3Codeset);
5271 srch->iconv3Codeset = NULL;