mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
5277 lines
184 KiB
C
5277 lines
184 KiB
C
/*
|
||
* CDE - Common Desktop Environment
|
||
*
|
||
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
||
*
|
||
* These libraries and programs are free software; you can
|
||
* redistribute them and/or modify them under the terms of the GNU
|
||
* Lesser General Public License as published by the Free Software
|
||
* Foundation; either version 2 of the License, or (at your option)
|
||
* any later version.
|
||
*
|
||
* These libraries and programs are distributed in the hope that
|
||
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
* PURPOSE. See the GNU Lesser General Public License for more
|
||
* details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with these libraries and programs; if not, write
|
||
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
||
* Floor, Boston, MA 02110-1301 USA
|
||
*/
|
||
/* $TOG: GlobSearch.c /main/21 1999/11/11 10:59:15 mgreess $ */
|
||
/************************************<+>*************************************
|
||
****************************************************************************
|
||
**
|
||
** File: GlobSearch.c
|
||
**
|
||
** Project: DtHelp Project
|
||
**
|
||
** Description: Builds and displays an instance of a DtHelp GlobSearch
|
||
** Dialog.
|
||
**
|
||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||
**
|
||
**
|
||
**
|
||
****************************************************************************
|
||
************************************<+>*************************************/
|
||
#include <sys/param.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#if defined(sun)
|
||
#include <sys/utsname.h>
|
||
#endif
|
||
#include <limits.h>
|
||
#include <stdlib.h> /* for MB_CUR_MAX */
|
||
#include <unistd.h> /* R_OK */
|
||
#include <locale.h> /* getlocale(), LOCALE_STATUS */
|
||
#ifndef NO_REGEX
|
||
# ifdef NO_REGCOMP
|
||
# if defined(SVR4)
|
||
# include <libgen.h> /* for regcmp, regex */
|
||
# endif
|
||
# else
|
||
# include <regex.h> /* for regcomp, regexec */
|
||
# endif
|
||
#endif
|
||
|
||
#include <Xm/Xm.h>
|
||
#include <Xm/XmP.h>
|
||
#include <Xm/Frame.h>
|
||
#include <Xm/TextF.h>
|
||
#include <Xm/Form.h>
|
||
#include <Xm/LabelG.h>
|
||
#include <Xm/ScrolledW.h>
|
||
#include <Xm/SeparatoG.h>
|
||
#include <Xm/PushBG.h>
|
||
#include <Xm/List.h>
|
||
#include <Xm/DialogS.h>
|
||
#include <Xm/MwmUtil.h>
|
||
#include <Xm/Protocols.h>
|
||
#include <Xm/RowColumn.h>
|
||
#include <Xm/SelectioB.h>
|
||
#include <Xm/ToggleBG.h>
|
||
|
||
#include <X11/Intrinsic.h>
|
||
#include <X11/Shell.h>
|
||
#include <X11/ShellP.h>
|
||
#include <X11/Xutil.h>
|
||
#include <X11/keysymdef.h>
|
||
|
||
#include <Dt/Help.h>
|
||
#include <Dt/HelpDialog.h>
|
||
|
||
/*
|
||
* private includes
|
||
*/
|
||
#include "bufioI.h"
|
||
#include "Access.h"
|
||
#include "AccessI.h"
|
||
#include "StringFuncsI.h"
|
||
#include "DisplayAreaI.h"
|
||
#include "HelpDialogP.h"
|
||
#include "HelpDialogI.h"
|
||
#include "HelpAccessI.h"
|
||
#include "HelpUtilI.h"
|
||
#include "HelposI.h"
|
||
#include "HourGlassI.h"
|
||
#include "GlobSearchI.h"
|
||
#include "FileListUtilsI.h"
|
||
#include "FileUtilsI.h"
|
||
#include "FormatI.h"
|
||
#include "HelpXlate.h"
|
||
#include "VolSelectI.h"
|
||
#include "Lock.h"
|
||
|
||
/******** TYPES ***********/
|
||
typedef enum {
|
||
SEARCH_RESULTS_STATUS = 1,
|
||
WORKING_STATUS = 2,
|
||
SCANNING_STATUS = 3,
|
||
BLANK_STATUS = 4,
|
||
NO_VOL_STATUS = 5,
|
||
FIRST_PROMPT_STATUS = 6
|
||
} ResultsStatus;
|
||
|
||
static Boolean VolumeHasIndexP (
|
||
_DtHelpGlobSrchSources srchSource,
|
||
int helpType,
|
||
char * baseName);
|
||
static void DeleteListContents(
|
||
_DtHelpGlobSearchStuff * srch);
|
||
static void StatusLabelUpdate(
|
||
DtHelpDialogWidget hw,
|
||
ResultsStatus status,
|
||
Boolean forceUpdate,
|
||
int intArg);
|
||
static void ResultsListUpdate(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry newFile);
|
||
static void StopSearchCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData);
|
||
static void VolNameDisplay(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file,
|
||
Boolean insertVol);
|
||
static int VolHitsDisplay (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file);
|
||
static void UpdateSearchVolumesCB(
|
||
Widget widget,
|
||
XtPointer clientData,
|
||
XtPointer callData);
|
||
static void UpdateSearchStartStatusCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData);
|
||
|
||
/********** CONSTANTS *************/
|
||
#define DIR_SLASH '/'
|
||
#define EOS '\0'
|
||
|
||
/* message catalog set number for GlobSearch.c */
|
||
#define GSSET 5
|
||
|
||
#define DONT_SET (-1) /* used as third value of a Boolean */
|
||
|
||
#define HIT_FONT_RES_NAME "*helpSearchMonoFont"
|
||
#define HIT_FONT_RES_CLASS "*HelpSearchMonoFont"
|
||
#define PREFIX_FONT_SPEC "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
|
||
#define PREFIX_FONT_SPEC1 "-dt-application-bold-r-normal-*-*-140-*-*-m-*-iso8859-1"
|
||
#define PREFIX_FONT_SPEC2 "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
|
||
#define PREFIX_FONT_SPEC3 "courb14" /* non CDE platforms */
|
||
#define PREFIX_FONT_TAG "prefixFontTag"
|
||
|
||
#define START_SEARCH_CAT s_GlobSrchDlgBtnCatNum[0]
|
||
#define START_SEARCH_STR s_GlobSrchDlgBtnStrs[0]
|
||
#define START_SEARCH_MNEM "S"
|
||
#define CONT_SEARCH_CAT s_GlobSrchDlgBtnCatNum[1]
|
||
#define CONT_SEARCH_STR s_GlobSrchDlgBtnStrs[1]
|
||
#define CONT_SEARCH_MNEM "S"
|
||
#define STOP_SEARCH_CAT s_GlobSrchDlgBtnCatNum[2]
|
||
#define STOP_SEARCH_STR s_GlobSrchDlgBtnStrs[2]
|
||
#define STOP_SEARCH_MNEM "S"
|
||
#define CLOSE_BTN_CAT s_GlobSrchDlgBtnCatNum[3]
|
||
#define CLOSE_BTN_STR s_GlobSrchDlgBtnStrs[3]
|
||
#define CLOSE_BTN_MNEM "C"
|
||
#define HELP_BTN_CAT s_GlobSrchDlgBtnCatNum[4]
|
||
#define HELP_BTN_STR s_GlobSrchDlgBtnStrs[4]
|
||
#define HELP_BTN_MNEM "H"
|
||
|
||
|
||
/********** MACROS ************/
|
||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||
|
||
/********** Global VARIABLES ************/
|
||
char _DtHelpDefaultSrchHitPrefixFont[] = PREFIX_FONT_SPEC;
|
||
|
||
/********** VARIABLES ************/
|
||
static const char *DirSlash = "/";
|
||
static char * s_GlobSrchDlgBtnStrs[] = {
|
||
"Start Search",
|
||
"Continue Search",
|
||
"Stop Search",
|
||
"Close",
|
||
"Help",
|
||
NULL };
|
||
/* catalog index numbers for the strings */
|
||
static unsigned char s_GlobSrchDlgBtnCatNum[] = {
|
||
12, 13, 14, 15, 16 };
|
||
|
||
static char * s_PrefixFontListTag = NULL;
|
||
|
||
/* Setup for the Retrun Translation set for the text field */
|
||
static char defaultBtnTranslations[] = "<Key>Return: Activate()";
|
||
/* static char defaultListTranslations[] = "<Key>Return: Activate()"; */
|
||
/* static char defaultMgrTranslations[] = "<Key>Return: ManagerParentActivate()"; */
|
||
|
||
#if DOC
|
||
/************************************************************************
|
||
The startPosition and nextVolPosition values of the DtHelpGlobSrchVol
|
||
structure are used as follows:
|
||
|
||
startPosition: the position of the volume in the results list
|
||
if hitCnt == 0, startPosition is the same value as the
|
||
most recent volume with hits
|
||
nextVolPosition: the position of the next volume in the results list
|
||
if hitCnt == 0, nextVolPosition is the same value as the
|
||
most recent volume with hits
|
||
The value must be adjusted to include the positions
|
||
occupied by hits and topics that are listed for the volume
|
||
|
||
These variables are maintained using the AdjustPositionValues()
|
||
routine, which increment/decrement the position values of all
|
||
files after the start. So, when doing a search and display,
|
||
as results are added to the list, the position values of volumes
|
||
later in the list are always up to date.
|
||
************************************************************************/
|
||
#endif
|
||
|
||
/*======================================================================*/
|
||
/*======================================================================*/
|
||
/*======================================================================*/
|
||
/*======================================================================*/
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void MergeFontListIntoWidgetFonts()
|
||
*
|
||
* Parameters: widget a widget with a XmNfontList resource
|
||
* newFontsList font list with fonts to merge into widget
|
||
*
|
||
* Return Value: void
|
||
*
|
||
* Purpose: Merges the fonts from the newFontsList into the fontlist
|
||
* of the widget
|
||
*
|
||
*****************************************************************************/
|
||
static void MergeFontListIntoWidgetFonts(
|
||
Widget widget,
|
||
XmFontList newFontsList)
|
||
{
|
||
XmFontList fontList = NULL;
|
||
XmFontContext context;
|
||
XmFontListEntry entry;
|
||
Arg args[2];
|
||
|
||
/* get current resultList fontlist */
|
||
XtSetArg(args[0], XmNfontList, &fontList);
|
||
XtGetValues(widget,args,1);
|
||
|
||
if (NULL == fontList) return; /* RETURN on error */
|
||
|
||
/* work with copy, because FontListAppendEntry() destroys input FL */
|
||
fontList = XmFontListCopy(fontList);
|
||
|
||
/* walk through the volTitlesFontList entries and add them in */
|
||
XmFontListInitFontContext(&context,newFontsList);
|
||
for ( entry = XmFontListNextEntry(context);
|
||
NULL != entry;
|
||
entry = XmFontListNextEntry(context) )
|
||
{
|
||
fontList = XmFontListAppendEntry(fontList,entry);
|
||
}
|
||
if (context) XmFontListFreeFontContext(context);
|
||
|
||
/* install the changed list */
|
||
XtSetArg(args[0], XmNfontList, fontList);
|
||
XtSetValues(widget,args,1);
|
||
|
||
if (fontList) XmFontListFree(fontList);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void UpdateCurVolBtnSens()
|
||
*
|
||
* Parameters: new the help widget
|
||
*
|
||
* Return Value: True if cur vol has an index
|
||
* False if not
|
||
*
|
||
* Purpose: Checks on current volume for an index
|
||
and sets buttons appropriately
|
||
*
|
||
*****************************************************************************/
|
||
static Boolean UpdateCurVolBtnSens(
|
||
DtHelpDialogWidget hw,
|
||
Boolean selectVolBtn)
|
||
{
|
||
XmToggleButtonCallbackStruct status; /* the call data */
|
||
Boolean curState;
|
||
Widget sourceBtn;
|
||
|
||
/* set the cur vol btn sensitivity */
|
||
/* set the volumes/show selection btns by generating a false event */
|
||
status.reason = XmCR_VALUE_CHANGED;
|
||
status.set = True;
|
||
status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
|
||
|
||
#if 0
|
||
if ( VolumeHasIndexP (
|
||
hw->help_dialog.srch.srchSources,
|
||
hw->help_dialog.display.helpType,
|
||
hw->help_dialog.display.helpVolume) )
|
||
{
|
||
curState = True;
|
||
sourceBtn = hw->help_dialog.srch.curVolRadBtn;
|
||
}
|
||
else
|
||
{
|
||
curState = False;
|
||
sourceBtn = hw->help_dialog.srch.allVolRadBtn;
|
||
}
|
||
/* ??? XtSetSensitive(hw->help_dialog.srch.curVolRadBtn,curState); */
|
||
hw->help_dialog.srch.curVolRadBtnSens = curState;
|
||
if (selectVolBtn) UpdateSearchVolumesCB(sourceBtn,hw,&status);
|
||
#else
|
||
|
||
curState = True;
|
||
sourceBtn = hw->help_dialog.srch.curVolRadBtn;
|
||
|
||
hw->help_dialog.srch.curVolRadBtnSens = curState;
|
||
if (selectVolBtn)
|
||
UpdateSearchVolumesCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
|
||
#endif
|
||
|
||
|
||
return curState;
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: LoadPrefixFont()
|
||
*
|
||
* Loads the prefix font, if that hasn't yet occurred
|
||
*
|
||
************************************************************************/
|
||
static void LoadPrefixFont(
|
||
DtHelpDialogWidget hw)
|
||
{
|
||
XmFontListEntry entry;
|
||
XmFontList curFontList = NULL;
|
||
XmFontList newFontList = NULL;
|
||
char * fontSpec = NULL;
|
||
Arg args[3];
|
||
|
||
if (hw->help_dialog.srch.hitsFontLoaded) return; /* RETURN */
|
||
|
||
/* this code is for when the resource is part of the widget */
|
||
fontSpec = hw->help_dialog.srch.hitPrefixFont;
|
||
|
||
/* get current font list */
|
||
XtSetArg(args[0], XmNfontList, &curFontList);
|
||
XtGetValues(hw->help_dialog.srch.resultList,args,1);
|
||
|
||
/* work with copy, because FontListAppendEntry() destroys input FL */
|
||
newFontList = XmFontListCopy(curFontList);
|
||
|
||
/* load and merge fonts */
|
||
s_PrefixFontListTag = PREFIX_FONT_TAG;
|
||
entry = XmFontListEntryLoad(XtDisplay(hw->help_dialog.srch.srchForm),
|
||
fontSpec,XmFONT_IS_FONT, s_PrefixFontListTag);
|
||
newFontList = XmFontListAppendEntry(newFontList,entry);
|
||
XmFontListEntryFree(&entry);
|
||
|
||
/* install font */
|
||
if (NULL == newFontList)
|
||
{ /* error case */
|
||
s_PrefixFontListTag = XmFONTLIST_DEFAULT_TAG;
|
||
}
|
||
else
|
||
{
|
||
/* set new font list */
|
||
XtSetArg(args[0], XmNfontList, newFontList);
|
||
XtSetValues(hw->help_dialog.srch.resultList,args,1);
|
||
if (newFontList) XmFontListFree(newFontList);
|
||
}
|
||
hw->help_dialog.srch.hitsFontLoaded = True;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: VolumeHasIndexP()
|
||
*
|
||
* Looks for the specified volume in the file system and
|
||
* tests whether the volume has an index associated with it.
|
||
*
|
||
************************************************************************/
|
||
static Boolean VolumeHasIndexP (
|
||
_DtHelpGlobSrchSources srchSource,
|
||
int helpType,
|
||
char * baseName)
|
||
{
|
||
char * path = NULL;
|
||
_DtHelpVolumeHdl vol;
|
||
int keyWordCount = 0;
|
||
char **currentKeyList = NULL;
|
||
|
||
/* if help content isn't a volume, it has no index */
|
||
if ( _DtHelpGlobSrchCurVolume == srchSource
|
||
&& helpType != DtHELP_TYPE_TOPIC )
|
||
return False; /* RETURN */
|
||
|
||
/* try to locate file and its entry, if present */
|
||
path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, baseName,
|
||
_DtHelpFileSuffixList,False,R_OK);
|
||
if (_DtHelpOpenVolume(path, &vol) == 0 )
|
||
{
|
||
/* Get the keyword list values */
|
||
keyWordCount = _DtHelpCeGetKeywordList(vol,&(currentKeyList));
|
||
|
||
/* no need to free currentKeyList because these are mgd by CE */
|
||
_DtHelpCloseVolume(vol);
|
||
}
|
||
|
||
XtFree(path);
|
||
return (keyWordCount > 0);
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: GetVolumeInfoCB()
|
||
*
|
||
* Get the info on the volume and return it
|
||
* Any of the 'out' parameters may be NULL.
|
||
*
|
||
************************************************************************/
|
||
static Boolean GetVolumeInfoCB (
|
||
XtPointer pDisplayArea, /* in: display area in use */
|
||
char * volumePath, /* in: full path to file */
|
||
char ** ret_title, /* out: mallocd doc title text string */
|
||
XmString * ret_titleXmStr,/* out: mallocd doc title string */
|
||
char ** ret_docId, /* out: mallocd doc Id string */
|
||
char ** ret_timeStamp, /* out: mallocd doc time string */
|
||
int * ret_nameKey, /* out: hash value for fast discimination */
|
||
XmFontList * io_fontList, /* io: fontList for title */
|
||
Boolean * ret_mod) /* out: has font list been changed */
|
||
{
|
||
char empty = EOS;
|
||
_DtHelpVolumeHdl vol;
|
||
char * baseName = volumePath; /* no path component */
|
||
|
||
/* calc baseName */
|
||
if(_DtHelpCeStrrchr(volumePath, DirSlash, MB_CUR_MAX, &baseName)==0)
|
||
baseName++;
|
||
|
||
/* open volume */
|
||
if ( _DtHelpOpenVolume(volumePath, &vol) != 0 )
|
||
{ /* if can't open, do best possible */
|
||
if (ret_titleXmStr)
|
||
*ret_titleXmStr = XmStringCreateLocalized(baseName);
|
||
if (ret_title) *ret_title= XtNewString(baseName);
|
||
if (ret_nameKey) *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
|
||
return False;
|
||
}
|
||
|
||
/** volume is open, now get the data **/
|
||
|
||
if (ret_title)
|
||
{
|
||
char * locTitle = NULL;
|
||
|
||
/* locTitle is owned by caller */
|
||
_DtHelpGetAsciiVolumeTitle(pDisplayArea, vol, &locTitle);
|
||
if (locTitle == NULL)
|
||
locTitle = XtNewString(baseName);
|
||
*ret_title = locTitle;
|
||
}
|
||
|
||
if (ret_titleXmStr)
|
||
{
|
||
XmString locTitleXmStr = NULL;
|
||
|
||
/* locTitle is owned by caller */
|
||
_DtHelpFormatVolumeTitle(pDisplayArea,vol,
|
||
&locTitleXmStr,io_fontList,ret_mod);
|
||
if (locTitleXmStr == NULL)
|
||
locTitleXmStr = XmStringCreateLocalized(baseName);
|
||
*ret_titleXmStr = locTitleXmStr;
|
||
}
|
||
|
||
if (ret_docId || ret_timeStamp)
|
||
{
|
||
char * locDocId = NULL;
|
||
char * locTimeStamp = NULL;
|
||
|
||
/* locDocId & locTimeStamp will point to private memory; do not modify */
|
||
_DtHelpCeGetDocStamp(vol,&locDocId, &locTimeStamp);
|
||
|
||
if (ret_docId)
|
||
*ret_docId = locDocId ? locDocId : XtNewString(&empty);
|
||
if (ret_timeStamp)
|
||
*ret_timeStamp = locTimeStamp?locTimeStamp:XtNewString(&empty);
|
||
}
|
||
|
||
if (ret_nameKey)
|
||
{
|
||
*ret_nameKey = _DtHelpCeStrHashToKey(baseName);
|
||
}
|
||
|
||
_DtHelpCloseVolume(vol);
|
||
|
||
return True;
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: AdjustPositionValues()
|
||
|
||
* Adjust the position values of all volumes in the list by the amount given
|
||
*
|
||
************************************************************************/
|
||
static void AdjustPositionValues(
|
||
_DtHelpFileList fileList,
|
||
int adjStartAmount,
|
||
int adjNextAmount,
|
||
int adjustThisFile)
|
||
{
|
||
_DtHelpGlobSrchVol * curVol;
|
||
|
||
if ( NULL == fileList
|
||
|| NULL == (curVol = (_DtHelpGlobSrchVol *) fileList->clientData) )
|
||
return; /* RETURN */
|
||
|
||
/* do we need to find first next file that has hits and is in list? */
|
||
if(False == adjustThisFile)
|
||
{
|
||
curVol->nextVolPosition += adjNextAmount;
|
||
for ( fileList = _DtHelpFileListGetNext(NULL,fileList); /* begin with next */
|
||
NULL != fileList;
|
||
fileList = _DtHelpFileListGetNext(NULL,fileList) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol=(_DtHelpGlobSrchVol *)fileList->clientData;
|
||
if (vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
|
||
break; /* BREAK */
|
||
vol->nextVolPosition += adjNextAmount;
|
||
}
|
||
/* all further files require same adj amts */
|
||
adjStartAmount = adjNextAmount;
|
||
}
|
||
|
||
|
||
/* add in the adjust amount to all files */
|
||
for ( /* do nothing */;
|
||
NULL != fileList;
|
||
fileList = _DtHelpFileListGetNext(NULL,fileList) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) fileList->clientData;
|
||
if (vol)
|
||
{
|
||
vol->startPosition += adjStartAmount;
|
||
vol->nextVolPosition += adjNextAmount;
|
||
}
|
||
/* overwrite, once we've done the first file, if haven't already */
|
||
adjStartAmount = adjNextAmount;
|
||
}
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitLoadTopics()
|
||
*
|
||
* Loads the topics referred to by a hit
|
||
* Returns: 0 if loaded ok, -1 otherwise
|
||
************************************************************************/
|
||
static int HitLoadTopics (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file,
|
||
_DtHelpGlobSrchHit * hit)
|
||
{
|
||
_DtHelpVolumeHdl volHandle;
|
||
char * * origTopicIdList = NULL;
|
||
int topicCnt;
|
||
int i;
|
||
XmString * titlesList = NULL;
|
||
char * * idList = NULL;
|
||
char * * fileList = NULL;
|
||
XmFontList fontList = NULL;
|
||
Boolean mod = False;
|
||
Boolean allMods = False;
|
||
Arg args[5];
|
||
|
||
if (hit->topicsLoaded) return 0; /* RETURN: ok */
|
||
|
||
if (_DtHelpOpenVolume(file->fullFilePath, &volHandle) != 0 )
|
||
return -1; /* RETURN: error */
|
||
|
||
topicCnt = _DtHelpCeFindKeyword(volHandle,hit->indexEntry,&origTopicIdList);
|
||
if (topicCnt <= 0) return -1; /* RETURN: error */
|
||
|
||
/* get results font list */
|
||
XtSetArg(args[0], XmNfontList, &fontList);
|
||
XtGetValues(hw->help_dialog.srch.resultList,args,1);
|
||
|
||
#if defined(DONT_USE_CDExc22774)
|
||
/* Don't need to copy, _DtHelpFormatVolumeTitle copies
|
||
* before modifying.
|
||
*/
|
||
|
||
/* FIX: check whether this is a memory leak. It isn't if the
|
||
GetValues of XmFontList returns its own list, not a copy */
|
||
/* work with copy, because FontListAppendEntry() destroys input FL */
|
||
fontList = XmFontListCopy(fontList);
|
||
#endif
|
||
|
||
/* get the titles of all topics */
|
||
for (i=0; i<topicCnt; i++)
|
||
{
|
||
XmString titleStr = NULL;
|
||
Boolean valid = False;
|
||
XmFontList lastFontList = NULL;
|
||
|
||
/*
|
||
* mod==True indicates _DtHelpFormatTopicTitle copied fontList
|
||
* once already. Save a pointer to it so we can free the font list
|
||
* if _DtHelpFormatTopicTitle copies it again.
|
||
*/
|
||
lastFontList = fontList;
|
||
|
||
valid = _DtHelpFormatTopicTitle(hw->help_dialog.help.pDisplayArea,
|
||
volHandle,origTopicIdList[i], &titleStr, &fontList, &mod);
|
||
|
||
if (mod && NULL != lastFontList) XmFontListFree(lastFontList);
|
||
lastFontList = NULL;
|
||
allMods |= mod; /* track for all iterations */
|
||
|
||
if(valid!=0 || NULL==titleStr)
|
||
{
|
||
titleStr=XmStringCreateLocalized(origTopicIdList[i]);
|
||
} /* if couldn't get title */
|
||
|
||
/* note that titleStr is an XmString, not an (Xt) String */
|
||
titlesList = (XmString *)_DtHelpCeAddPtrToArray (
|
||
(void **)titlesList, (void *) titleStr);
|
||
idList = (char **)_DtHelpCeAddPtrToArray (
|
||
(void **)idList,
|
||
(void *) XtNewString(origTopicIdList[i]));
|
||
fileList = (char **)_DtHelpCeAddPtrToArray (
|
||
(void **)fileList,
|
||
(void *) XtNewString(file->fullFilePath));
|
||
} /* for all topics of this index entry */
|
||
|
||
/* install font list, if changed */
|
||
if (allMods)
|
||
{
|
||
XtSetArg(args[0], XmNfontList, fontList);
|
||
XtSetValues(hw->help_dialog.srch.resultList,args,1);
|
||
if (fontList) XmFontListFree(fontList);
|
||
}
|
||
|
||
/* put results into hit */
|
||
hit->topicTitles = titlesList;
|
||
hit->topicIdList = idList;
|
||
hit->topicFileList = fileList;
|
||
hit->topicCnt = topicCnt;
|
||
hit->topicsLoaded = True;
|
||
|
||
_DtHelpCloseVolume(volHandle);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitNameDisplay()
|
||
*
|
||
* Updates the name of the hit, not delete or insert
|
||
************************************************************************/
|
||
static int HitNameDisplay (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file,
|
||
_DtHelpGlobSrchHit * hit,
|
||
int hitPos,
|
||
Boolean insertHit)
|
||
{
|
||
char * expandPrefix;
|
||
char * contractPrefix;
|
||
char * gotoPrefix;
|
||
XmString prefixString;
|
||
XmString labelString;
|
||
char * tmpStr;
|
||
char buf[30];
|
||
|
||
/* FIX: this method of getting/using the prefixes
|
||
is a performance nightmare; plus subject to font variability */
|
||
expandPrefix = (char *)_DTGETMESSAGE (GSSET, 28," +");
|
||
contractPrefix = (char *)_DTGETMESSAGE (GSSET, 29," -");
|
||
gotoPrefix = (char *)_DTGETMESSAGE (GSSET, 30," ");
|
||
|
||
/* if more than one topic for this index, signal it */
|
||
tmpStr = gotoPrefix; /* index entry has one topic */
|
||
if ( hit->topicCnt > 1 )
|
||
{
|
||
if (hit->topicsDisplayed) /* topics currently displayed */
|
||
tmpStr = contractPrefix;
|
||
else /* topics not displayed */
|
||
tmpStr = expandPrefix;
|
||
sprintf(buf, "%s%3d ", tmpStr, hit->topicCnt); /* 4d too spacy */
|
||
tmpStr = buf;
|
||
}
|
||
LoadPrefixFont(hw);
|
||
prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
|
||
XmCHARSET_TEXT, NULL);
|
||
labelString = XmStringConcat(prefixString,hit->indexTitle);
|
||
/* recall indexTitle is an XmString in the volume's indexXmStrsList */
|
||
|
||
/* install/insert the item */
|
||
if (insertHit)
|
||
XmListAddItemUnselected(hw->help_dialog.srch.resultList,
|
||
labelString,hitPos);
|
||
else
|
||
XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
|
||
&labelString,1,hitPos);
|
||
|
||
XmStringFree(prefixString);
|
||
XmStringFree(labelString);
|
||
return (insertHit ? 1 : 0);
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitTopicsDisplay()
|
||
*
|
||
* Loads the topics referred to by a hit and displays them
|
||
* Returns the number of topics displayed
|
||
************************************************************************/
|
||
static int HitTopicsDisplay (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file,
|
||
_DtHelpGlobSrchHit * hit,
|
||
int firstTopicListPosition)
|
||
{
|
||
XmString * pTopicString;
|
||
XmString prefixString;
|
||
XmString *items;
|
||
char * tmpStr;
|
||
int i;
|
||
|
||
if ( False == hit->topicsLoaded && HitLoadTopics(hw,file,hit) < 0 )
|
||
return 0; /* RETURN: error */
|
||
if ( hit->topicsDisplayed ) return 0; /* RETURN: ok */
|
||
|
||
LoadPrefixFont(hw);
|
||
/*tmpStr = (char *)_DTGETMESSAGE (GSSET, 32," * ");*/
|
||
tmpStr = (char *)_DTGETMESSAGE (GSSET, 31," ");
|
||
prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
|
||
XmCHARSET_TEXT, NULL);
|
||
|
||
if (hit->topicCnt > 0)
|
||
{
|
||
items = (XmString *) XtMalloc (sizeof (XmString) * hit->topicCnt);
|
||
|
||
/* put XmString-formatted topic titles into list */
|
||
for (i = 0, pTopicString = hit->topicTitles; NULL != *pTopicString;
|
||
pTopicString++, i++ )
|
||
items[i] = XmStringConcat(prefixString,*pTopicString);
|
||
|
||
XmListAddItemsUnselected(hw->help_dialog.srch.resultList, items,
|
||
hit->topicCnt, firstTopicListPosition);
|
||
for (i = 0; i < hit->topicCnt; i++)
|
||
XmStringFree(items[i]);
|
||
XtFree((char *) items);
|
||
}
|
||
|
||
XmStringFree(prefixString);
|
||
|
||
/* set state */
|
||
hit->topicsDisplayed = True;
|
||
hit->showTopicsWithHit = True;
|
||
return hit->topicCnt;
|
||
}
|
||
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitTopicsUndisplay()
|
||
*
|
||
* Releases the topics referred to by a hit and undisplays them
|
||
* Returns number of topics removed from display and hit.
|
||
************************************************************************/
|
||
static int HitTopicsUndisplay (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file,
|
||
_DtHelpGlobSrchHit * hit,
|
||
int firstTopicListPosition)
|
||
{
|
||
int topPos;
|
||
Arg args[5];
|
||
|
||
if ( False == hit->topicsDisplayed ) return 0; /* RETURN */
|
||
|
||
XtSetArg(args[0], XmNtopItemPosition, &topPos);
|
||
XtGetValues(hw->help_dialog.srch.resultList,args,1);
|
||
|
||
/* count the topics -- they are also being collapsed */
|
||
if (hit->topicCnt > 0)
|
||
XmListDeleteItemsPos(hw->help_dialog.srch.resultList,
|
||
hit->topicCnt, firstTopicListPosition);
|
||
|
||
hit->topicsDisplayed = False;
|
||
/* NOTE: don't reset hit->showTopicsWithHit here; require that
|
||
to be explicitly reset in ProcessResultSelection() */
|
||
|
||
XmListSetPos(hw->help_dialog.srch.resultList, topPos);
|
||
|
||
return hit->topicCnt;
|
||
}
|
||
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitFree()
|
||
*
|
||
* Frees the memory associated with a hit and returns the next hit
|
||
* member of the structure
|
||
************************************************************************/
|
||
static _DtHelpGlobSrchHit * HitFree (
|
||
_DtHelpGlobSrchHit * hit,
|
||
Boolean freeHitItself)
|
||
{
|
||
XmString * nextStr;
|
||
_DtHelpGlobSrchHit * nextHit;
|
||
|
||
if (NULL == hit) return NULL;
|
||
|
||
nextHit = hit->next;
|
||
|
||
/* Free the mem of the topics id list */
|
||
_DtHelpCeFreeStringArray(hit->topicIdList);
|
||
hit->topicIdList = NULL; /* mem not owned by me */
|
||
|
||
/* Free the mem of the topics files list */
|
||
_DtHelpCeFreeStringArray(hit->topicFileList);
|
||
hit->topicFileList = NULL;
|
||
|
||
/* topicTitles are XmStrings and we can't use FreeStringArray() */
|
||
for ( nextStr = hit->topicTitles;
|
||
NULL != nextStr && NULL != *nextStr;
|
||
nextStr++)
|
||
XmStringFree (*nextStr);
|
||
XtFree((char *) hit->topicTitles); /* its an XmString * */
|
||
hit->topicTitles = NULL;
|
||
|
||
/* set flags */
|
||
hit->topicsLoaded = False;
|
||
hit->topicsDisplayed = False;
|
||
|
||
if (freeHitItself)
|
||
{
|
||
/* Free the index entry */
|
||
XtFree(hit->indexEntry);
|
||
XtFree((String)hit);
|
||
}
|
||
|
||
return nextHit;
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitListFree()
|
||
*
|
||
* Walks along a hit list and frees its contents
|
||
************************************************************************/
|
||
static void HitListFree(
|
||
_DtHelpGlobSrchVol * vol,
|
||
Boolean freeHitsThemselves)
|
||
{
|
||
_DtHelpGlobSrchHit * hit;
|
||
|
||
if (NULL == vol) return; /* RETURN */
|
||
|
||
for ( hit = vol->hitListHead;
|
||
NULL != hit;
|
||
hit = HitFree(hit,freeHitsThemselves) )
|
||
{ /* nothing */ }
|
||
|
||
/* reset search flags */
|
||
vol->nothingDone = True;
|
||
vol->topicSearchDone = False;
|
||
vol->indexSearchDone = False;
|
||
vol->searchCompleted = False;
|
||
vol->searchedCnt = 0;
|
||
vol->gatheredFullIndex = False;
|
||
|
||
/* reset hit flags */
|
||
vol->hitsDisplayed = False;
|
||
vol->showHitsWithVol = False;
|
||
vol->zeroHitsOk = False;
|
||
vol->hitCnt = 0;
|
||
|
||
/* reset list display flags */
|
||
vol->startPosition = 1;
|
||
vol->nextVolPosition = 1;
|
||
|
||
/* don't free indexXmStrsList here because they
|
||
are reused for every search on this volume */
|
||
vol->curIndexXmStr = vol->indexXmStrsList;
|
||
|
||
/* indexEntriesList,volhandle inited elsewhere */
|
||
|
||
if (freeHitsThemselves)
|
||
{
|
||
vol->hitListHead = NULL;
|
||
vol->hitListTail = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitListFreeAllVolHits()
|
||
*
|
||
* Walks along all the volumes and frees their hits
|
||
************************************************************************/
|
||
static void
|
||
HitListFreeAllVolHits (
|
||
DtHelpDialogWidget hw,
|
||
Boolean freeFullIndex)
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
_DtHelpFileEntry curFile;
|
||
|
||
/* walk the files, freeing all hits and their data */
|
||
for ( curFile = hw->help_dialog.srch.volListHead;
|
||
NULL != curFile;
|
||
curFile = _DtHelpFileListGetNext(NULL,curFile) )
|
||
{
|
||
vol = (_DtHelpGlobSrchVol *) curFile->clientData;
|
||
|
||
if (NULL == vol) continue; /* CONTINUE */
|
||
if (vol->gatheredFullIndex && freeFullIndex == False) continue;
|
||
HitListFree(vol,True); /* True: free hits themselves */
|
||
}
|
||
hw->help_dialog.srch.hitsFound = False;
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitListGetNth()
|
||
*
|
||
* Retrieves the Nth entry from the hits contained in the VolList
|
||
*
|
||
* This code follows the same counting paradigm used when adding
|
||
* the items to the srchResultList widget, so that we can just use the
|
||
* position value returned by it to retrieve the selected item.
|
||
*
|
||
* This paradigm also counts the presence of a volume as an item
|
||
* if it contains any hits, and doesn't count it if it contains
|
||
* no hits. It also counts the topicTitles that are associated
|
||
* with a hit and displayed indented beneath it.
|
||
*
|
||
* The position count is 1 based, which corresponds with the
|
||
* XmList approach.
|
||
*
|
||
* Return params:
|
||
* ret_hit: retuns NULL if an error or a pointer to the hit structure.
|
||
* ret_locationId: returns NULL is position is for the hit
|
||
* structure itself, returns a pointer to private
|
||
* memory containing the location id if position
|
||
* is a topic belonging to the hit.
|
||
*
|
||
* Returns: 0 if ok, -1 if error
|
||
************************************************************************/
|
||
static int HitListGetNth (
|
||
_DtHelpFileList volListHead,
|
||
int position,
|
||
_DtHelpFileEntry * ret_file,
|
||
_DtHelpGlobSrchHit * * ret_hit,
|
||
char * * ret_locationId,
|
||
char * * ret_helpFile)
|
||
{
|
||
_DtHelpGlobSrchHit * hit = NULL;
|
||
_DtHelpGlobSrchVol * curVol;
|
||
_DtHelpFileEntry curFile = NULL;
|
||
_DtHelpFileEntry posFile = NULL;
|
||
char * * locationIdList = NULL;
|
||
char * * fileNameList = NULL;
|
||
int curPos;
|
||
|
||
if (NULL == volListHead) goto done; /* GOTO on error */
|
||
|
||
/* walk along the volumes to find the one containing the position
|
||
Because we need the most recent file with hits before the
|
||
nextFile that has too high a position, only set posFile when
|
||
we aren't ready to stop yet and we're on a file with hits. */
|
||
for ( curFile = volListHead;
|
||
NULL != curFile;
|
||
curFile = _DtHelpFileListGetNext(curFile,curFile) )
|
||
{
|
||
/* it is impt to use > test so that multiple volumes with the same
|
||
start position are properly handled. This occurs when they
|
||
have no hits in them. */
|
||
curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
|
||
if (NULL == curVol) continue;
|
||
#if 0
|
||
if (curVol->startPosition > position) break; /* BREAK */
|
||
if (curVol->hitCnt > 0) posFile = curFile; /* recent with hits */
|
||
#else
|
||
if (curVol->showVolInList && curVol->nextVolPosition > position)
|
||
{
|
||
posFile = curFile;
|
||
break; /* BREAK */
|
||
}
|
||
#endif
|
||
}
|
||
if(NULL == posFile) goto done; /* GOTO on error */
|
||
|
||
/*** walk along the hits to find the one matching the position ***/
|
||
curVol = (_DtHelpGlobSrchVol *) posFile->clientData;
|
||
curPos = curVol->startPosition;
|
||
hit = NULL;
|
||
locationIdList = NULL;
|
||
fileNameList = NULL;
|
||
|
||
/* (position == curPos) ==> volume name itself was selected */
|
||
if ( curPos < position )
|
||
{ /* a hit inside the volume */
|
||
if ( curVol->hitsDisplayed )
|
||
{
|
||
for ( curPos++, hit = curVol->hitListHead;
|
||
curPos < position && NULL != hit;
|
||
curPos++, hit = hit->next )
|
||
{
|
||
if (False == hit->topicsDisplayed) continue; /* CONTINUE */
|
||
|
||
/* walk all displayed topics to see if the position is here */
|
||
for ( locationIdList=hit->topicIdList,fileNameList=hit->topicFileList;
|
||
NULL != locationIdList[0];
|
||
locationIdList++, fileNameList++ )
|
||
{
|
||
/* use GOTO to escape with all pointers correct and
|
||
without introducing an additional flag variable */
|
||
if (++curPos == position) goto done; /* GOTO */
|
||
} /* for all locations of a hit before the position */
|
||
} /* for all members of the hit list before the position */
|
||
} /* if hits are currently shown */
|
||
else posFile = NULL; /* an error occurred */
|
||
} /* if position is in the hit list */
|
||
|
||
done:
|
||
if (ret_hit) *ret_hit = hit;
|
||
if (ret_file) *ret_file = posFile;
|
||
if (ret_locationId)
|
||
{
|
||
if ( locationIdList ) *ret_locationId = locationIdList[0];
|
||
else *ret_locationId = NULL;
|
||
}
|
||
if (ret_helpFile)
|
||
{
|
||
if ( fileNameList ) *ret_helpFile = fileNameList[0];
|
||
else *ret_helpFile = NULL;
|
||
}
|
||
/* WARNING: depends on pointers and integers the same size */
|
||
#ifdef __LP64__
|
||
return (0 == ((int64_t)hit|(int64_t)posFile|(int64_t)locationIdList)) ? -1 : 0;
|
||
#else
|
||
return (0 == ((int)hit|(int)posFile|(int)locationIdList)) ? -1 : 0;
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: HitListAddFound()
|
||
*
|
||
* Adds a hit to the hit list of the specified volume
|
||
* The hits are added either to the end of the list,
|
||
* so that the srchResultList presents the items in the order found,
|
||
* or in a sorted order.
|
||
* If a hit on that topic already exists, just the existing
|
||
* hit structure is returned.
|
||
*
|
||
* Return Parameters:
|
||
* Ret_hit points to the hit data. This is not a copy--do not
|
||
* free the pointer.
|
||
*
|
||
* Return value:
|
||
* Returns 0 if no error, -1 if an error occurred.
|
||
************************************************************************/
|
||
static int HitListAddFound (
|
||
_DtHelpFileEntry curFile,
|
||
XmString indexTitle,
|
||
char * indexEntry,
|
||
Boolean insertSorted,
|
||
_DtHelpGlobSrchHit **ret_hit)
|
||
{
|
||
_DtHelpGlobSrchHit * prev;
|
||
_DtHelpGlobSrchHit * next;
|
||
_DtHelpGlobSrchHit * srcHit;
|
||
_DtHelpGlobSrchVol * vol;
|
||
int newKey;
|
||
extern _CEStrcollProc _DtHelpCeGetStrcollProc();
|
||
_CEStrcollProc strcollfn = _DtHelpCeGetStrcollProc();
|
||
|
||
if (NULL == curFile) return -1; /* RETURN */
|
||
vol = (_DtHelpGlobSrchVol *) curFile->clientData;
|
||
if (NULL == vol) return -1; /* RETURN */
|
||
|
||
/* walk along the hits, looking for one matching the new hit */
|
||
/* recall that position is 1-based */
|
||
newKey = _DtHelpCeStrHashToKey(indexEntry);
|
||
prev = next = NULL;
|
||
if ( insertSorted ) /* find position and check for duplicates */
|
||
{
|
||
/* walk along list */
|
||
for( next = vol->hitListHead;
|
||
NULL != next;
|
||
prev = next, next = next->next )
|
||
{
|
||
int ret;
|
||
|
||
/* do a NLS case insensitive compare using NLS collating */
|
||
if ( (ret = (*strcollfn)(next->indexEntry,indexEntry)) >= 0 )
|
||
{
|
||
if (0 == ret)
|
||
{
|
||
if(ret_hit) *ret_hit = next;
|
||
return 0; /* RETURN */
|
||
}
|
||
/* prev and next are set correctly */
|
||
break; /* BREAK */
|
||
}
|
||
}
|
||
}
|
||
else /* check for duplicates */
|
||
{
|
||
/* walk along list */
|
||
for( next = vol->hitListHead;
|
||
NULL != next;
|
||
prev = next, next = next->next )
|
||
{
|
||
if ( newKey == next->indexKey /* quick compare */
|
||
&& strcmp(indexEntry,next->indexEntry) == 0 ) /* long compare */
|
||
{
|
||
if(ret_hit) *ret_hit = next;
|
||
return 0; /* RETURN */
|
||
}
|
||
}
|
||
/* prev and next are set correctly (at end of list) */
|
||
}
|
||
|
||
/* handle a new hit */
|
||
srcHit = (_DtHelpGlobSrchHit *)XtCalloc(1,sizeof(_DtHelpGlobSrchHit));
|
||
if (NULL == srcHit) return -1; /* RETURN */
|
||
|
||
/* init hit values */
|
||
/* leave srcHit->hitCnt == 0 here */
|
||
if (NULL == indexTitle)
|
||
srcHit->indexTitle = XmStringCreateLocalized(indexEntry);
|
||
else
|
||
srcHit->indexTitle = indexTitle;
|
||
srcHit->indexEntry = XtNewString(indexEntry);
|
||
srcHit->indexKey = newKey;
|
||
srcHit->volume = curFile;
|
||
|
||
/* integrate hit into the list */
|
||
srcHit->next = next;
|
||
if (prev) prev->next = srcHit;
|
||
else vol->hitListHead = srcHit;
|
||
if (!next) vol->hitListTail = srcHit;
|
||
|
||
/* add in the volume contribution */
|
||
vol->hitCnt++;
|
||
|
||
/* return stuff */
|
||
if(ret_hit) *ret_hit = srcHit;
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: CountSelectedVolumes()
|
||
*
|
||
* Counts the number volumes with the searchThisVolume flag set
|
||
* for which the search has yet to complete
|
||
*
|
||
************************************************************************/
|
||
static int CountSelectedVolumes (
|
||
_DtHelpFileList volListHead,
|
||
Boolean countSearchCompletedVolumes)
|
||
{
|
||
int count = 0;
|
||
|
||
/* walk all volumes */
|
||
for ( /* nothing */;
|
||
NULL != volListHead;
|
||
volListHead = _DtHelpFileListGetNext(NULL, volListHead) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
|
||
/* get the volume info */
|
||
vol = (_DtHelpGlobSrchVol *) volListHead->clientData;
|
||
/* if (NULL != vol && vol->searchThisVolume && False == vol->searchCompleted)*/
|
||
if (vol && vol->searchThisVolume)
|
||
{
|
||
if ( (False == vol->searchCompleted)
|
||
|| (countSearchCompletedVolumes && vol->searchCompleted) )
|
||
count++;
|
||
}
|
||
} /* walk all volumes */
|
||
return count;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: GetNextSearchFileAndDisplayCompleted()
|
||
*
|
||
* Scans list for next file ready for searching
|
||
* If it encounters a file that has completed it's search
|
||
* and for which the results should be displayed, they are displayed
|
||
*
|
||
************************************************************************/
|
||
static _DtHelpFileEntry GetNextSearchFileAndDisplayCompleted(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileList listHead,
|
||
_DtHelpFileEntry curFile)
|
||
{
|
||
/* get first file needing work */
|
||
for ( curFile = _DtHelpFileListGetNext(listHead, curFile);
|
||
NULL != curFile;
|
||
curFile = _DtHelpFileListGetNext(NULL, curFile) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
|
||
vol = (_DtHelpGlobSrchVol *) curFile->clientData;
|
||
if (NULL == vol) continue; /* CONTINUE */
|
||
|
||
/* if file already searched and should be displayed, then do so */
|
||
if ( vol->searchThisVolume && vol->searchCompleted
|
||
&& vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
|
||
{
|
||
/* record that a hit found */
|
||
if ( vol->hitCnt > 0
|
||
|| ( vol->zeroHitsOk
|
||
&& _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
|
||
hw->help_dialog.srch.hitsFound = True;
|
||
|
||
/* True: adjust count beginning with this file */
|
||
AdjustPositionValues(curFile,0,1,True);
|
||
ResultsListUpdate(hw,curFile);
|
||
|
||
/* display the hits as well? */
|
||
if ( vol->showHitsWithVol
|
||
|| hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
|
||
{
|
||
VolHitsDisplay(hw,curFile);
|
||
|
||
/* update the volume label to show state; False--don't insert */
|
||
VolNameDisplay(hw,curFile,False);
|
||
}
|
||
}
|
||
|
||
/* if want to search, and need to, then return it */
|
||
if ( vol->searchThisVolume && False == vol->searchCompleted
|
||
&& vol->showVolInList ) /* don' search unless results will be shown */
|
||
break;
|
||
}
|
||
|
||
XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
|
||
return curFile;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: AddVolInfoToFile
|
||
*
|
||
* Creates a volume info entry for each member of the list
|
||
* and initializes its values
|
||
* If searchStatus is False, all volumes are set. If its True,
|
||
* all are set if selectedFilesOnly is false, otherwise only
|
||
* selected files are set to true.
|
||
*
|
||
************************************************************************/
|
||
static void AddVolInfoToFile(
|
||
_DtHelpFileEntry file,
|
||
Boolean initialSearchStatus,
|
||
Boolean displayStatus,
|
||
Boolean selectedFilesOnly)
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
|
||
if (NULL == file) return; /* RETURN */
|
||
|
||
vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
if (NULL == vol)
|
||
{
|
||
vol = (_DtHelpGlobSrchVol *) XtCalloc(1,sizeof(_DtHelpGlobSrchVol));
|
||
file->clientData = (XtPointer) vol;
|
||
if (NULL == vol) return; /* RETURN: memory alloc error */
|
||
|
||
/* calloc() inited almost everything inside to 0 */
|
||
/* set first time creation values */
|
||
vol->nothingDone = True;
|
||
}
|
||
|
||
/* now set search and display flags */
|
||
vol->searchThisVolume = initialSearchStatus;
|
||
vol->showVolInList = displayStatus;
|
||
if ( False == file->fileSelected && True == selectedFilesOnly )
|
||
{
|
||
vol->searchThisVolume = False;
|
||
vol->showVolInList = False;
|
||
}
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: AddVolInfoToList
|
||
*
|
||
* Creates a volume info entry for each member of the list
|
||
* and initializes its values
|
||
* If searchStatus is False, all volumes are set. If its True,
|
||
* all are set if selectedFilesOnly is false, otherwise only
|
||
* selected files are set to true.
|
||
*
|
||
************************************************************************/
|
||
static void AddVolInfoToList(
|
||
_DtHelpFileList listHead,
|
||
Boolean initialSearchStatus,
|
||
Boolean displayStatus,
|
||
Boolean selectedFilesOnly)
|
||
{
|
||
/* walk the files and allocate the vol info as needed */
|
||
for ( /*nothing*/;
|
||
NULL != listHead;
|
||
listHead = _DtHelpFileListGetNext(listHead,listHead) )
|
||
{
|
||
AddVolInfoToFile(listHead,
|
||
initialSearchStatus, displayStatus, selectedFilesOnly);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: SetVolStatus()
|
||
*
|
||
* Sets all volumes in the list to the specified search and/or display
|
||
* status values.
|
||
*
|
||
* If searchThisVolume is False, all volumes are set. If its True,
|
||
* all are set if selectedFilesOnly is false, otherwise only
|
||
* selected files are set to true. If searchThisVolume is False,
|
||
* then the settings remain unchanged in all volumes.
|
||
*
|
||
************************************************************************/
|
||
static void SetVolStatus(
|
||
_DtHelpFileList listHead,
|
||
Boolean searchThisVolume,
|
||
Boolean showVolInList,
|
||
Boolean zeroHitsOk,
|
||
Boolean selectedFilesOnly)
|
||
{
|
||
/* walk the files and set the status */
|
||
for ( /*nothing*/;
|
||
NULL != listHead;
|
||
listHead = _DtHelpFileListGetNext(listHead,listHead) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
|
||
|
||
if (NULL == vol) continue;
|
||
|
||
if ( (False == selectedFilesOnly)
|
||
|| (True == listHead->fileSelected && True == selectedFilesOnly) )
|
||
{
|
||
/* just set the inclusion and/or display flags;
|
||
don't reset the search progress flags */
|
||
vol->searchThisVolume = searchThisVolume;
|
||
vol->showVolInList = showVolInList;
|
||
vol->zeroHitsOk = zeroHitsOk;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: VolNameDisplay()
|
||
*
|
||
* Updates the display of the volume name
|
||
************************************************************************/
|
||
static void VolNameDisplay(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file,
|
||
Boolean insertVol)
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
XmString prefixString;
|
||
XmString labelString;
|
||
char * tmpStr;
|
||
char buf[40];
|
||
|
||
if ( NULL == vol || (False == vol->zeroHitsOk && 0 == vol->hitCnt) )
|
||
return; /* RETURN */
|
||
|
||
/* put volume name into list */
|
||
if (vol->hitCnt <= 0) tmpStr = (char *)_DTGETMESSAGE (GSSET, 25," ");
|
||
else if (vol->hitsDisplayed) tmpStr = (char *)_DTGETMESSAGE (GSSET, 27,"-");
|
||
else tmpStr = (char *)_DTGETMESSAGE (GSSET, 26,"+"); /* >0 hits */
|
||
sprintf(buf, "%s%3d ", tmpStr, vol->hitCnt); /* 4d too spacy */
|
||
|
||
LoadPrefixFont(hw);
|
||
prefixString = XmStringGenerate(buf, s_PrefixFontListTag,
|
||
XmCHARSET_TEXT, NULL);
|
||
labelString = XmStringConcat(prefixString,file->fileTitleXmStr);
|
||
|
||
/* replace or insert to reflect changed contents */
|
||
if (insertVol)
|
||
XmListAddItemUnselected(hw->help_dialog.srch.resultList,
|
||
labelString, vol->startPosition);
|
||
else
|
||
XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
|
||
&labelString, 1, vol->startPosition);
|
||
|
||
XmStringFree(prefixString);
|
||
XmStringFree(labelString);
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: VolHitsDisplay()
|
||
*
|
||
* displays the hits associated with a volume
|
||
* Returns the number of new items added to the list
|
||
************************************************************************/
|
||
static int VolHitsDisplay (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file)
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
_DtHelpGlobSrchHit * hit;
|
||
int listPos = vol->startPosition; /* vol item position */
|
||
int itemCnt;
|
||
|
||
if (True == vol->hitsDisplayed ) return 0; /* RETURN */
|
||
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
/*** walk through the hits and count and display any open hits ***/
|
||
for ( hit = vol->hitListHead, itemCnt = 0;
|
||
NULL != hit;
|
||
hit = hit->next)
|
||
{
|
||
itemCnt++; /* True: insert Hit into list */
|
||
HitNameDisplay (hw,file,hit,listPos + itemCnt,True);
|
||
|
||
/* display topics too? */
|
||
if (hit->showTopicsWithHit)
|
||
{
|
||
int newItems;
|
||
newItems = HitTopicsDisplay(hw,file,hit, listPos + itemCnt + 1);
|
||
HitNameDisplay (hw,file,hit,listPos + itemCnt,False);
|
||
itemCnt += newItems;
|
||
}
|
||
}
|
||
|
||
/* new state */
|
||
vol->hitsDisplayed = True;
|
||
vol->showHitsWithVol = True;
|
||
|
||
/* adjust count beginning with next file with hits */
|
||
AdjustPositionValues(file, 0, itemCnt, True);
|
||
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
return itemCnt;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: VolHitsUndisplay()
|
||
*
|
||
* undisplays the hits associated with a volume
|
||
************************************************************************/
|
||
static int VolHitsUndisplay (
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file)
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
_DtHelpGlobSrchHit * hit;
|
||
Boolean nonVisibleItems;
|
||
int listPos = vol->startPosition; /* vol item position */
|
||
int itemCnt;
|
||
int curDelPos;
|
||
int undisItemCnt;
|
||
int visItemCnt;
|
||
int topNonVisPos;
|
||
int topPos;
|
||
Arg args[5];
|
||
|
||
if (False == vol->hitsDisplayed) return 0; /* RETURN */
|
||
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
XtSetArg(args[0], XmNtopItemPosition, &topPos);
|
||
XtSetArg(args[1], XmNvisibleItemCount, &visItemCnt);
|
||
XtGetValues(hw->help_dialog.srch.resultList,args,2);
|
||
|
||
/* these are the num visible items below the volume name */
|
||
topNonVisPos = topPos + visItemCnt; /* 1st non vis pos */
|
||
|
||
/* num of items that will be undisplayed */
|
||
undisItemCnt = vol->nextVolPosition - (vol->startPosition + 1);
|
||
|
||
/* find out if any items aren't visible */
|
||
nonVisibleItems = False;
|
||
if ( vol->nextVolPosition > topNonVisPos )
|
||
nonVisibleItems = True;
|
||
|
||
/*** walk through the hits and count and delete any open topics ***/
|
||
/* Make two passes: the first pass deletes all non-visible
|
||
items. The second pass deletes the remaining visible items.
|
||
The objective is to make collapse as fast and smooth as expand. */
|
||
if (nonVisibleItems)
|
||
{ /* delete all items with a position > topNonVisPos */
|
||
curDelPos = listPos + 1; /* starting position */
|
||
for ( hit = vol->hitListHead, itemCnt = 0;
|
||
NULL != hit;
|
||
hit = hit->next )
|
||
{
|
||
/* are we still in the visible region? */
|
||
if (curDelPos < topNonVisPos)
|
||
{
|
||
/* move down the list to next hit */
|
||
curDelPos++; /* this hit's item */
|
||
/* plus any open topics */
|
||
if (hit->topicsDisplayed) curDelPos += hit->topicCnt;
|
||
continue; /* CONTINUE */
|
||
}
|
||
/* we're in non-visible region--undisplay hit */
|
||
XmListDeletePos(hw->help_dialog.srch.resultList, curDelPos);
|
||
/* undisplay any topics */
|
||
if ( hit->topicsDisplayed )
|
||
itemCnt += HitTopicsUndisplay(hw,file,hit,curDelPos);
|
||
}
|
||
} /* if non visible items */
|
||
|
||
/* now delete the remaining visible items */
|
||
/* Note that curDelPos is a virtual cursor that helps us
|
||
figure out when to stop undisplaying. Virtually, we''re
|
||
moving the cursor down the list with every delete. Actually,
|
||
the rest of the list bumps up one--that''s why we delete
|
||
at listPos+1. */
|
||
|
||
curDelPos = listPos + 1; /* starting position */
|
||
for ( hit = vol->hitListHead, itemCnt = 0;
|
||
(NULL != hit) && (curDelPos < topNonVisPos);
|
||
hit = hit->next )
|
||
{
|
||
curDelPos++; /* undisplay hit item */
|
||
XmListDeletePos(hw->help_dialog.srch.resultList, listPos + 1);
|
||
/* undipslay any open topics */
|
||
if ( hit->topicsDisplayed )
|
||
{
|
||
curDelPos += HitTopicsUndisplay(hw,file,hit,listPos + 1);
|
||
XmListSetPos(hw->help_dialog.srch.resultList, topPos);
|
||
}
|
||
}
|
||
|
||
/* new state */
|
||
vol->hitsDisplayed = False;
|
||
/* NOTE: don't reset vol->showHitsWithVol here; require that
|
||
to be explicitly reset in ProcessResultSelection() */
|
||
|
||
/* adjust count beginning with next file with hits */
|
||
AdjustPositionValues(file, 0, -undisItemCnt, True);
|
||
|
||
XmListSetPos(hw->help_dialog.srch.resultList, topPos);
|
||
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
return undisItemCnt;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: VolListFree()
|
||
*
|
||
* Releases all memory used by the volume list
|
||
*
|
||
************************************************************************/
|
||
static void VolListFree (
|
||
_DtHelpGlobSearchStuff * srch)
|
||
{
|
||
_DtHelpFileList nextFile;
|
||
|
||
/* walk all volumes */
|
||
nextFile = srch->volListHead;
|
||
while ( NULL != nextFile )
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
_DtHelpFileList tmpFile;
|
||
XmString * nextStr;
|
||
|
||
/* get the volume info */
|
||
vol = (_DtHelpGlobSrchVol *) nextFile->clientData;
|
||
|
||
/** free vol entry contents and container **/
|
||
XtFree(vol->stdLocale);
|
||
XtFree(vol->iconv3Codeset);
|
||
HitListFree(vol,True); /* True: free hits themselves */
|
||
|
||
/* no need to free indexEntriesList because these aren't owned by vol */
|
||
vol->indexEntriesList = NULL;
|
||
|
||
/* free indexXmStrsList */
|
||
/* indexXmStrs are XmStrings and we can't use FreeStringArray() */
|
||
for ( nextStr = vol->indexXmStrsList;
|
||
NULL != nextStr && NULL != *nextStr;
|
||
nextStr++)
|
||
XmStringFree (*nextStr);
|
||
XtFree((char *) vol->indexXmStrsList); /* its a XmString * */
|
||
vol->indexXmStrsList = NULL;
|
||
|
||
tmpFile = nextFile;
|
||
nextFile = _DtHelpFileListGetNext(NULL, nextFile);
|
||
_DtHelpFileFreeEntry(tmpFile); /* also frees the clientData (vol) */
|
||
} /* walk all volumes */
|
||
|
||
/* reset related values */
|
||
srch->volListHead = NULL;
|
||
srch->curSrchVol = NULL;
|
||
srch->volLeftCnt = 0;
|
||
|
||
/* delete the results */
|
||
DeleteListContents(srch);
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: ScanStatusCB
|
||
*
|
||
* Updates the status display with the number of volumes found
|
||
* as the scan progresses
|
||
*
|
||
************************************************************************/
|
||
static void ScanStatusCB(
|
||
int count,
|
||
XtPointer clientData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
|
||
StatusLabelUpdate(hw,SCANNING_STATUS,True,count);
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: VolListBuild
|
||
*
|
||
* Frees the old list and builds a new one by scanning the
|
||
* help directories for volumes and adding the associated
|
||
* volume information used for searching.
|
||
*
|
||
************************************************************************/
|
||
static void VolListBuild(
|
||
DtHelpDialogWidget hw,
|
||
Boolean searchStatus,
|
||
Boolean displayStatus,
|
||
Boolean selectedVolumesOnly)
|
||
{
|
||
Boolean mod;
|
||
XmFontList origFontList;
|
||
|
||
/* turn on hour glass */
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
StatusLabelUpdate(hw,SCANNING_STATUS,True,0);
|
||
|
||
origFontList = hw->help_dialog.srch.volTitlesFontList;
|
||
|
||
/* and rescan the volumes for the new list */
|
||
_DtHelpFileListScanPaths( &hw->help_dialog.srch.volListHead,
|
||
&hw->help_dialog.srch.volTitlesFontList,&mod,
|
||
DtHelpVOLUME_TYPE, _DtHelpFileSuffixList, False,
|
||
GetVolumeInfoCB,hw->help_dialog.help.pDisplayArea,
|
||
/* sysPathCompare */ _DtHELP_FILE_NAME,
|
||
/*otherPathCompare*/ _DtHELP_FILE_NAME|_DtHELP_FILE_TIME| _DtHELP_FILE_IDSTR,
|
||
/* sortBy */ _DtHELP_FILE_TITLE, ScanStatusCB, (XtPointer)hw);
|
||
|
||
/* if new fonts added to list, add them to the resultList */
|
||
if (mod)
|
||
{
|
||
MergeFontListIntoWidgetFonts(
|
||
hw->help_dialog.srch.resultList,
|
||
hw->help_dialog.srch.volTitlesFontList);
|
||
|
||
if (origFontList) XmFontListFree(origFontList);
|
||
}
|
||
|
||
/* Add on the Vol info and (T,F) allow search on all volumes */
|
||
AddVolInfoToList(hw->help_dialog.srch.volListHead,
|
||
searchStatus, displayStatus, selectedVolumesOnly);
|
||
|
||
hw->help_dialog.srch.volScanDone = True;
|
||
|
||
StatusLabelUpdate(hw,BLANK_STATUS,True,0);
|
||
|
||
/* turn off hour glass */
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
}
|
||
|
||
|
||
|
||
#if 0 || defined(DEBUG) /* for debug, set to 1 */
|
||
/************************************************************************
|
||
* Function: OutputVolInfo()
|
||
*
|
||
* Output info on all volumes in the list
|
||
*
|
||
************************************************************************/
|
||
static void OutputVolInfo(
|
||
_DtHelpFileList listHead)
|
||
{
|
||
for ( /*nothing*/;
|
||
NULL != listHead;
|
||
listHead = _DtHelpFileListGetNext(listHead,listHead) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
|
||
if (NULL == vol) continue;
|
||
|
||
/* output the info */
|
||
printf("==================\n");
|
||
printf("fileName: %s, %s\npathName: %s\n",
|
||
listHead->fileName, listHead->fileTitle, listHead->fullFilePath);
|
||
printf("searchThisVolume = %d, hitCnt = %d, startPos = %d\n",
|
||
(int) listHead->fileSelected,
|
||
(int) vol->hitCnt,
|
||
(int) vol->startPosition);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
/************************************************************************
|
||
* Function: SearchContinuePossible()
|
||
*
|
||
* Test whether the search can be continued from the
|
||
* current state.
|
||
*
|
||
************************************************************************/
|
||
static Boolean SearchContinuePossible(
|
||
DtHelpDialogWidget hw,
|
||
char * srchWord)
|
||
{
|
||
char * normSrchWord;
|
||
Boolean possible = False;
|
||
|
||
normSrchWord = XtNewString(srchWord);
|
||
_DtHelpCeCompressSpace(normSrchWord);
|
||
_DtHelpCeUpperCase(normSrchWord);
|
||
|
||
/* are we searching on the same word as previous search ? */
|
||
/* comparison with srchNormWordStr is correct, given calls to this fn */
|
||
/* FIX: use CheckSearchWord()? */
|
||
if ( ( hw->help_dialog.srch.fullIndex
|
||
|| ( NULL != hw->help_dialog.srch.normWordStr
|
||
&& NULL != normSrchWord
|
||
&& strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
|
||
&& NULL != hw->help_dialog.srch.volListHead
|
||
&& hw->help_dialog.srch.volLeftCnt > 0 )
|
||
possible = True;
|
||
|
||
XtFree(normSrchWord);
|
||
return possible;
|
||
}
|
||
|
||
|
||
#ifdef not_used
|
||
/************************************************************************
|
||
* Function: SearchOnSameCriteria()
|
||
*
|
||
* Test whether the search criteria have changed
|
||
*
|
||
************************************************************************/
|
||
static Boolean SearchOnSameCriteria(
|
||
DtHelpDialogWidget hw,
|
||
char * srchWord)
|
||
{
|
||
char * normSrchWord;
|
||
Boolean sameCrit = False;
|
||
|
||
normSrchWord = XtNewString(srchWord);
|
||
_DtHelpCeCompressSpace(normSrchWord);
|
||
_DtHelpCeUpperCase(normSrchWord);
|
||
|
||
/* are we searching on the same word as previous search ? */
|
||
/* comparison with srchNormWordStr is correct, given calls to this fn */
|
||
if ( hw->help_dialog.srch.fullIndex
|
||
|| ( NULL != hw->help_dialog.srch.normWordStr
|
||
&& NULL != normSrchWord
|
||
&& strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
|
||
sameCrit = True;
|
||
|
||
XtFree(normSrchWord);
|
||
return sameCrit;
|
||
}
|
||
#endif /* not_used */
|
||
|
||
|
||
|
||
|
||
/************************************************************************
|
||
* Function: UpdateActionButtonLabel()
|
||
*
|
||
* Sets the start button label properly
|
||
*
|
||
************************************************************************/
|
||
static void UpdateActionButtonLabel(
|
||
DtHelpDialogWidget hw,
|
||
char * srchWord,
|
||
Boolean startContAction)
|
||
{
|
||
Arg args[5];
|
||
XmString labelString;
|
||
XmString curLabelString;
|
||
String textString;
|
||
/* char * mnemonic; */
|
||
|
||
/* if action label is to start or continue */
|
||
_DtHelpProcessLock();
|
||
if (startContAction)
|
||
{
|
||
if ( SearchContinuePossible(hw,srchWord) )
|
||
{ /* then continue search */
|
||
textString=(char *)_DTGETMESSAGE (GSSET,
|
||
CONT_SEARCH_CAT,CONT_SEARCH_STR);
|
||
labelString = XmStringCreateLocalized(textString);
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 22,CONT_SEARCH_MNEM));*/
|
||
}
|
||
else
|
||
{ /* otherwise start it */
|
||
textString=(char *)_DTGETMESSAGE (GSSET,
|
||
START_SEARCH_CAT,START_SEARCH_STR);
|
||
labelString = XmStringCreateLocalized(textString);
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
|
||
}
|
||
}
|
||
else /* action label is to stop */
|
||
{
|
||
textString = (char *)_DTGETMESSAGE (GSSET,
|
||
STOP_SEARCH_CAT,STOP_SEARCH_STR);
|
||
labelString = XmStringCreateLocalized(textString);
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, ??,STOP_SEARCH_MNEM));*/
|
||
}
|
||
_DtHelpProcessUnlock();
|
||
|
||
/* get the current state of the button */
|
||
XtSetArg(args[0],XmNlabelString,&curLabelString);
|
||
XtGetValues (hw->help_dialog.srch.actionBtn, args, 1);
|
||
|
||
/* update label if it is different; avoid flashing this way */
|
||
if ( XmStringCompare(labelString,curLabelString) == False )
|
||
{
|
||
XtSetArg(args[0],XmNlabelString,labelString);
|
||
XtSetArg(args[1], XmNalignment, XmALIGNMENT_CENTER);
|
||
/* XtSetArg(args[2], XmNmnemonic, mnemonic[0]);*/
|
||
XtSetValues (hw->help_dialog.srch.actionBtn, args, 2);
|
||
XmUpdateDisplay(hw->help_dialog.srch.actionBtn);
|
||
}
|
||
|
||
/* release the memory */
|
||
XmStringFree(labelString);
|
||
XmStringFree(curLabelString);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: CheckSearchWord()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: True: word has changed
|
||
* False: word is same
|
||
*
|
||
* Purpose: Checks whether the search word is a new
|
||
* one or the same as before. If the same, it frees
|
||
* the word and returns False. If new, it moves the
|
||
* previous word to another variable and installs
|
||
* the new word in its place, using the srchWord mem.
|
||
* ...but only if updateWidgetFields is True
|
||
*
|
||
*****************************************************************************/
|
||
static Boolean CheckSearchWord(
|
||
DtHelpDialogWidget hw,
|
||
char * srchWord,
|
||
Boolean updateWidgetFields)
|
||
{
|
||
wchar_t firstChar;
|
||
char * rawSrchWord;
|
||
|
||
/* avoid a core dump */
|
||
if ( NULL == srchWord )
|
||
{
|
||
if ( NULL == hw->help_dialog.srch.normWordStr
|
||
|| hw->help_dialog.srch.normWordStr[0] == 0)
|
||
return False; /* word hasn't changed */
|
||
return True; /* RETURN: word has changed */
|
||
}
|
||
|
||
_DtHelpCeCompressSpace(srchWord);
|
||
rawSrchWord = XtNewString(srchWord);
|
||
_DtHelpCeUpperCase(srchWord);
|
||
/* FIX: to support regcomp(3), do that here */
|
||
|
||
/* are we searching on the same word? */
|
||
if ( NULL != hw->help_dialog.srch.normWordStr
|
||
&& strcmp(srchWord, hw->help_dialog.srch.normWordStr) == 0 )
|
||
{
|
||
XtFree(srchWord);
|
||
XtFree(rawSrchWord);
|
||
#if 0
|
||
/* output a message */
|
||
if ( NULL != hw->help_dialog.srch.normWordStr
|
||
&& EOS != hw->help_dialog.srch.normWordStr[0])
|
||
StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
|
||
#endif
|
||
|
||
return False; /* RETURN: no change */
|
||
}
|
||
|
||
if (False == updateWidgetFields) return True; /* RETURN */
|
||
|
||
/* update search word fields */
|
||
XtFree(hw->help_dialog.srch.normWordStr);
|
||
XtFree(hw->help_dialog.srch.rawWordStr);
|
||
hw->help_dialog.srch.normWordStr = srchWord;
|
||
hw->help_dialog.srch.rawWordStr = rawSrchWord;
|
||
hw->help_dialog.srch.wordFieldLen = strlen(srchWord); /* note: not nl_strlen
|
||
because used on strncmp not nl_strncmp */
|
||
|
||
/* convert first char to a value for easy access for _DtHelpStrchr() */
|
||
if ( mbtowc(&firstChar,srchWord,1) <= 0 ) firstChar = 0;
|
||
hw->help_dialog.srch.wordFieldFirstChar = firstChar;
|
||
|
||
/* output a message */
|
||
if ( NULL != hw->help_dialog.srch.normWordStr
|
||
&& EOS != hw->help_dialog.srch.normWordStr[0])
|
||
StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
|
||
|
||
return True; /* word changed */
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: PrepSearchSourceData()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Based on the current settings of the volume
|
||
* selection buttons construct or utilitize an
|
||
* existing volume list for processing.
|
||
* Determine whether to continue search or
|
||
* restart by comparing search words and states.
|
||
*
|
||
*****************************************************************************/
|
||
static void PrepSearchSourceData(
|
||
DtHelpDialogWidget hw,
|
||
char * srchWord)
|
||
{
|
||
/* try to install the new word; if returns False, word is same
|
||
as before. True = also update widget fields. */
|
||
/* This test determines whether we might need to continue. */
|
||
if ( hw->help_dialog.srch.fullIndex
|
||
|| CheckSearchWord(hw,srchWord,True) == False )
|
||
{
|
||
/* check to see if CheckSearchWord() was called. If it wasn't
|
||
then srchWord has not been freed or saved. We will lose the
|
||
memory unless we free it here. */
|
||
if (hw->help_dialog.srch.fullIndex)
|
||
XtFree(srchWord);
|
||
|
||
/* are we continuing an interrupted search? */
|
||
if ( hw->help_dialog.srch.volLeftCnt > 0
|
||
&& NULL != hw->help_dialog.srch.volListHead )
|
||
return; /* RETURN: continue with search */
|
||
|
||
/* if searching full index, False=don't free vol with full index */
|
||
if (hw->help_dialog.srch.fullIndex)
|
||
HitListFreeAllVolHits(hw,False);
|
||
/* else we're searching on the same word, but completed
|
||
previous search. So reset the volumes to search/display
|
||
according to the current settings of the Volumes radio buttons,
|
||
but leave the results intact.
|
||
*/
|
||
/* fall thru to do prep */
|
||
}
|
||
else /* searching for a different word */
|
||
{
|
||
/* free all hit-related data and reset flags */
|
||
HitListFreeAllVolHits(hw,True); /*True=free everything*/
|
||
}
|
||
|
||
/*** It's not just a continue. So, we may be beginning a new search
|
||
or continuing a search based on new volume selection params ***/
|
||
|
||
/* update display area */
|
||
DeleteListContents(&hw->help_dialog.srch);
|
||
StatusLabelUpdate(hw,WORKING_STATUS,False,0);
|
||
|
||
/*** update the volumes list according to sources selected ***/
|
||
if ( _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources )
|
||
{
|
||
/* volume list already built when opening selection dialog */
|
||
/* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
|
||
/* (T,T,T,T): enable search, enable display,
|
||
zero hits ok, only for selected volumes */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
|
||
} /* if selected volumes button */
|
||
else if ( _DtHelpGlobSrchAllVolumes == hw->help_dialog.srch.srchSources )
|
||
{
|
||
/* Scan directories for volumes if necessary */
|
||
if ( False == hw->help_dialog.srch.volScanDone
|
||
|| NULL == hw->help_dialog.srch.volListHead)
|
||
{
|
||
/* Add on the Vol info; (T,T,F) search, display, all */
|
||
VolListBuild(hw,True,True,False);
|
||
}
|
||
|
||
/* (T,T,F,F): enable search,enable display,no 0 hits,for all vols */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,True,True,False,False);
|
||
} /* if all volumes button */
|
||
else /*** current volume button ***/
|
||
{
|
||
char * path;
|
||
_DtHelpFileEntry cur;
|
||
|
||
/* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
|
||
|
||
/* try to locate file and its entry, if present */
|
||
path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
|
||
_DtHelpFileSuffixList,False,R_OK);
|
||
cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
|
||
GetVolumeInfoCB, _DtHELP_FILE_NAME,
|
||
hw->help_dialog.help.pDisplayArea);
|
||
|
||
if (NULL == cur && NULL != path) /*file was located but isn't in list*/
|
||
{ /* add it to the list */
|
||
Boolean mod;
|
||
XmFontList origFontList;
|
||
|
||
origFontList = hw->help_dialog.srch.volTitlesFontList;
|
||
|
||
_DtHelpFileListAddFile(&hw->help_dialog.srch.volListHead,
|
||
&hw->help_dialog.srch.volTitlesFontList,&mod,path,NULL,
|
||
GetVolumeInfoCB, _DtHELP_FILE_NAME, _DtHELP_FILE_TITLE,
|
||
hw->help_dialog.help.pDisplayArea);
|
||
if (mod)
|
||
{
|
||
MergeFontListIntoWidgetFonts(
|
||
hw->help_dialog.srch.resultList,
|
||
hw->help_dialog.srch.volTitlesFontList);
|
||
|
||
if (origFontList) XmFontListFree(origFontList);
|
||
}
|
||
|
||
/* (F,F,F): disable search, disable display, for all volumes */
|
||
AddVolInfoToList(hw->help_dialog.srch.volListHead,False,False,False);
|
||
cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
|
||
GetVolumeInfoCB, _DtHELP_FILE_NAME,
|
||
hw->help_dialog.help.pDisplayArea);
|
||
}
|
||
|
||
if (cur) /* file present in list */
|
||
{
|
||
/* enable search and display on this volume */
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) cur->clientData;
|
||
|
||
vol->searchThisVolume = True;
|
||
vol->showVolInList = True;
|
||
vol->zeroHitsOk = True; /* show zero hits for search of cur vol */
|
||
}
|
||
else /* file not found */
|
||
{
|
||
/* FIX: put up error dialog and disable the button */
|
||
/*printf("Current volume %s not found\n",
|
||
hw->help_dialog.display.helpVolume);*/
|
||
} /* if file found */
|
||
|
||
XtFree(path); /* tests for NULL */
|
||
} /* if selected/all/cur volumes sources */
|
||
|
||
#if 0 || defined(DEBUG) /* for debug, set to 1 */
|
||
OutputVolInfo(hw->help_dialog.srch.volListHead);
|
||
#endif
|
||
|
||
/* get num volumes to process */
|
||
hw->help_dialog.srch.volLeftCnt =
|
||
CountSelectedVolumes(hw->help_dialog.srch.volListHead,True);
|
||
|
||
/* empty the results list */
|
||
XmUpdateDisplay(hw->help_dialog.srch.resultList);
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* Function: CloseSearchCB()
|
||
*
|
||
* Close the Global Search Dialog
|
||
*
|
||
************************************************************************/
|
||
static void CloseSearchCB (
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
_DtHelpGlobSearchStuff * srch = (_DtHelpGlobSearchStuff *) clientData;
|
||
|
||
/* stop any work proc */
|
||
if(srch->workProcId)
|
||
{
|
||
XtRemoveWorkProc(srch->workProcId);
|
||
srch->workProcId = 0;
|
||
}
|
||
|
||
/* unmanage the srchForm dialog but don't destroy it */
|
||
if (NULL != srch->srchForm)
|
||
{
|
||
XtUnmanageChild(srch->srchForm);
|
||
XtUnmapWidget(srch->srchForm);
|
||
}
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void DeleteListContents()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: empties list and resets position values
|
||
*
|
||
*****************************************************************************/
|
||
static void DeleteListContents(
|
||
_DtHelpGlobSearchStuff * srch)
|
||
{
|
||
_DtHelpFileEntry curFile;
|
||
|
||
if (NULL != srch->resultList)
|
||
XmListDeleteAllItems(srch->resultList);
|
||
|
||
for ( curFile = srch->volListHead;
|
||
NULL != curFile;
|
||
curFile = _DtHelpFileListGetNext(NULL,curFile) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) curFile->clientData;
|
||
if (NULL == vol) continue; /* CONTINUE */
|
||
|
||
/* if any hits are displayed and any have open topics,
|
||
walk through and close them */
|
||
if ( vol->hitsDisplayed
|
||
&& ((vol->nextVolPosition - vol->startPosition) != vol->hitCnt) )
|
||
{
|
||
_DtHelpGlobSrchHit * hit;
|
||
for ( hit = vol->hitListHead;
|
||
NULL != hit;
|
||
hit = hit->next)
|
||
{
|
||
hit->topicsDisplayed = False;
|
||
}
|
||
}
|
||
|
||
vol->startPosition = 1;
|
||
vol->nextVolPosition = 1;
|
||
vol->hitsDisplayed = False;
|
||
}
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void StatusLabelUpdate()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Installs proper label over results list
|
||
*
|
||
*****************************************************************************/
|
||
static void StatusLabelUpdate(
|
||
DtHelpDialogWidget hw,
|
||
ResultsStatus status,
|
||
Boolean forceUpdate,
|
||
int intArg)
|
||
{
|
||
char * labelMsg;
|
||
XmString labelString;
|
||
XmString curLabelString;
|
||
Arg args[5];
|
||
char buf[100];
|
||
|
||
#if 0
|
||
/* only update if necessary */
|
||
if (status == hw->help_dialog.srch.statusLineUsage && !forceUpdate)
|
||
return;
|
||
#endif
|
||
|
||
/* order up the right message */
|
||
hw->help_dialog.srch.statusLineUsage = status;
|
||
switch (status)
|
||
{
|
||
case SCANNING_STATUS:
|
||
labelMsg = (char *)_DTGETMESSAGE(GSSET, 17,"Scanning for volumes... Found %d");
|
||
sprintf(buf,labelMsg,intArg);
|
||
labelMsg = buf;
|
||
break; /* BREAK */
|
||
case WORKING_STATUS:
|
||
labelMsg = (char *)_DTGETMESSAGE(GSSET, 18,
|
||
"Searching... Volumes remaining: %d");
|
||
/* we need +1 because of when this message is used */
|
||
sprintf(buf,labelMsg,hw->help_dialog.srch.volLeftCnt + 1);
|
||
labelMsg = buf;
|
||
break; /* BREAK */
|
||
case SEARCH_RESULTS_STATUS:
|
||
/* if no hits found */
|
||
if (hw->help_dialog.srch.hitsFound == False) /*don't use == True*/
|
||
{
|
||
if (hw->help_dialog.srch.fullIndex)
|
||
{
|
||
if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchAllVolumes)
|
||
labelMsg = (char *)_DTGETMESSAGE (GSSET,19,
|
||
"No index entries found.");
|
||
else
|
||
labelMsg = (char *)_DTGETMESSAGE (GSSET,50,
|
||
"No index entries found. Try All Volumes.");
|
||
}
|
||
else /* searched on a pattern */
|
||
{
|
||
labelMsg = (char *)_DTGETMESSAGE (GSSET,51,
|
||
"No index entries found. Try another word.");
|
||
}
|
||
/* change focus to the search word. Traversal is ignored
|
||
if srchWord is desensitized (Contains btn not selected) */
|
||
|
||
if (XtIsSensitive(hw->help_dialog.srch.wordField))
|
||
{
|
||
/*
|
||
* make sure the text field is editable before sending
|
||
* the traversal there.
|
||
*/
|
||
XtSetArg(args[0],XmNeditable,True);
|
||
XtSetValues(hw->help_dialog.srch.wordField, args, 1);
|
||
XmProcessTraversal
|
||
(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
|
||
}
|
||
else
|
||
XmProcessTraversal
|
||
(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
|
||
|
||
}
|
||
else /* if hits found */
|
||
{
|
||
/* select the appropriate message */
|
||
if (hw->help_dialog.srch.fullIndex)
|
||
{
|
||
labelMsg = (char *)_DTGETMESSAGE(GSSET, 20,"Complete Index");
|
||
|
||
}
|
||
else
|
||
{
|
||
labelMsg = (char *)_DTGETMESSAGE(GSSET, 21,"Entries with \"%s\"");
|
||
sprintf(buf,labelMsg,hw->help_dialog.srch.rawWordStr);
|
||
labelMsg = buf;
|
||
|
||
}
|
||
/* change focus to the results list */
|
||
XmProcessTraversal(
|
||
hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
|
||
|
||
|
||
} /* if no hits found else */
|
||
|
||
break; /* BREAK */
|
||
case NO_VOL_STATUS:
|
||
labelMsg = (char *)_DTGETMESSAGE (GSSET, 22,"No volumes selected");
|
||
break; /* BREAK */
|
||
case FIRST_PROMPT_STATUS:
|
||
labelMsg = (char *)_DTGETMESSAGE(GSSET,23,"Select search options above");
|
||
break; /* BREAK */
|
||
case BLANK_STATUS:
|
||
default:
|
||
/* DBG: when an empty string, form constraints are wrong; make a space */
|
||
labelMsg = " ";
|
||
break; /* BREAK */
|
||
}
|
||
|
||
/* make a label string */
|
||
labelString = XmStringCreateLocalized(labelMsg);
|
||
|
||
/* get the current string of the label */
|
||
curLabelString = NULL;
|
||
XtSetArg(args[0],XmNlabelString,&curLabelString);
|
||
XtGetValues (hw->help_dialog.srch.statusLabel, args, 1);
|
||
|
||
/* update label if it is different; avoid flashing this way */
|
||
if ( NULL != curLabelString && NULL != labelString
|
||
&& XmStringCompare(labelString,curLabelString) == False )
|
||
{
|
||
/* update msg over results list */
|
||
XtSetArg(args[0],XmNlabelString,labelString);
|
||
XtSetValues(hw->help_dialog.srch.statusLabel,args,1);
|
||
}
|
||
|
||
XmStringFree(labelString);
|
||
XmStringFree(curLabelString);
|
||
|
||
XmUpdateDisplay(hw->help_dialog.srch.statusLabel);
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void ResultsListUpdate()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: empty list and display results status message
|
||
*
|
||
*****************************************************************************/
|
||
static void ResultsListUpdate(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry newFile)
|
||
{
|
||
_DtHelpFileEntry testFile;
|
||
|
||
/* check that in fact, there are no results that will be overwritten */
|
||
for ( testFile = hw->help_dialog.srch.volListHead;
|
||
NULL != testFile;
|
||
testFile = _DtHelpFileListGetNext(NULL,testFile) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
vol = (_DtHelpGlobSrchVol *)testFile->clientData;
|
||
if (vol && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk))
|
||
break; /* BREAK */
|
||
}
|
||
|
||
/* clean the list out if this is the first new result */
|
||
/* this presumes that files are processed in order in the list */
|
||
if (testFile == newFile)
|
||
{
|
||
DeleteListContents(&hw->help_dialog.srch);
|
||
AdjustPositionValues(newFile,0,1,True);
|
||
}
|
||
/* True: insert new item */
|
||
VolNameDisplay(hw,newFile,True);
|
||
|
||
/* Update status label */
|
||
StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0); /* FIX: False */
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void SearchForPattern()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: True if pattern found, False if not found
|
||
*
|
||
* Purpose: Find a pattern in a string
|
||
*
|
||
* WARNING: may convert string to uppercase in place
|
||
* depending on which code is compiled.
|
||
*****************************************************************************/
|
||
static Boolean SearchForPattern(
|
||
char * string,
|
||
char * pattern,
|
||
int patternLen)
|
||
{
|
||
#if defined(NO_REGEX) /* don't support regex in string searches */
|
||
char * hit;
|
||
|
||
_DtHelpCeUpperCase(string);
|
||
/* FIX: make this code much faster by using an improved
|
||
pattern search algorithm, such as Rabin-Karp. */
|
||
/* hit is set to NULL if no matching char is found */
|
||
while (_DtHelpCeStrchr(string, pattern, MB_CUR_MAX, &hit) == 0)
|
||
{
|
||
if ( strncmp(hit,pattern,patternLen) == 0 )
|
||
break; /* BREAK */
|
||
else
|
||
string = hit + mblen(hit,1);
|
||
}
|
||
return (NULL != hit); /* RETURN True or False */
|
||
#else /* if NO_REGEX */
|
||
# ifndef NO_REGCOMP
|
||
regex_t re;
|
||
int ret = -1;
|
||
|
||
/* use regexec to pattern match */
|
||
/* a 0 return value indicates success */
|
||
if ( regcomp(&re,pattern,REG_NOSUB|REG_ICASE|REG_EXTENDED) == 0 )
|
||
{
|
||
/* a 0 return value indicates success */
|
||
ret = regexec(&re,string,0,NULL,0);
|
||
regfree(&re);
|
||
}
|
||
return (ret == 0); /* RETURN True or False */
|
||
# else /* NO_REGCOMP */
|
||
char *compiledRE;
|
||
char *ret = NULL;
|
||
|
||
/* a non NULL return value indicates success */
|
||
compiledRE = (char *)regcmp(pattern, (char *) NULL);
|
||
if (compiledRE)
|
||
{
|
||
/* a non NULL return value indicates success */
|
||
ret = regex(compiledRE, string);
|
||
free(compiledRE);
|
||
}
|
||
return (ret != NULL); /* RETURN True or False */
|
||
# endif /* NO_REGCOMP */
|
||
#endif /* if NO_REGEX */
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void OpenVolForSearch()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: False if an error
|
||
* True if no error
|
||
*
|
||
* Purpose: Opens a volume for searching,
|
||
* gets the volume locale, if
|
||
* different from system locale,
|
||
* saves system locale in vol,
|
||
* installs volume locale
|
||
*
|
||
* Note that the system locale
|
||
*****************************************************************************/
|
||
static Boolean OpenVolForSearch(
|
||
DtHelpDialogWidget hw,
|
||
char * fullFilePath,
|
||
_DtHelpGlobSrchVol * curVol)
|
||
{
|
||
Boolean openedVolume = False;
|
||
|
||
/* open the volume if not open */
|
||
if ( NULL == curVol->volHandle )
|
||
{
|
||
_DtHelpOpenVolume(fullFilePath, &curVol->volHandle);
|
||
if (NULL == curVol->volHandle) return False; /* RETURN */
|
||
|
||
if (curVol->gotLocale == False)
|
||
{
|
||
curVol->stdLocale = _DtHelpGetVolumeLocale(curVol->volHandle);
|
||
/* get the op-specific locales; the strings are default values */
|
||
_DtHelpCeXlateStdToOpLocale(DtLCX_OPER_ICONV3,curVol->stdLocale,
|
||
"iso88591",&curVol->iconv3Codeset);
|
||
curVol->gotLocale = True;
|
||
}
|
||
openedVolume = True;
|
||
|
||
/* get the codeset of the application's locale, if haven't gotten it */
|
||
if ( NULL == hw->help_dialog.srch.iconv3Codeset )
|
||
{
|
||
char * locale = NULL;
|
||
_DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,
|
||
setlocale(LC_CTYPE,NULL),&locale,NULL,NULL);
|
||
/* get the op-specific locales; the strings are default values */
|
||
/* impt: XlateStdToOpLocale() call requires a locale, not a codeset */
|
||
_DtHelpCeXlateStdToOpLocale(DtLCX_OPER_ICONV3,locale,
|
||
"iso88591",&hw->help_dialog.srch.iconv3Codeset);
|
||
XtFree(locale);
|
||
}
|
||
|
||
/** only saves or changes the locale if necessary **/
|
||
/* create an iconv3 context to convert codeset of */
|
||
/* the volume to the codeset of the application */
|
||
if ( _DtHelpCeIconvContextSuitable(hw->help_dialog.srch.iconv3Context,
|
||
curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset) == False )
|
||
{
|
||
/* close old, open new */
|
||
_DtHelpCeIconvClose(&hw->help_dialog.srch.iconv3Context);
|
||
_DtHelpCeIconvOpen(&hw->help_dialog.srch.iconv3Context,
|
||
curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset,' ',' ');
|
||
}
|
||
}
|
||
/* else volume already open */
|
||
|
||
/* if just opened volume */
|
||
if (openedVolume)
|
||
{
|
||
/* we just share pointers; when freeing localeWordStr, we need to
|
||
test whether they are different before freeing */
|
||
hw->help_dialog.srch.localeWordStr = hw->help_dialog.srch.normWordStr;
|
||
}
|
||
|
||
/* get the str coll function, iff needed */
|
||
if (NULL == curVol->strcollProc)
|
||
{
|
||
/* get strcollProc for vol locale */
|
||
curVol->strcollProc = _DtHelpCeGetStrcollProc();
|
||
}
|
||
|
||
return True;
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void CloseVolAfterSearch()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Closes a volume opened for searching,
|
||
* installs system locale, if diff from volume.
|
||
*
|
||
*****************************************************************************/
|
||
static void CloseVolAfterSearch(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpGlobSrchVol * curVol)
|
||
{
|
||
/* close the volume if open */
|
||
if ( NULL != curVol->volHandle )
|
||
{
|
||
_DtHelpCloseVolume(curVol->volHandle);
|
||
curVol->volHandle = NULL;
|
||
/* free the locale word string, if allocated */
|
||
if(hw->help_dialog.srch.localeWordStr!=hw->help_dialog.srch.normWordStr)
|
||
{
|
||
XtFree(hw->help_dialog.srch.localeWordStr);
|
||
hw->help_dialog.srch.localeWordStr = NULL;
|
||
}
|
||
}
|
||
|
||
/* don't free the iconv context...may apply to the next volume */
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void SearchTopic()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Get a single topic and search for the search word in it
|
||
*
|
||
*****************************************************************************/
|
||
static void SearchTopic(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry curFile,
|
||
_DtHelpGlobSrchVol * curVol,
|
||
char * srchWord,
|
||
int srchWordLen,
|
||
int numSearches)
|
||
{
|
||
#if 0
|
||
int i;
|
||
|
||
/* if the volume is not open; don't continue */
|
||
if ( NULL == curVol->volHandle )
|
||
return; /* RETURN */
|
||
|
||
if ( NULL == curVol->indexEntriesList )
|
||
_CEVolumeTopicList(curVol->volHandle,&curVol->indexEntriesList);
|
||
if ( NULL == curVol->volHandle || NULL == curVol->indexEntriesList )
|
||
{
|
||
curVol->topicSearchInProgress = False;
|
||
curVol->topicSearchDone = True;
|
||
curVol->indexSearchInProgress = True;
|
||
if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
|
||
return; /* RETURN */
|
||
}
|
||
|
||
curVol->topicSearchInProgress = True;
|
||
|
||
|
||
/* search the topics */
|
||
/* note that indexEntriesList[0] is correct; ptr is incremented */
|
||
/* we can increment the pointer because we don't own this memory;
|
||
the open volume does. */
|
||
for (i=0;
|
||
i < numSearches && NULL != curVol->indexEntriesList[0];
|
||
i++, curVol->indexEntriesList++ )
|
||
{
|
||
char * topicTitle = NULL;
|
||
Boolean validTopic;
|
||
|
||
validTopic = _DtHelpGetTopicTitle( curVol->volHandle,
|
||
curVol->indexEntriesList[0],&topicTitle);
|
||
if(validTopic)
|
||
{
|
||
/* look for a hit and process if there was one */
|
||
if (SearchForPattern(topicTitle,srchWord,srchWordLen) == True)
|
||
{
|
||
HitListAddFound(curFile, curVol->indexEntriesList[0], True, NULL);
|
||
}
|
||
}
|
||
|
||
/* clean up and advance to next topic */
|
||
XtFree(topicTitle);
|
||
curVol->searchedCnt++;
|
||
} /* for all topics to search */
|
||
#endif
|
||
|
||
if ( NULL == curVol->indexEntriesList /* no topics queried */
|
||
|| NULL == curVol->indexEntriesList[0] ) /* no more topics available */
|
||
{
|
||
/* hand off to next stage */
|
||
curVol->indexEntriesList = NULL;
|
||
curVol->topicSearchInProgress = False;
|
||
curVol->topicSearchDone = True;
|
||
curVol->indexSearchInProgress = True;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void SearchIndex()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: void
|
||
*
|
||
* Purpose: Get a single Index and search for the search word in it
|
||
*
|
||
* Commentary: There are two strings for each index entry.
|
||
* One string is the straight text in
|
||
* the codeset of the volume. The
|
||
* other string is a XmString that
|
||
* has a font tag that will allow
|
||
* it to be displayed in the
|
||
* correct codeset.
|
||
*
|
||
* Preconditions: This code requires that the volume to be search
|
||
* has already been opened [OpenVolForSearch()],
|
||
* that the locale of the volume has been installed,
|
||
* and that the search word is in the same code
|
||
* set as the volume and has been converted to
|
||
* upper case.
|
||
*
|
||
*****************************************************************************/
|
||
static void SearchIndex(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry curFile,
|
||
_DtHelpGlobSrchVol * curVol,
|
||
_DtHelpCeIconvContext iconvContext,
|
||
char * srchWord,
|
||
int srchWordLen,
|
||
int numSearches)
|
||
{
|
||
int i;
|
||
char * indexEntry = NULL;
|
||
size_t entryLen = 100; /* starting size */
|
||
Arg args[5];
|
||
|
||
/* if the volume is not open; don't continue */
|
||
if ( NULL == curVol->volHandle )
|
||
return; /* RETURN */
|
||
|
||
/* get the XmStrings of the entries */
|
||
if ( NULL == curVol->indexXmStrsList )
|
||
{
|
||
XmFontList fontList = NULL;
|
||
Boolean mod = False;
|
||
int numEntries = 0;
|
||
|
||
/* get results font list */
|
||
XtSetArg(args[0], XmNfontList, &fontList);
|
||
XtGetValues(hw->help_dialog.srch.resultList,args,1);
|
||
|
||
#if 1
|
||
/* Don't need to copy, _DtHelpFormatVolumeTitle copies
|
||
* before modifying.
|
||
*/
|
||
|
||
/* work with copy, because FontListAppendEntry() destroys input FL */
|
||
fontList = XmFontListCopy(fontList);
|
||
#endif
|
||
|
||
/* get the entries */
|
||
_DtHelpFormatIndexEntries(hw->help_dialog.help.pDisplayArea,
|
||
curVol->volHandle,&numEntries, &curVol->indexXmStrsList,
|
||
&fontList, &mod);
|
||
|
||
/* install the changed list */
|
||
if (mod)
|
||
{
|
||
XtSetArg(args[0], XmNfontList, fontList);
|
||
XtSetValues(hw->help_dialog.srch.resultList,args,1);
|
||
if (fontList) XmFontListFree(fontList);
|
||
}
|
||
}
|
||
|
||
/* get the pure strings for searching */
|
||
if ( NULL == curVol->indexEntriesList )
|
||
{
|
||
/* recall that the array and strings pointed to by
|
||
the indexEntriesList is owned by the open volume */
|
||
_DtHelpCeGetKeywordList(curVol->volHandle,&curVol->indexEntriesList);
|
||
|
||
/* and re-init curIndexXmStr */
|
||
curVol->curIndexXmStr = curVol->indexXmStrsList;
|
||
}
|
||
|
||
if ( NULL == curVol->volHandle
|
||
|| NULL == curVol->indexEntriesList
|
||
|| NULL == curVol->indexXmStrsList )
|
||
{
|
||
curVol->indexSearchInProgress = False;
|
||
curVol->indexSearchDone = True;
|
||
curVol->searchCompleted = True;
|
||
if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
|
||
return; /* RETURN */
|
||
}
|
||
|
||
curVol->indexSearchInProgress = True;
|
||
|
||
/* alloc memory for index processing */
|
||
indexEntry = XtMalloc(sizeof(char)*(entryLen+1));
|
||
if (NULL == indexEntry) return; /* RETURN */
|
||
|
||
/* get a index entry */
|
||
for (i=0;
|
||
i < numSearches && NULL != curVol->indexEntriesList[0];
|
||
i++, curVol->indexEntriesList++, curVol->curIndexXmStr++ )
|
||
{
|
||
/* prevent overflow of buffer */
|
||
if (strlen(curVol->indexEntriesList[0]) > entryLen)
|
||
{
|
||
entryLen = strlen(curVol->indexEntriesList[0]) + 50;
|
||
indexEntry = XtRealloc(indexEntry,entryLen+1);
|
||
if (NULL == indexEntry) break; /* BREAK */
|
||
}
|
||
indexEntry[0] = EOS; /* init to empty string */
|
||
|
||
/* look for a hit and process if there was one */
|
||
/* if srchWord is NULL, all entries are hits */
|
||
/* copy, and possible iconv, the index string into the */
|
||
/* the codeset of srchWord (the application) */
|
||
if ( NULL == srchWord
|
||
|| ( _DtHelpCeIconvStr(iconvContext,curVol->indexEntriesList[0],
|
||
&indexEntry, &entryLen,indexEntry,entryLen) == 0
|
||
&& SearchForPattern(indexEntry, srchWord, srchWordLen) == True ) )
|
||
{
|
||
_DtHelpGlobSrchHit * hit;
|
||
char * * topicIdList;
|
||
|
||
HitListAddFound ( curFile, curVol->curIndexXmStr[0],
|
||
curVol->indexEntriesList[0], True, &hit);
|
||
|
||
/* topicIdList is set but not allocated & need not be freed */
|
||
hit->topicCnt = _DtHelpCeFindKeyword(curVol->volHandle,
|
||
hit->indexEntry,&topicIdList);
|
||
}
|
||
|
||
/* clean up and advance to next topic */
|
||
curVol->searchedCnt++;
|
||
}
|
||
|
||
if ( NULL == curVol->indexEntriesList /*no topics queried*/
|
||
|| NULL == curVol->indexEntriesList[0] )/*no more index entries avail*/
|
||
{
|
||
/* hand off to next stage */
|
||
curVol->indexEntriesList = NULL; /* init */
|
||
curVol->curIndexXmStr = curVol->indexXmStrsList; /* re-init */
|
||
curVol->indexSearchInProgress = False;
|
||
curVol->indexSearchDone = True;
|
||
curVol->searchCompleted = True;
|
||
}
|
||
|
||
XtFree(indexEntry);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void SearchVolume()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: do the search operation
|
||
* This routine does incremental search--it searchs
|
||
* a little, then returns to allow further processing.
|
||
* It is called whenever Xt detects no other events.
|
||
*
|
||
*****************************************************************************/
|
||
static void SearchVolume(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry curFile,
|
||
_DtHelpGlobSrchVol * curVol,
|
||
int numSearches)
|
||
{
|
||
XmString labelString;
|
||
Arg args[10];
|
||
char buf[50];
|
||
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
/* Process according to state */
|
||
if ( curVol->nothingDone )
|
||
{
|
||
curVol->nothingDone = False;
|
||
curVol->topicSearchInProgress = True;
|
||
|
||
/* Update the search status string */
|
||
sprintf(buf,(char *)_DTGETMESSAGE(GSSET,18,
|
||
"Searching... Volumes remaining: %d"),
|
||
hw->help_dialog.srch.volLeftCnt);
|
||
labelString = XmStringCreateLocalized(buf);
|
||
XtSetArg(args[0],XmNlabelString,labelString);
|
||
XtSetValues (hw->help_dialog.srch.statusLabel, args, 1);
|
||
XmStringFree(labelString);
|
||
|
||
XmUpdateDisplay((Widget) hw->help_dialog.srch.statusLabel);
|
||
}
|
||
|
||
OpenVolForSearch(hw,curFile->fullFilePath,curVol);
|
||
|
||
if ( curVol->topicSearchInProgress )
|
||
{
|
||
SearchTopic(hw, curFile,curVol,hw->help_dialog.srch.localeWordStr,
|
||
hw->help_dialog.srch.wordFieldLen, numSearches);
|
||
}
|
||
|
||
/* NOTE: because this isn't an "else if", we could potentially
|
||
search for 2*numSearches; but I know that I've disabled the
|
||
topic search. Furthermore, my code depends upon the possibility
|
||
of searching an entire volume in one call to the routine, if
|
||
desired, and having an else if would break that.
|
||
*/
|
||
if ( curVol->indexSearchInProgress )
|
||
{
|
||
char * srchWord;
|
||
srchWord = hw->help_dialog.srch.localeWordStr;
|
||
/* FullIndex search indicated by a null search word string */
|
||
if (hw->help_dialog.srch.fullIndex) srchWord = NULL;
|
||
SearchIndex(hw, curFile, curVol, hw->help_dialog.srch.iconv3Context,
|
||
srchWord, hw->help_dialog.srch.wordFieldLen, numSearches);
|
||
}
|
||
|
||
/* If search was completed, update dependent stuff */
|
||
if (curVol->searchCompleted)
|
||
{
|
||
/* handle completion */
|
||
CloseVolAfterSearch(hw,curVol);
|
||
curVol->indexEntriesList = NULL; /* mem not owned by GlobSrch */
|
||
if (hw->help_dialog.srch.fullIndex)
|
||
curVol->gatheredFullIndex = True;
|
||
hw->help_dialog.srch.volLeftCnt--;
|
||
if (hw->help_dialog.srch.volLeftCnt < 0)
|
||
hw->help_dialog.srch.volLeftCnt = 0;
|
||
}
|
||
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void SearchFile()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: do the search operation on an entire file
|
||
* It searches the entire file at once
|
||
* and displays the results in the list.
|
||
*
|
||
*****************************************************************************/
|
||
static void SearchFile(
|
||
DtHelpDialogWidget hw,
|
||
_DtHelpFileEntry file)
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
|
||
/* get volume info, adding if necessary */
|
||
vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
/* (T,T,F): enable search, enable display, any volume */
|
||
if (NULL == vol) AddVolInfoToFile(file, True, True, False);
|
||
vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
if (NULL == vol) return;
|
||
|
||
/* conduct search of entire volume in one call */
|
||
hw->help_dialog.srch.volLeftCnt = 1;
|
||
vol->searchThisVolume = True;
|
||
vol->showVolInList = True;
|
||
vol->zeroHitsOk = True;
|
||
SearchVolume(hw,file,vol,INT_MAX);
|
||
|
||
/* update status */
|
||
StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);/*FIX: False*/
|
||
|
||
/* update the list to show the volume */
|
||
AdjustPositionValues(file,0,1,True);
|
||
/* True: do insert new item */
|
||
VolNameDisplay(hw,file,True);
|
||
|
||
if (vol->showHitsWithVol)
|
||
{
|
||
VolHitsDisplay(hw,file);
|
||
/* False: don't insert new item */
|
||
VolNameDisplay(hw,file,False);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void DoBackgroundSearchWP(
|
||
* XtPointer clientData)
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: do the search operation in the background
|
||
* This routine does incremental search--it searchs
|
||
* a little, then returns to allow further processing.
|
||
* It is called whenever Xt detects no other events.
|
||
*
|
||
*****************************************************************************/
|
||
static Boolean DoBackgroundSearchWP(
|
||
XtPointer clientData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
_DtHelpFileEntry curFile;
|
||
_DtHelpGlobSrchVol * curVol = NULL;
|
||
|
||
if ( 0 == hw->help_dialog.srch.volLeftCnt )
|
||
goto searchComplete; /* GOTO: done! */
|
||
|
||
/* get file to work on */
|
||
curFile = hw->help_dialog.srch.curSrchVol;
|
||
if ( NULL == curFile )
|
||
{
|
||
curFile = GetNextSearchFileAndDisplayCompleted(
|
||
hw, hw->help_dialog.srch.volListHead, NULL);
|
||
if ( NULL == curFile ) goto searchComplete; /* GOTO: done */
|
||
hw->help_dialog.srch.curSrchVol = curFile;
|
||
} /* if no current file */
|
||
|
||
/* get volume info */
|
||
curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
|
||
|
||
#define NUM_SEARCHES_PER_CALL 30
|
||
SearchVolume(hw,curFile,curVol,NUM_SEARCHES_PER_CALL);
|
||
|
||
/* If search was completed, update dependent stuff */
|
||
if (curVol->searchCompleted)
|
||
{
|
||
/* update the search results list */
|
||
/* True: adjust count beginning with this file */
|
||
if (curVol->hitCnt > 0 || curVol->zeroHitsOk)
|
||
{
|
||
/* record that a hit found */
|
||
if ( curVol->hitCnt > 0
|
||
|| ( curVol->zeroHitsOk
|
||
&& _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
|
||
hw->help_dialog.srch.hitsFound = True;
|
||
|
||
/* update the list to show the volume */
|
||
AdjustPositionValues(curFile,0,1,True);
|
||
ResultsListUpdate(hw,curFile);
|
||
|
||
/* update the list to show the hits? */
|
||
if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
|
||
{
|
||
VolHitsDisplay(hw,curFile);
|
||
/* False: don't insert new item */
|
||
VolNameDisplay(hw,curFile,False);
|
||
}
|
||
XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
|
||
}
|
||
|
||
/* prepare for next search */
|
||
hw->help_dialog.srch.curSrchVol =
|
||
GetNextSearchFileAndDisplayCompleted(hw,NULL,curFile);
|
||
|
||
} /* if search completed */
|
||
|
||
/* return */
|
||
if ( hw->help_dialog.srch.volLeftCnt > 0
|
||
|| False == curVol->searchCompleted )
|
||
return False; /* RETURN: False ==> continue processing */
|
||
|
||
/* Do this when no more files are left to search */
|
||
searchComplete:
|
||
{
|
||
XmPushButtonCallbackStruct status;
|
||
|
||
/* zero search data before stopping */
|
||
hw->help_dialog.srch.volLeftCnt = 0; /* just in case */
|
||
hw->help_dialog.srch.curSrchVol = NULL; /* just in case */
|
||
|
||
/* generate a fake event to reset the dialog */
|
||
status.reason = XmCR_ACTIVATE;
|
||
status.event = NULL;
|
||
status.click_count = 1;
|
||
StopSearchCB(hw->help_dialog.srch.actionBtn,
|
||
(XtPointer)hw,(XtPointer)&status);
|
||
|
||
return True; /* RETURN: True ==> stop processing */
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void StartSearchCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Create a new user bookmark
|
||
*
|
||
* Warning: This CB is also used by the volume selection buttons
|
||
* to activate a search when they are selected. The routine
|
||
* cannot rely upon the w or callData params. The clientData
|
||
* will always be the help widget.
|
||
*****************************************************************************/
|
||
static void StartSearchCB(
|
||
Widget w, /* don't use */
|
||
XtPointer clientData,
|
||
XtPointer callData) /* don't use */
|
||
{
|
||
char *srchWord = NULL;
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
XtAppContext appCntx;
|
||
int n;
|
||
Arg args[5];
|
||
|
||
/* set state of start button correctly */
|
||
UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
|
||
|
||
/* if help content isn't a volume, it has no index */
|
||
if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
|
||
&& hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC )
|
||
return; /* RETURN */
|
||
|
||
/* retrieve the name */
|
||
srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
|
||
|
||
/* test for empty (also emtpy spaces) and only process if not emtpy */
|
||
_DtHelpCeCompressSpace(srchWord);
|
||
if ( (strlen(srchWord) > (size_t) 0 || hw->help_dialog.srch.fullIndex)
|
||
&& hw->help_dialog.srch.workProcId == 0)
|
||
/* test on workProcId prevents multiple activations due to
|
||
race condition on desensitizing the start button */
|
||
{
|
||
_DtHelpTurnOnHourGlass(XtParent(hw));
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
/*XtSetSensitive (hw->help_dialog.srch.actionBtn,False);*/
|
||
XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False);
|
||
XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,False);
|
||
XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,False);
|
||
XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
|
||
|
||
/* 9/26/94: these two XtSetArgs (and following SetValues) cause a core dump
|
||
for the SunOS 5.3 optimized executable. It isn't a problem for the
|
||
non-optimized or debuggable versions or any versions on AIX 3.2 or
|
||
HP-UX 9.05. */
|
||
#if !defined(sun)
|
||
n = 0;
|
||
XtSetArg(args[n],XmNeditable,False); n++;
|
||
XtSetArg(args[n],XmNcursorPositionVisible,False); n++;
|
||
XtSetValues (hw->help_dialog.srch.wordField, args, n);
|
||
#endif
|
||
XmUpdateDisplay(hw->help_dialog.srch.srchForm);
|
||
|
||
/* process the source selection and retain in widget srchWord memory */
|
||
PrepSearchSourceData(hw, srchWord);
|
||
|
||
/* activate search thread; do it even with a 0 count, because the
|
||
process reactivates the dialog after search is completed */
|
||
appCntx = XtWidgetToApplicationContext((Widget) hw);
|
||
hw->help_dialog.srch.workProcId =
|
||
XtAppAddWorkProc(appCntx,DoBackgroundSearchWP, (XtPointer) hw);
|
||
|
||
hw->help_dialog.srch.searchInProgress = True;
|
||
|
||
/* don't free srchWord */
|
||
|
||
/* turn on "Stop" label */
|
||
UpdateActionButtonLabel(hw,NULL,False);
|
||
|
||
_DtHelpTurnOffHourGlass(XtParent(hw));
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
}
|
||
else
|
||
{
|
||
if ( strlen(srchWord) == 0 )
|
||
StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
|
||
XtFree(srchWord);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void StartSelectedVolumeSearchCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Begin a search on the selected volume
|
||
*
|
||
*****************************************************************************/
|
||
static void StartSelectedVolumeSearchCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
_DtHelpFileEntry file;
|
||
String srchWord;
|
||
Boolean noSelectedFiles = True;
|
||
|
||
/* if not full index search */
|
||
if (hw->help_dialog.srch.fullIndex == False)
|
||
{
|
||
/* get the current contents of the search word field */
|
||
srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
|
||
|
||
/* test the word ; False=dontUpdate--do this in PrepSearchSourceData() */
|
||
if ( CheckSearchWord(hw,srchWord,False) == True )
|
||
{ /* word has changed since last search; do a whole new search */
|
||
StartSearchCB(NULL,(XtPointer) hw, NULL);
|
||
return; /* RETURN */
|
||
}
|
||
|
||
/* if the text field is empty, do nothing */
|
||
if ( strlen(hw->help_dialog.srch.normWordStr) == 0 )
|
||
return; /* RETURN */
|
||
}
|
||
|
||
/* set this to true to counteract False if no hits */
|
||
hw->help_dialog.srch.hitsFound = True;
|
||
|
||
/* Word is the same, just the selection has changed. */
|
||
/* Determine which one was selected or deselected */
|
||
for ( file = hw->help_dialog.srch.volListHead;
|
||
NULL != file;
|
||
file = _DtHelpFileListGetNext(NULL,file) )
|
||
{
|
||
_DtHelpGlobSrchVol * vol;
|
||
vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
if (NULL == vol) continue;
|
||
|
||
/* update flag */
|
||
if (file->fileSelected) noSelectedFiles = False;
|
||
|
||
/* test for contradictory flags; fileSelected reflects dialog list */
|
||
if (file->fileSelected != vol->showVolInList)
|
||
{
|
||
/* file has been deselected */
|
||
if (False == file->fileSelected)
|
||
{
|
||
if (vol->showVolInList)
|
||
{
|
||
/* update list: delete hits, topics, and volume title */
|
||
if (vol->hitsDisplayed) VolHitsUndisplay(hw,file);
|
||
|
||
/* delete hits first, then volume */
|
||
XmListDeletePos(
|
||
hw->help_dialog.srch.resultList,vol->startPosition);
|
||
AdjustPositionValues(file, 0, -1, True);
|
||
vol->showVolInList = False;
|
||
vol->searchThisVolume = False;
|
||
}
|
||
}
|
||
else /* file has been selected */
|
||
{
|
||
SearchFile(hw,file);
|
||
} /* if file de/selected */
|
||
} /* if contradictory flags */
|
||
} /* for all volumes */
|
||
|
||
/* update state */
|
||
if (noSelectedFiles) StatusLabelUpdate(hw,NO_VOL_STATUS,True,0);
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void UpdateSearchStartStatusCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: update the status of the search status button
|
||
* Routine is called whenever text is changed in the search
|
||
* word field.
|
||
*
|
||
*****************************************************************************/
|
||
static void UpdateSearchStartStatusCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
char *srchWord = NULL;
|
||
/*XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) callData;*/
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
Boolean newState;
|
||
|
||
/* retrieve the name */
|
||
srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
|
||
|
||
/* test for empty (also emtpy spaces) */
|
||
_DtHelpCeCompressSpace(srchWord);
|
||
|
||
/* FIX: change the locale from the volume locale back to the system
|
||
locale temporarily (if not already in that locale) */
|
||
_DtHelpCeUpperCase(srchWord);
|
||
|
||
/* only sensitize if working on a help volume and word is not emtpy
|
||
or not needed */
|
||
newState = True;
|
||
if ( ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
|
||
&& hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC)
|
||
|| ( strlen(srchWord) == (size_t) 0
|
||
&& hw->help_dialog.srch.fullIndex == False))
|
||
newState = False;
|
||
XtSetSensitive (hw->help_dialog.srch.actionBtn,newState);
|
||
|
||
/* if word has changed from word of previous search, change to Start */
|
||
UpdateActionButtonLabel(hw,srchWord,True);
|
||
|
||
XtFree(srchWord);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void StopSearchCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Stop the search
|
||
*
|
||
*****************************************************************************/
|
||
static void StopSearchCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
int n;
|
||
Arg args[10];
|
||
Boolean cur;
|
||
|
||
/* stop the search thread */
|
||
if(hw->help_dialog.srch.workProcId != 0)
|
||
XtRemoveWorkProc(hw->help_dialog.srch.workProcId);
|
||
hw->help_dialog.srch.workProcId = 0;
|
||
|
||
hw->help_dialog.srch.searchInProgress = False;
|
||
|
||
/* update statuses */
|
||
#ifdef OLD_WAY
|
||
XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,
|
||
hw->help_dialog.srch.curVolRadBtnSens);
|
||
#else
|
||
XtSetSensitive (hw->help_dialog.srch.curVolRadBtn, TRUE);
|
||
#endif
|
||
|
||
XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,True);
|
||
XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,True);
|
||
n = 0;
|
||
XtSetArg(args[n],XmNeditable,True); n++;
|
||
XtSetArg(args[n],XmNcursorPositionVisible,True); n++;
|
||
XtSetValues (hw->help_dialog.srch.wordField, args, n);
|
||
|
||
/* update select btn status; only when selected and dialog closed */
|
||
XtSetArg(args[0],XmNset,&cur);
|
||
XtGetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
|
||
XtSetSensitive(hw->help_dialog.srch.selectBtn,
|
||
cur && ( NULL == hw->help_dialog.srch.selectionDlg
|
||
|| !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
|
||
|
||
/* set the action button label appropriately */
|
||
UpdateActionButtonLabel(hw,hw->help_dialog.srch.normWordStr,True);
|
||
|
||
/* post message of results */
|
||
StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void ActionButtonCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Act upon the action
|
||
*
|
||
*****************************************************************************/
|
||
static void ActionButtonCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
|
||
if ( hw->help_dialog.srch.searchInProgress == False )
|
||
StartSearchCB(w,clientData,callData);
|
||
else
|
||
StopSearchCB(w,clientData,callData);
|
||
}
|
||
|
||
|
||
|
||
#ifdef not_used
|
||
/*****************************************************************************
|
||
* Function: void GotoResultCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Goto a result topic
|
||
*
|
||
*****************************************************************************/
|
||
static void GotoResultCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
char * helpFile = NULL;
|
||
int * topicPosList=NULL;
|
||
int topicPosition;
|
||
Boolean status;
|
||
int i;
|
||
|
||
/* Determine the item selected and find that item in our list */
|
||
status = XmListGetSelectedPos(hw->help_dialog.srch.resultList, &topicPosList,&i);
|
||
|
||
/* if true, an item selected */
|
||
if (status && topicPosList)
|
||
{
|
||
_DtHelpGlobSrchHit * entry = NULL;
|
||
_DtHelpFileEntry file = NULL;
|
||
char * locationId = NULL;
|
||
topicPosition = topicPosList[0] - 1; /* convert to 0 based */
|
||
XtFree((String)topicPosList);
|
||
|
||
/* Get the entry */
|
||
HitListGetNth(hw->help_dialog.srch.volListHead,
|
||
topicPosition,&file,&entry,&locationId,&helpFile);
|
||
|
||
/* jump to selected location */
|
||
XtFree(hw->help_dialog.display.locationId);
|
||
hw->help_dialog.display.locationId = XtNewString(locationId);
|
||
XtFree(hw->help_dialog.display.helpVolume);
|
||
hw->help_dialog.display.helpVolume = XtNewString(helpFile);
|
||
hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
|
||
hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
|
||
|
||
_DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
|
||
}
|
||
else
|
||
{
|
||
if (topicPosList) XtFree((String)topicPosList);
|
||
|
||
/* FIX: Put up a message to suggest selecting an item first */
|
||
/* Don't close the dialog */
|
||
}
|
||
}
|
||
#endif /* not_used */
|
||
|
||
#if 0 /* save--used in code commented out elsewhere in this file */
|
||
|
||
/*****************************************************************************
|
||
* Function: void CloseHelpCB()
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Close and destroy the help widget
|
||
*
|
||
*****************************************************************************/
|
||
static void CloseHelpCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
XtUnmanageChild(w);
|
||
XtDestroyWidget(w);
|
||
}
|
||
#endif /* save--used in code commented out elsewhere in this file */
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void GotoLocation(hw,helpVolume,location)
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Goto a topic by opening a new help dialog window
|
||
*
|
||
*****************************************************************************/
|
||
static void GotoLocation(
|
||
DtHelpDialogWidget hw,
|
||
char * helpVolume,
|
||
char * locationId)
|
||
{
|
||
#if 0 /* don't delete...useful as reference */
|
||
{
|
||
Widget helpDlg;
|
||
Arg args[15];
|
||
int n;
|
||
|
||
/* This opens a new help window on the topic */
|
||
n = 0;
|
||
XtSetArg( args[n], XmNtitle, "Help" ); n++;
|
||
XtSetArg( args[n], DtNhelpType, DtHELP_TYPE_TOPIC ); n++;
|
||
XtSetArg( args[n], DtNlocationId, locationId ); n++;
|
||
XtSetArg( args[n], DtNhelpVolume, helpVolume ); n++;
|
||
helpDlg = DtCreateHelpDialog(XtParent(hw),"mainHelpDialog",args,n);
|
||
XtAddCallback(helpDlg,DtNcloseCallback,CloseHelpCB,helpDlg);
|
||
XtManageChild(helpDlg);
|
||
}
|
||
#else
|
||
{
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
|
||
/* jump to selected location in same window */
|
||
XtFree(hw->help_dialog.display.locationId);
|
||
hw->help_dialog.display.locationId = XtNewString(locationId);
|
||
XtFree(hw->help_dialog.display.helpVolume);
|
||
hw->help_dialog.display.helpVolume = XtNewString(helpVolume);
|
||
hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
|
||
hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
|
||
|
||
_DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
|
||
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void ProcessResultSelectionCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Process user selection of an item in the result List.
|
||
*
|
||
*****************************************************************************/
|
||
static void ProcessResultSelectionCB(
|
||
Widget w,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
int * topicPosList = NULL;
|
||
int topicPosition;
|
||
Boolean status;
|
||
int n;
|
||
|
||
/* Determine the item selected and find that item in our list */
|
||
status = XmListGetSelectedPos(
|
||
hw->help_dialog.srch.resultList, &topicPosList,&n);
|
||
|
||
/* if true, an item selected */
|
||
if (status && topicPosList)
|
||
{
|
||
_DtHelpFileEntry file = NULL;
|
||
_DtHelpGlobSrchHit * hit = NULL;
|
||
char * locationId = NULL;
|
||
char * helpFile = NULL;
|
||
|
||
topicPosition = topicPosList[0]; /* 1 based */
|
||
XtFree((String)topicPosList);
|
||
|
||
/* Get the entry */
|
||
if ( HitListGetNth(hw->help_dialog.srch.volListHead,
|
||
topicPosition,&file,&hit,&locationId,&helpFile) == 0 )
|
||
{
|
||
_DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
|
||
/* deactivate it */
|
||
XmListDeselectPos(hw->help_dialog.srch.resultList,topicPosition);
|
||
|
||
/* was a volume item selected? */
|
||
if ( NULL == hit )
|
||
{
|
||
_DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
|
||
if (vol->hitCnt > 0)
|
||
{
|
||
if (False == vol->hitsDisplayed)
|
||
{
|
||
VolHitsDisplay(hw,file); /* toggle state */
|
||
}
|
||
else
|
||
{
|
||
VolHitsUndisplay(hw,file);
|
||
vol->showHitsWithVol = False;
|
||
}
|
||
/* update the volume label to show the state */
|
||
/* False: don't insert hw item */
|
||
VolNameDisplay(hw,file,False);
|
||
}
|
||
/* else don't otherwise handle a 0-hits volume */
|
||
}
|
||
/* was an expandable index selected */
|
||
else if (NULL == locationId && hit->topicCnt > 1)
|
||
{
|
||
int topicCnt = 0;
|
||
|
||
/* if we're turning them on, build a list */
|
||
if (False == hit->topicsDisplayed)
|
||
{
|
||
topicCnt = HitTopicsDisplay(hw,file,hit,topicPosition+1);
|
||
}
|
||
else
|
||
{
|
||
topicCnt = - HitTopicsUndisplay(hw,file,hit,topicPosition+1);
|
||
hit->showTopicsWithHit = False;
|
||
}
|
||
/* update the hit label to show the state; False--don't insert */
|
||
HitNameDisplay(hw,file,hit,topicPosition,False);
|
||
|
||
/* add to all the following */
|
||
if (topicCnt != 0)
|
||
{
|
||
/* adjust count beginning with next file with hits */
|
||
AdjustPositionValues(file, 0, topicCnt, True);
|
||
}
|
||
}
|
||
/* a location or index with one topic was selected */
|
||
else
|
||
{
|
||
/* if a single click, goto the location */
|
||
if (hit->topicCnt == 1)
|
||
{
|
||
if ( HitLoadTopics(hw,file,hit) == 0 )
|
||
{
|
||
GotoLocation(hw, file->fullFilePath, hit->topicIdList[0]);
|
||
HitFree(hit,False); /*release what was loaded 3 lines up*/
|
||
}
|
||
else
|
||
{ /* volume couldn't be opened or some other error */
|
||
/* FIX: error message */
|
||
}
|
||
} /* if an index with a single topic */
|
||
else
|
||
{ /* a location from an open multi-topic index entry */
|
||
GotoLocation(hw, file->fullFilePath, locationId);
|
||
}
|
||
} /* else index with one topic or topic was selected */
|
||
|
||
/* finish up processing a selection */
|
||
_DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
|
||
|
||
} /* got the nth item */
|
||
}
|
||
else /* could not find the nth hit */
|
||
{
|
||
if (topicPosList) XtFree((String)topicPosList);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void CloseVolSelDialogCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Resets the selection dialog variable to NULL
|
||
*
|
||
*****************************************************************************/
|
||
static void CloseVolSelDialogCB(
|
||
Widget widget,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
|
||
/* unmanage & destroy the dialog zero the variable */
|
||
if ( hw->help_dialog.srch.selectionDlg
|
||
&& XtIsManaged(hw->help_dialog.srch.selectionDlg) )
|
||
XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
|
||
|
||
/* start a search to be sure we got all changes; FIX: need this??? */
|
||
/*StartSearchCB(NULL,hw,NULL);*/
|
||
XtSetSensitive(hw->help_dialog.srch.selectBtn,True);
|
||
|
||
/* change focus */
|
||
if (hw->help_dialog.srch.hitsFound == True)
|
||
XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
|
||
else
|
||
XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void CreateVolSelDialog(
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Creates selection dialog to chose volumes
|
||
*
|
||
*****************************************************************************/
|
||
static void CreateVolSelDialog(
|
||
DtHelpDialogWidget hw)
|
||
{
|
||
Widget selDlg;
|
||
_DtHelpFileDlgChildren dlgChld;
|
||
Atom wm_delete_window;
|
||
Arg args[5];
|
||
|
||
/* desensitize the button */
|
||
XtSetSensitive(hw->help_dialog.srch.selectBtn,False);
|
||
|
||
/* only create one */
|
||
if ( NULL != hw->help_dialog.srch.selectionDlg )
|
||
{
|
||
XtManageChild(hw->help_dialog.srch.selectionDlg);
|
||
return;
|
||
}
|
||
|
||
/* open the modal dialog and let user select the volumes */
|
||
selDlg = _DtHelpFileListCreateSelectionDialog(
|
||
hw, hw->help_dialog.srch.srchForm, False,
|
||
(char *)_DTGETMESSAGE (GSSET, 40,
|
||
"Help - Search Volume Selection"),
|
||
&hw->help_dialog.srch.volTitlesFontList,
|
||
hw->help_dialog.srch.volListHead, &dlgChld);
|
||
hw->help_dialog.srch.selectionDlg = selDlg;
|
||
|
||
XtAddCallback(dlgChld.closeBtn, XmNactivateCallback,
|
||
CloseVolSelDialogCB,(XtPointer)hw);
|
||
XtAddCallback(dlgChld.form, XmNunmapCallback,
|
||
CloseVolSelDialogCB,(XtPointer)hw);
|
||
|
||
/* set the default response to a WM_DELETE_WINDOW message
|
||
to no response instead of UNMAP. */
|
||
XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
|
||
XtSetValues(dlgChld.shell, args, 1);
|
||
wm_delete_window = XmInternAtom(XtDisplay(dlgChld.shell),
|
||
"WM_DELETE_WINDOW", FALSE);
|
||
XmAddWMProtocolCallback(dlgChld.shell,wm_delete_window,
|
||
(XtCallbackProc)CloseVolSelDialogCB, (XtPointer)hw);
|
||
|
||
XtAddCallback(dlgChld.list, XmNsingleSelectionCallback,
|
||
StartSelectedVolumeSearchCB, (XtPointer) hw);
|
||
XtAddCallback(dlgChld.list, XmNmultipleSelectionCallback,
|
||
StartSelectedVolumeSearchCB, (XtPointer) hw);
|
||
XtAddCallback(dlgChld.list, XmNextendedSelectionCallback,
|
||
StartSelectedVolumeSearchCB, (XtPointer) hw);
|
||
XtAddCallback(dlgChld.list, XmNdefaultActionCallback,
|
||
StartSelectedVolumeSearchCB, (XtPointer) hw);
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void OpenSelectDialogCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Process user selection of the select button
|
||
*
|
||
*****************************************************************************/
|
||
static void OpenSelectDialogCB(
|
||
Widget widget,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
|
||
/* only build the list of files if it hasn't been done */
|
||
if ( False == hw->help_dialog.srch.volScanDone
|
||
|| NULL == hw->help_dialog.srch.volListHead)
|
||
{
|
||
/* Add on the Vol info; (T,T,T) search, display, selected only */
|
||
VolListBuild(hw,True,True,True);
|
||
}
|
||
|
||
/* FIX: the modal behaviour doesn't seem to be set; is it desired/needed? */
|
||
/* don't need to worry about having open twice, since
|
||
the dialog is always opened in modal mode from the search dialog */
|
||
/* open the dialog and let user select the volumes */
|
||
CreateVolSelDialog(hw);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void UpdateSearchVolumesCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Process user selection of a button in the Volumes Radio box
|
||
*
|
||
*****************************************************************************/
|
||
static void UpdateSearchVolumesCB(
|
||
Widget widget,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
Arg args[5];
|
||
|
||
|
||
/* change focus */
|
||
|
||
if (hw->help_dialog.srch.hitsFound == True)
|
||
XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
|
||
else
|
||
XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
|
||
|
||
|
||
|
||
/* if turning off the button, just reinforce the current settings.
|
||
This message occurs when an on button is hit again. */
|
||
if ( False == status->set )
|
||
{
|
||
XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
|
||
XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
|
||
XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
|
||
XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
|
||
XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
|
||
XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
|
||
return;
|
||
}
|
||
|
||
/*** if work when something is turned on; ignore the off messages
|
||
except when the button is the selected volumes button; we
|
||
want to catch every click on that button */
|
||
if ( XmCR_VALUE_CHANGED == status->reason
|
||
&& True == status->set
|
||
&& NULL != status->event ) /* event is NULL for 1st of the two calls
|
||
to this routine that are made when a
|
||
button is pressed. */
|
||
{
|
||
/*** now update the sources value according to button selected ***/
|
||
hw->help_dialog.srch.volLeftCnt = 0; /* change invalidates prior search */
|
||
UpdateActionButtonLabel(hw,NULL,True);
|
||
|
||
XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
|
||
XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
|
||
XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
|
||
XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
|
||
XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
|
||
XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
|
||
|
||
/*** selected volumes button activated ***/
|
||
if (hw->help_dialog.srch.selVolRadBtn == widget)
|
||
{
|
||
/* set state */
|
||
hw->help_dialog.srch.srchSources = _DtHelpGlobSrchSelectedVolumes;
|
||
|
||
/* only build the list of files if it hasn't been done */
|
||
if ( False == hw->help_dialog.srch.volScanDone
|
||
|| NULL == hw->help_dialog.srch.volListHead)
|
||
{
|
||
/* Add on the Vol info; (T,T,T) search, display, selected only */
|
||
VolListBuild(hw,True,True,True);
|
||
}
|
||
|
||
/* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
|
||
/* (T,T,T,T): enable search, enable display,
|
||
zero hits ok, only for selected volumes */
|
||
/* Set these here so that the CountSelectedVolumes() works right */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
|
||
|
||
/* count all volumes selected, including those already searched */
|
||
if (CountSelectedVolumes(hw->help_dialog.srch.volListHead,True)==0)
|
||
{
|
||
StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
|
||
DeleteListContents(&hw->help_dialog.srch);
|
||
CreateVolSelDialog(hw);
|
||
/* NOTE: don't start search here, start it from the callback */
|
||
/* set state of start button correctly */
|
||
UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
|
||
}
|
||
else /* volumes already selected; just display */
|
||
{
|
||
hw->help_dialog.srch.hitsFound = False; /*DBG*/
|
||
StartSearchCB(NULL,(XtPointer) hw, NULL);
|
||
}
|
||
} /* if selected volumes button */
|
||
|
||
/*** all volumes button ***/
|
||
else if (hw->help_dialog.srch.allVolRadBtn == widget)
|
||
{
|
||
/* close the selection dialog, if open */
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
|
||
|
||
/* set sources state */
|
||
hw->help_dialog.srch.srchSources = _DtHelpGlobSrchAllVolumes;
|
||
hw->help_dialog.srch.hitsFound = False; /*DBG*/
|
||
StartSearchCB(NULL,(XtPointer) hw, NULL);
|
||
}
|
||
/*** current volume button ***/
|
||
else
|
||
{
|
||
/* close the selection dialog, if open */
|
||
if (hw->help_dialog.srch.selectionDlg)
|
||
XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
|
||
|
||
/* set sources state */
|
||
hw->help_dialog.srch.srchSources = _DtHelpGlobSrchCurVolume;
|
||
hw->help_dialog.srch.hitsFound = False; /*DBG*/
|
||
StartSearchCB(NULL,(XtPointer) hw, NULL);
|
||
}
|
||
|
||
/* update the Select... button status */
|
||
/* do this last, so that while searching for volumes (VolListBuild),
|
||
the button is not active. */
|
||
XtSetSensitive(hw->help_dialog.srch.selectBtn,
|
||
(hw->help_dialog.srch.selVolRadBtn == widget)
|
||
&& ( NULL == hw->help_dialog.srch.selectionDlg
|
||
|| !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
|
||
|
||
} /* if value changed */
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void UpdateIndexSelectionCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Process user selection of a button in the Entries Radio box
|
||
*
|
||
*****************************************************************************/
|
||
static void UpdateIndexSelectionCB(
|
||
Widget widget,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
Boolean containsState;
|
||
int n;
|
||
Arg args[5];
|
||
|
||
/* change focus */
|
||
if (hw->help_dialog.srch.hitsFound == True)
|
||
XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
|
||
else
|
||
XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
|
||
|
||
|
||
/* if turning off the button, just reinforce the current settings.
|
||
This message occurs when an on button is hit again. */
|
||
if ( False == status->set )
|
||
{
|
||
containsState = (hw->help_dialog.srch.containsRadBtn == widget);
|
||
XtSetArg(args[0], XmNset, !containsState);
|
||
XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
|
||
XtSetArg(args[0], XmNset, containsState);
|
||
XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
|
||
return;
|
||
}
|
||
|
||
/*** if work when something is turned on; ignore the off messages
|
||
except when the button is the selected volumes button; we
|
||
want to catch every click on that button */
|
||
if ( XmCR_VALUE_CHANGED == status->reason
|
||
&& True == status->set
|
||
&& NULL != status->event ) /* event is NULL for 1st of the two calls
|
||
to this routine that are made when a
|
||
button is pressed. */
|
||
{
|
||
/* if search in progress, stop it */
|
||
if(hw->help_dialog.srch.searchInProgress||hw->help_dialog.srch.workProcId)
|
||
{
|
||
XmPushButtonCallbackStruct status;
|
||
|
||
/* generate a fake event to reset the dialog */
|
||
status.reason = XmCR_ACTIVATE;
|
||
status.event = NULL;
|
||
status.click_count = 1;
|
||
StopSearchCB(hw->help_dialog.srch.actionBtn,
|
||
(XtPointer)hw,(XtPointer)&status);
|
||
}
|
||
|
||
containsState = (hw->help_dialog.srch.containsRadBtn == widget);
|
||
XtSetArg(args[0], XmNset, !containsState);
|
||
XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
|
||
XtSetArg(args[0], XmNset, containsState);
|
||
XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
|
||
|
||
/* sensitize/desensitize the Contains text field */
|
||
XtSetSensitive(hw->help_dialog.srch.wordField,containsState);
|
||
n=0;
|
||
XtSetArg(args[n],XmNeditable,containsState); n++;
|
||
XtSetArg(args[n],XmNcursorPositionVisible,containsState); n++;
|
||
XtSetValues(hw->help_dialog.srch.wordField,args,n);
|
||
|
||
/* set widget status here; do this way bec. srchFullIndex is a bit flag */
|
||
hw->help_dialog.srch.fullIndex = (containsState ? False : True); /*flag*/
|
||
|
||
/* set state of start button correctly */
|
||
UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
|
||
|
||
if (containsState)
|
||
{ /* if changing to "Containing" */
|
||
/* change focus to the search word */
|
||
XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
|
||
/* user will need to hit CR to initiate search */
|
||
}
|
||
else
|
||
{ /* if changing to full index */
|
||
/* indicate that no contains word is valid by deleting it */
|
||
/* FIX: I'm concerned that normWordStr & localeWordStr aren't in synch */
|
||
XtFree(hw->help_dialog.srch.normWordStr);
|
||
hw->help_dialog.srch.normWordStr = NULL;
|
||
/* search full index */
|
||
StartSearchCB(NULL,(XtPointer) hw, NULL);
|
||
}
|
||
|
||
/* and search to update results to the new state */
|
||
} /* if value changed */
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void ContainsDisarmCB(Widget w,
|
||
* XtPointer clientData,
|
||
* XtPointer callData);
|
||
*
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: Void.
|
||
*
|
||
* Purpose: Process disarm of the contains radio button
|
||
*
|
||
*****************************************************************************/
|
||
static void ContainsDisarmCB(
|
||
Widget widget,
|
||
XtPointer clientData,
|
||
XtPointer callData)
|
||
{
|
||
XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
|
||
|
||
/* Force focus to the word field if set. */
|
||
if (True==status->set)
|
||
XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: CreateCurVolBtnLabel()
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value: True or False if current vol has an index
|
||
*
|
||
* Purpose: Creates the label for the current volume button
|
||
*
|
||
*****************************************************************************/
|
||
static Boolean CreateCurVolBtnLabel(
|
||
DtHelpDialogWidget hw,
|
||
Boolean * out_curVolAvailable,
|
||
XmString * out_labelString,
|
||
char * * out_mnemonic)
|
||
{
|
||
char * path = NULL;
|
||
char * preTitle;
|
||
char * postTitle;
|
||
XmString volTitleString = NULL;
|
||
XmString preTitleString = NULL;
|
||
XmString postTitleString = NULL;
|
||
XmString newTitle;
|
||
XmString labelString;
|
||
char * mnemonic;
|
||
Boolean curVolAvail;
|
||
int n;
|
||
Arg args[5];
|
||
|
||
#if 0 /* DBG */
|
||
if (out_curVolAvailable)
|
||
*out_curVolAvailable = False;
|
||
if (out_labelString)
|
||
*out_labelString = XmStringCreateLocalized("dum");
|
||
if (out_mnemonic)
|
||
*out_mnemonic = "";
|
||
return False;
|
||
#endif
|
||
|
||
/* if help content is a volume, get the title */
|
||
if ( hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC )
|
||
{
|
||
/* determine whether a current volume index is available */
|
||
curVolAvail = VolumeHasIndexP(
|
||
hw->help_dialog.srch.srchSources,
|
||
hw->help_dialog.display.helpType,
|
||
hw->help_dialog.display.helpVolume);
|
||
|
||
/* change False to True to search home dir; may want this */
|
||
path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
|
||
_DtHelpFileSuffixList,False,R_OK);
|
||
|
||
/* title needs to be an XmString to use volume's font */
|
||
if (path)
|
||
{
|
||
XmFontList fontList = NULL;
|
||
Boolean mod = False;
|
||
|
||
/* get the font list of the btn */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNfontList, &fontList); n++;
|
||
XtGetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
|
||
|
||
#if defined(DONT_USE_CDExc22774)
|
||
/* copy the list before passing it in for modification */
|
||
fontList = XmFontListCopy (fontList);
|
||
#endif
|
||
|
||
GetVolumeInfoCB(hw->help_dialog.help.pDisplayArea,path,
|
||
NULL,&volTitleString,NULL,NULL,NULL,&fontList,&mod);
|
||
|
||
/* if font list was changed, install it */
|
||
if (mod)
|
||
{
|
||
/* set the font list of the btn */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNfontList, fontList); n++;
|
||
XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
|
||
if (fontList) XmFontListFree (fontList);
|
||
}
|
||
}
|
||
|
||
/* just in case */
|
||
if (NULL == volTitleString)
|
||
volTitleString = XmStringCreateLocalized(
|
||
hw->help_dialog.display.helpVolume);
|
||
} /* if helpType == TOPIC */
|
||
else
|
||
{ /* if helpType != TOPIC */
|
||
curVolAvail = False;
|
||
switch (hw->help_dialog.display.helpType)
|
||
{
|
||
case DtHELP_TYPE_STRING:
|
||
case DtHELP_TYPE_DYNAMIC_STRING:
|
||
volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 32,"Help Message")));
|
||
break;
|
||
case DtHELP_TYPE_FILE:
|
||
volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 33,"Help File")));
|
||
break;
|
||
case DtHELP_TYPE_MAN_PAGE:
|
||
volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 34,"Manual Page")));
|
||
break;
|
||
default:
|
||
volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 35,"Unknown Format")));
|
||
break;
|
||
} /* switch on helpType */
|
||
} /* if helpType != TOPIC */
|
||
|
||
/* record path in the widget */
|
||
XtFree(hw->help_dialog.srch.curVolPath);
|
||
hw->help_dialog.srch.curVolPath = path;
|
||
|
||
/* create title */
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 3,"Current")));
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 4,"r"));*/
|
||
mnemonic = 0;
|
||
|
||
/* append volume name to title */
|
||
preTitle = (char *)_DTGETMESSAGE(GSSET, 60," (");
|
||
preTitleString = XmStringCreateLocalized(preTitle);
|
||
postTitle = (char *)_DTGETMESSAGE(GSSET, 61,")");
|
||
postTitleString = XmStringCreateLocalized(postTitle);
|
||
|
||
newTitle = XmStringConcat(labelString,preTitleString);
|
||
XmStringFree(labelString);
|
||
XmStringFree(preTitleString);
|
||
labelString = newTitle;
|
||
|
||
newTitle = XmStringConcat(labelString,volTitleString);
|
||
XmStringFree(labelString);
|
||
XmStringFree(volTitleString);
|
||
labelString = newTitle;
|
||
|
||
newTitle = XmStringConcat(labelString,postTitleString);
|
||
XmStringFree(labelString);
|
||
XmStringFree(postTitleString);
|
||
labelString = newTitle;
|
||
|
||
/* set the out values */
|
||
if (out_curVolAvailable) *out_curVolAvailable = curVolAvail;
|
||
if (out_mnemonic) *out_mnemonic = mnemonic;
|
||
if (out_labelString) *out_labelString = labelString;
|
||
else XmStringFree(labelString);
|
||
|
||
return curVolAvail;
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void CreateGlobSrchDialog()
|
||
*
|
||
*
|
||
* Parameters:
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Purpose: Creates and displays an instance of the search dialog.
|
||
*
|
||
*****************************************************************************/
|
||
static void CreateGlobSrchDialog(
|
||
Widget nw,
|
||
char * searchWord)
|
||
{
|
||
Widget parentForm;
|
||
Widget separator;
|
||
Widget srchShell;
|
||
/* Widget topWidget; */
|
||
Widget volumesFrame;
|
||
Widget volumesForm;
|
||
Widget showFrame;
|
||
Widget showForm;
|
||
Widget frameTitle;
|
||
XmString labelString;
|
||
/* char * mnemonic; */
|
||
Dimension widgetHeight;
|
||
Dimension widgetBorderHeight;
|
||
char * title;
|
||
DtHelpListStruct *pHelpInfo;
|
||
Atom wm_delete_window;
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) nw ;
|
||
XtTranslations btnTransTable;
|
||
/* XtTranslations listTransTable; */
|
||
/* XtTranslations mgrTransTable; */
|
||
Boolean curVolAvailable;
|
||
int n;
|
||
Arg args[20];
|
||
|
||
/* get state of the volume */
|
||
curVolAvailable = VolumeHasIndexP (
|
||
hw->help_dialog.srch.srchSources,
|
||
hw->help_dialog.display.helpType,
|
||
hw->help_dialog.display.helpVolume);
|
||
|
||
/* Set up the translations table stuff */
|
||
btnTransTable = XtParseTranslationTable(defaultBtnTranslations);
|
||
/* listTransTable = XtParseTranslationTable(defaultListTranslations); */
|
||
/* mgrTransTable = XtParseTranslationTable(defaultMgrTranslations); */
|
||
|
||
/* Create the shell used for the dialog. */
|
||
title = XtNewString(((char *)_DTGETMESSAGE(GSSET,1,"Help - Index Search")));
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtitle, title); n++;
|
||
XtSetArg (args[n], XmNallowShellResize, True); n++;
|
||
srchShell = XmCreateDialogShell((Widget) hw, "searchShell", args, n);
|
||
XtFree(title);
|
||
|
||
/* Set the useAsyncGeo on the shell */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
|
||
XtSetValues (XtParent(srchShell), args, n); /* parent is new's shell */
|
||
#if 0
|
||
/* Adjust the decorations for the dialog shell of the dialog */
|
||
n = 0;
|
||
XtSetArg(args[n], XmNmwmFunctions, 0); n++;
|
||
XtSetArg (args[n], XmNmwmDecorations,
|
||
MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
|
||
XtSetValues (srchShell, args, n);
|
||
#endif
|
||
|
||
/* Grab the window mgr close and install a close dialog
|
||
callback when closed from dialog WM menu; this prevents
|
||
the dialog from closing the host application. */
|
||
wm_delete_window = XmInternAtom(XtDisplay(srchShell),
|
||
"WM_DELETE_WINDOW", FALSE);
|
||
XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
|
||
XmAddWMProtocolCallback(srchShell,wm_delete_window,
|
||
CloseSearchCB, (XtPointer)&hw->help_dialog.srch);
|
||
XtSetValues(srchShell, args, 1);
|
||
|
||
/* set the callback that positions the dialog when popped up */
|
||
XtAddCallback (srchShell, XmNpopupCallback,
|
||
(XtCallbackProc)_DtHelpMapCB, (XtPointer) XtParent(hw));
|
||
|
||
/*** Create the form used for the dialog. ***/
|
||
/* setting RESIZE_NONE is important to prevent the resultList from
|
||
dynamically resizing as items with various fonts are added and
|
||
deleted from it. */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNmarginWidth, 1); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 1); n++;
|
||
XtSetArg (args[n], XmNshadowThickness, 1); n++;
|
||
XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT); n++;
|
||
XtSetArg (args[n], XmNautoUnmanage, False); n++;
|
||
XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
|
||
parentForm = XmCreateForm (srchShell, "parentForm", args, n);
|
||
hw->help_dialog.srch.srchForm = parentForm;
|
||
|
||
/*==============================================================*/
|
||
/****** Create the volumes region ******/
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 5); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg (args[n], XmNmarginWidth, 5); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 2); n++;
|
||
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
|
||
volumesFrame = XmCreateFrame(parentForm, "volFrame", args, n);
|
||
XtManageChild (volumesFrame);
|
||
|
||
/* put form inside frame */
|
||
volumesForm = XmCreateForm (volumesFrame, "volumesForm", args, 0);
|
||
XtManageChild (volumesForm);
|
||
|
||
/* create the frame title */
|
||
labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,2, "Search")));
|
||
n = 0;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
|
||
XtSetArg (args[n], XmNtraversalOn, False); n++;
|
||
frameTitle = XmCreateLabelGadget(volumesFrame, "volFrameTitle", args, n);
|
||
XtManageChild (frameTitle);
|
||
XmStringFree (labelString);
|
||
|
||
/* create Current Volume radio button */
|
||
/* Use a dummy label until CreateCurVolBtnLabel can be used.
|
||
It refs the srchCurVolRadBtn widget and other things that need
|
||
initalizing. */
|
||
|
||
labelString = XmStringCreateLocalized (" ");
|
||
n = 0;
|
||
XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
|
||
XtSetArg (args[n], XmNset, TRUE); n++;
|
||
|
||
XtSetArg(args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 0); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 0); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
/* Attaching to form causes the hilite outline of the button to
|
||
stretch to the form edge when selected. But it also forces
|
||
the form to resize when the current volume title is too big
|
||
for the available space. */
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 10); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 0); n++;
|
||
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
|
||
XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.curVolRadBtn =
|
||
XmCreateToggleButtonGadget(volumesForm,"srchCurVolRadBtn",args,n);
|
||
XtAddCallback(hw->help_dialog.srch.curVolRadBtn,XmNvalueChangedCallback,
|
||
UpdateSearchVolumesCB, (XtPointer) hw);
|
||
/* ??? XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False); */
|
||
XtManageChild (hw->help_dialog.srch.curVolRadBtn);
|
||
XmStringFree (labelString);
|
||
|
||
/* create All Volumes radio button */
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 5,"All Volumes")));
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 7,"A"));*/
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
|
||
XtSetArg (args[n], XmNset, FALSE); n++;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 0); n++;
|
||
XtSetArg (args[n], XmNmarginWidth, 2); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.curVolRadBtn); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 1); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.allVolRadBtn =
|
||
XmCreateToggleButtonGadget(volumesForm,"srchAllVolRadBtn",args, n);
|
||
XtAddCallback(hw->help_dialog.srch.allVolRadBtn,XmNvalueChangedCallback,
|
||
UpdateSearchVolumesCB, (XtPointer) hw);
|
||
XtManageChild (hw->help_dialog.srch.allVolRadBtn);
|
||
XmStringFree (labelString);
|
||
|
||
/* create Selected Volumes radio button */
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 6,"Selected")));
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 9,"d"));*/
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 0); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 1); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 2); n++;
|
||
XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.selVolRadBtn =
|
||
XmCreateToggleButtonGadget(volumesForm,"srchSelVolRadBtn", args, n);
|
||
XtAddCallback(hw->help_dialog.srch.selVolRadBtn,XmNvalueChangedCallback,
|
||
UpdateSearchVolumesCB, (XtPointer) hw);
|
||
XtManageChild (hw->help_dialog.srch.selVolRadBtn);
|
||
XmStringFree (labelString);
|
||
|
||
|
||
/* Create Selected... button */
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 7,"Select Volumes...")));
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 0); n++;
|
||
XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 10); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 2); n++;
|
||
XtSetArg (args[n], XmNmarginTop, 0); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 3); n++;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
hw->help_dialog.srch.selectBtn =
|
||
XmCreatePushButtonGadget(volumesForm,"selectBtn", args, n);
|
||
XtAddCallback (hw->help_dialog.srch.selectBtn, XmNactivateCallback,
|
||
OpenSelectDialogCB, (XtPointer) hw);
|
||
XtManageChild (hw->help_dialog.srch.selectBtn);
|
||
XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
|
||
XmStringFree (labelString);
|
||
|
||
/****** Create the show selection region ******/
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, volumesFrame); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 5); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg (args[n], XmNmarginWidth, 5); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 2); n++;
|
||
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
|
||
showFrame = XmCreateFrame(parentForm, "showFrame", args, n);
|
||
XtManageChild (showFrame);
|
||
|
||
/* FIX: is this doing enough? Goal: CR activation of FullIndex */
|
||
/* Setup the proper translation on the title box widget */
|
||
/* XtAugmentTranslations(showFrame, mgrTransTable); */
|
||
|
||
/* put form inside frame */
|
||
showForm = XmCreateForm (showFrame, "showForm", args, 0);
|
||
XtManageChild (showForm);
|
||
|
||
/* create the frame title */
|
||
labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,8, "Show")));
|
||
n = 0;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNtraversalOn, False); n++;
|
||
XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
|
||
frameTitle = XmCreateLabelGadget(showFrame, "showFrameTitle", args, n);
|
||
XtManageChild (frameTitle);
|
||
XmStringFree (labelString);
|
||
|
||
/* create the All Entries button */
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 9,"Complete Index")));
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
|
||
XtSetArg (args[n], XmNset, True); n++;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 1); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 0); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 0); n++;
|
||
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
|
||
XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.fullIndexRadBtn =
|
||
XmCreateToggleButtonGadget(showForm,"srchFullIndexRadBtn",args,n);
|
||
XtAddCallback(hw->help_dialog.srch.fullIndexRadBtn,XmNvalueChangedCallback,
|
||
UpdateIndexSelectionCB, (XtPointer) hw);
|
||
XtManageChild (hw->help_dialog.srch.fullIndexRadBtn);
|
||
XmStringFree (labelString);
|
||
|
||
/* create Contains radio button */
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, 10,"Entries with:")));
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 16,"n"));*/
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
|
||
XtSetArg (args[n], XmNset, False); n++;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 1); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn);n++;
|
||
XtSetArg (args[n], XmNtopOffset, 1); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 4); n++;
|
||
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
|
||
XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.containsRadBtn =
|
||
XmCreateToggleButtonGadget(showForm,"srchContainsRadBtn",args,n);
|
||
XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNvalueChangedCallback,
|
||
UpdateIndexSelectionCB, (XtPointer) hw);
|
||
XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNdisarmCallback,
|
||
ContainsDisarmCB, (XtPointer) hw);
|
||
XtManageChild (hw->help_dialog.srch.containsRadBtn);
|
||
XmStringFree (labelString);
|
||
|
||
/* create the search name text field */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNvalue, ""); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 0); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNleftWidget,hw->help_dialog.srch.containsRadBtn); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 5); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 10); n++;
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 3); n++;
|
||
XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
|
||
XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
|
||
hw->help_dialog.srch.wordField =
|
||
XmCreateTextField (showForm,"srchWord",args, n);
|
||
XtSetSensitive(hw->help_dialog.srch.wordField,False);
|
||
XtManageChild (hw->help_dialog.srch.wordField);
|
||
/* Because the actionBtn is the default button on the form,
|
||
and it activates a search, we do not need to (nor do we want
|
||
to, since ActionButtonCB toggles between states) make it
|
||
a callback on activation of the text field */
|
||
XtAddCallback (hw->help_dialog.srch.wordField, XmNvalueChangedCallback,
|
||
UpdateSearchStartStatusCB, (XtPointer) hw);
|
||
|
||
/* Setup the proper translation on the text field widget */
|
||
XtAugmentTranslations(hw->help_dialog.srch.wordField, btnTransTable);
|
||
|
||
/* separator */
|
||
/* Create a separator search specs and result area */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, showFrame); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 10); n++;
|
||
separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
|
||
XtManageChild (separator);
|
||
|
||
/*==============================================================*/
|
||
/****** result related stuff *******/
|
||
/* Create result List Label */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, separator); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 10); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 10); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 10); n++;
|
||
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
|
||
hw->help_dialog.srch.statusLabel =
|
||
XmCreateLabelGadget (parentForm, "resultListLabel", args, n);
|
||
StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,True,0); /* installs a label */
|
||
XtManageChild (hw->help_dialog.srch.statusLabel);
|
||
|
||
/* Create our result topics scrolled list (not placed on form) */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
|
||
XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
|
||
XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
|
||
XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
|
||
hw->help_dialog.srch.resultList =
|
||
XmCreateScrolledList (parentForm, "resultList", args, n);
|
||
XtManageChild (hw->help_dialog.srch.resultList);
|
||
|
||
XtAddCallback (hw->help_dialog.srch.resultList, XmNsingleSelectionCallback,
|
||
ProcessResultSelectionCB, (XtPointer) hw);
|
||
XtAddCallback (hw->help_dialog.srch.resultList, XmNdefaultActionCallback,
|
||
ProcessResultSelectionCB, (XtPointer) hw);
|
||
|
||
/* Set the constraints on our scrolled list (place on form) */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.statusLabel); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNleftOffset, 10); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightOffset, 10); n++;
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 70); n++;
|
||
/* 70 is just a rough value that will be updated with a calculated
|
||
value below, after we know the height of the buttons */
|
||
XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
|
||
|
||
/* Create a separator between the buttons */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget,
|
||
XtParent (hw->help_dialog.srch.resultList)); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
|
||
XtManageChild (separator);
|
||
|
||
/***** search spec-related stuff *****/
|
||
/* Create start button (left of stop button)*/
|
||
_DtHelpProcessLock();
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, START_SEARCH_CAT,START_SEARCH_STR)));
|
||
_DtHelpProcessUnlock();
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, separator); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
/* L & R position set below */
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 5); n++;
|
||
/*XtSetArg (args[n], XmNmarginHeight, 3); n++;*/
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.actionBtn =
|
||
XmCreatePushButtonGadget(parentForm,"actionBtn", args, n);
|
||
XtAddCallback (hw->help_dialog.srch.actionBtn, XmNactivateCallback,
|
||
ActionButtonCB, (XtPointer) hw);
|
||
XtSetSensitive (hw->help_dialog.srch.actionBtn,False);
|
||
XtManageChild (hw->help_dialog.srch.actionBtn);
|
||
XmStringFree (labelString);
|
||
|
||
XtSetArg (args[0], XmNdefaultButton, hw->help_dialog.srch.actionBtn);
|
||
XtSetValues (parentForm, args, 1);
|
||
|
||
/* Build the Cancel Button */
|
||
_DtHelpProcessLock();
|
||
labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
|
||
(GSSET, CLOSE_BTN_CAT,CLOSE_BTN_STR)));
|
||
_DtHelpProcessUnlock();
|
||
/*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 25,CLOSE_BTN_MNEM));*/
|
||
n = 0;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
/* L & R position set below */
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, separator); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 5); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 3); n++;
|
||
XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.closeBtn =
|
||
XmCreatePushButtonGadget (parentForm, "srchCloseBtn", args, n);
|
||
|
||
XtAddCallback(hw->help_dialog.srch.closeBtn,
|
||
XmNactivateCallback, CloseSearchCB,(XtPointer) &hw->help_dialog.srch);
|
||
|
||
XtManageChild (hw->help_dialog.srch.closeBtn);
|
||
XmStringFree (labelString);
|
||
|
||
/* Build the Help button */
|
||
_DtHelpProcessLock();
|
||
labelString = XmStringCreateLocalized((char *)_DTGETMESSAGE
|
||
(GSSET, HELP_BTN_CAT,HELP_BTN_STR));
|
||
_DtHelpProcessUnlock();
|
||
/*mnemonic = (char *)_DTGETMESSAGE(GSSET, 27,HELP_BTN_MNEM);*/
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNlabelString, labelString); n++;
|
||
/* L & R position set below */
|
||
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
||
XtSetArg (args[n], XmNtopWidget, separator); n++;
|
||
XtSetArg (args[n], XmNtopOffset, 5); n++;
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, 5); n++;
|
||
XtSetArg (args[n], XmNmarginHeight, 3); n++;
|
||
XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
|
||
hw->help_dialog.srch.helpBtn =
|
||
XmCreatePushButtonGadget (parentForm, "srchHelpBtn", args, n);
|
||
XtManageChild (hw->help_dialog.srch.helpBtn);
|
||
XmStringFree (labelString);
|
||
|
||
pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexHelpBtn_STR,
|
||
(Widget) hw, &hw->help_dialog.help,
|
||
&hw->help_dialog.help.pHelpListHead);
|
||
XtAddCallback(hw->help_dialog.srch.helpBtn, XmNactivateCallback,
|
||
_DtHelpCB, (XtPointer) pHelpInfo);
|
||
|
||
/*==============================================================*/
|
||
/****** finishing touches *******/
|
||
/* set the Form cancel button (for KCancel) */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNcancelButton, hw->help_dialog.srch.closeBtn); n++;
|
||
XtSetValues (parentForm, args, n);
|
||
|
||
{ /* position buttons */
|
||
/* This code adds up the sizes of the buttons to go into
|
||
the bottom row and calculates the form position percentages.
|
||
All buttons are the same size, and are able to hold all
|
||
the strings that may be dynamically placed in them.
|
||
All buttons are 5% apart. */
|
||
/* This code is specifically written to handle 3 buttons
|
||
and assumes that the first 3 strings are to the ActionBtn */
|
||
#define NUMSTRS 5
|
||
Dimension maxWidth = 0;
|
||
Dimension borderWidth = 0;
|
||
Dimension sumWidth = 0;
|
||
float scale = 0.0;
|
||
float posList[11]; /* need 11 due to algorithm, which uses index 10 */
|
||
XmFontList fontList = NULL;
|
||
int i;
|
||
|
||
/* get the fontList for the button */
|
||
XtSetArg (args[0], XmNborderWidth, &borderWidth);
|
||
XtSetArg (args[1], XmNfontList, &fontList);
|
||
XtGetValues (hw->help_dialog.srch.actionBtn, args, 2);
|
||
|
||
#define BETBUTSPACE 5 /* pixels */
|
||
sumWidth = BETBUTSPACE; /* left side space */
|
||
posList[0] = (float) sumWidth;
|
||
for (i=0; i<NUMSTRS; i++)
|
||
{
|
||
XmString labelString;
|
||
Dimension width;
|
||
_DtHelpProcessLock();
|
||
s_GlobSrchDlgBtnStrs[i] = (char *) _DTGETMESSAGE(GSSET,
|
||
s_GlobSrchDlgBtnCatNum[i],s_GlobSrchDlgBtnStrs[i]);
|
||
labelString = XmStringCreateLocalized(s_GlobSrchDlgBtnStrs[i]);
|
||
_DtHelpProcessUnlock();
|
||
#define MARGINS 4 /* pixel margins: 2=L, 2=R */
|
||
width = XmStringWidth(fontList,labelString) + borderWidth + MARGINS;
|
||
if (i<=2) maxWidth = max(width,maxWidth);
|
||
if (i==2) width = maxWidth; /* 1st three labels go in 1st button */
|
||
if (i>=2) /* after scanning just labels, do buttons */
|
||
{
|
||
sumWidth += width;
|
||
posList[i*2+1] = (float) sumWidth;
|
||
sumWidth += BETBUTSPACE;
|
||
posList[i*2+2] = (float) sumWidth;
|
||
}
|
||
XmStringFree(labelString);
|
||
} /* for calcing widths */
|
||
|
||
/* scale pixels to percent */
|
||
scale = 100.0 / (float) sumWidth;
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNwidth, maxWidth); n++;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
|
||
XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[0]*scale)); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
|
||
XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[5]*scale)); n++;
|
||
XtSetValues (hw->help_dialog.srch.actionBtn, args, n);
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
|
||
XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[6]*scale)); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
|
||
XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[7]*scale)); n++;
|
||
XtSetValues (hw->help_dialog.srch.closeBtn, args, n);
|
||
|
||
n = 0;
|
||
XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
|
||
XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[8]*scale)); n++;
|
||
XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
|
||
XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[9]*scale)); n++;
|
||
XtSetValues (hw->help_dialog.srch.helpBtn, args, n);
|
||
} /* */
|
||
|
||
{ /* set the proper offset between the bottom of the results list
|
||
and the bottom of the form to maintain a constant sized
|
||
button bar. */
|
||
int offset = 0;
|
||
|
||
/* first calc offset of list to form bottom based on earlier sizes */
|
||
#define KNOWN_OFFSETS_BELOW_LIST 20 /* actually only 15, but 15 fails */
|
||
n = 0;
|
||
XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
|
||
XtSetArg(args[n], XmNheight, &widgetHeight); n++;
|
||
XtGetValues(hw->help_dialog.srch.actionBtn, args, n);
|
||
offset = widgetHeight + 2 * widgetBorderHeight;
|
||
XtGetValues(separator, args, n);
|
||
offset += widgetHeight + 2 * widgetBorderHeight;
|
||
XtGetValues(XtParent(hw->help_dialog.srch.resultList), args, 1);
|
||
offset += widgetBorderHeight;
|
||
offset += KNOWN_OFFSETS_BELOW_LIST;
|
||
|
||
/* then set the offset */
|
||
n = 0;
|
||
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
||
XtSetArg (args[n], XmNbottomOffset, offset); n++;
|
||
XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
|
||
}
|
||
|
||
/** force tabs to go to each widget and in right order **/
|
||
XtSetArg (args[0], XmNnavigationType, XmSTICKY_TAB_GROUP);
|
||
XtSetValues (hw->help_dialog.srch.curVolRadBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.allVolRadBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.selVolRadBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.selectBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.fullIndexRadBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.containsRadBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.wordField,args,1);
|
||
XtSetValues (hw->help_dialog.srch.resultList,args,1);
|
||
XtSetValues (hw->help_dialog.srch.actionBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.closeBtn,args,1);
|
||
XtSetValues (hw->help_dialog.srch.helpBtn,args,1);
|
||
|
||
/** put focus on the text field **/
|
||
XtSetArg (args[0], XmNinitialFocus, hw->help_dialog.srch.wordField);
|
||
XtSetValues (parentForm,args,1);
|
||
|
||
/* Add the proper help callback to the print dialog shell "F1" support */
|
||
pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexShell_STR,
|
||
(Widget) hw, &hw->help_dialog.help,
|
||
&hw->help_dialog.help.pHelpListHead);
|
||
XtAddCallback(parentForm, XmNhelpCallback,
|
||
_DtHelpCB, (XtPointer) pHelpInfo);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: updateDisplay()
|
||
*
|
||
*
|
||
* Parameters: hw: the help widget
|
||
*
|
||
* Return Value: 0
|
||
*
|
||
* Purpose: forces an update on index search dialog widgets
|
||
*
|
||
*****************************************************************************/
|
||
static int updateDisplay(
|
||
DtHelpDialogWidget hw)
|
||
{
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.actionBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.curVolRadBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.allVolRadBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.selVolRadBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.selectBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.fullIndexRadBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.containsRadBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.wordField);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.statusLabel);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.resultList);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.closeBtn);/*DBG*/
|
||
XmUpdateDisplay((Widget)hw->help_dialog.srch.helpBtn);/*DBG*/
|
||
XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));/*DBG*/
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void _DtHelpGlobSrchDisplayDialog()
|
||
*
|
||
*
|
||
* Parameters: parent Specifies the parent widget
|
||
* searchWord word to put into searchWord field
|
||
* remove this when integrated into DtHelp:
|
||
* curVolume volume considered the current volume
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Purpose: Setsup the proper data in the search dialog and
|
||
* displays an instance of the search dialog.
|
||
*
|
||
*****************************************************************************/
|
||
void _DtHelpGlobSrchDisplayDialog(
|
||
Widget w,
|
||
char * searchWord,
|
||
char * curVolume)
|
||
{
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
|
||
XmToggleButtonCallbackStruct status; /* the call data */
|
||
Widget sourceBtn; /* widget owning event */
|
||
#if 0
|
||
Dimension height;
|
||
Dimension width;
|
||
int n;
|
||
#endif
|
||
XmString labelString = NULL;
|
||
Arg args[10];
|
||
|
||
/* make the dialog itself */
|
||
if (NULL == hw->help_dialog.srch.srchForm)
|
||
{
|
||
CreateGlobSrchDialog((Widget) hw,searchWord);
|
||
|
||
/* create the button label */
|
||
CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
|
||
XtSetArg (args[0], XmNlabelString, labelString);
|
||
XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, 1);
|
||
XmStringFree (labelString);
|
||
|
||
/*** map widget and update display before doing any searching ***/
|
||
/* Make sure the Search Dialog is managed */
|
||
XtManageChild(hw->help_dialog.srch.srchForm);
|
||
XtMapWidget(hw->help_dialog.srch.srchForm);
|
||
|
||
/* set focus to contains word */
|
||
XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
|
||
|
||
/* force several updates to make sure it is fully displayed and
|
||
that height/width are correctly inited */
|
||
XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
|
||
XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
|
||
XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
|
||
|
||
/*** now update settings, which may also invoke a search ***/
|
||
/* set the cur vol btn sensitivity */
|
||
UpdateCurVolBtnSens(hw,True);
|
||
|
||
/* set default show index state */
|
||
/* set full index if current vol has an index, contains word if not */
|
||
if (hw->help_dialog.srch.curVolRadBtnSens) /* set in UpdateCurVolBtnSens*/
|
||
sourceBtn = hw->help_dialog.srch.fullIndexRadBtn;
|
||
else
|
||
sourceBtn = hw->help_dialog.srch.containsRadBtn;
|
||
|
||
/* set the show index state */
|
||
status.reason = XmCR_VALUE_CHANGED;
|
||
status.set = True;
|
||
status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
|
||
UpdateIndexSelectionCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
|
||
StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
|
||
|
||
updateDisplay(hw); /* DBG */
|
||
|
||
#if 0 /* 11/23/94 */
|
||
/** Set min size for the dialog **/
|
||
n = 0;
|
||
XtSetArg(args[n], XmNheight, &height); ++n;
|
||
XtSetArg(args[n], XmNwidth, &width); ++n;
|
||
XtGetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
|
||
n = 0;
|
||
XtSetArg(args[n], XmNminHeight, height - 200); ++n; /* 200: arbitrary */
|
||
XtSetArg(args[n], XmNminWidth, width); ++n;
|
||
XtSetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
|
||
#endif
|
||
}
|
||
else /* properly update dialog to support new word and cur vol */
|
||
{
|
||
/* fixup current volume, if need be */
|
||
_DtHelpGlobSrchUpdateCurVol((Widget)hw);
|
||
|
||
/* fixup search word, if need be */
|
||
if (NULL != searchWord)
|
||
{
|
||
String srchWord = XtNewString(searchWord);
|
||
/* srchWord is freed or used in CheckSearchWord() */
|
||
if (CheckSearchWord(hw,srchWord,True) == True)
|
||
{ /* words are different */
|
||
/* free all hit-related data and reset flags */
|
||
HitListFreeAllVolHits(hw,True); /*True=free everything*/
|
||
}
|
||
}
|
||
|
||
/* if its not managed, manage it */
|
||
if ( XtIsManaged(hw->help_dialog.srch.srchForm) == False )
|
||
{
|
||
/* manage and map the Search Dialog */
|
||
XtManageChild(hw->help_dialog.srch.srchForm);
|
||
XtMapWidget((Widget)hw->help_dialog.srch.srchForm);
|
||
|
||
/* see if the selection dialog was already open */
|
||
if ( hw->help_dialog.srch.selectionDlg
|
||
&& XtIsManaged(hw->help_dialog.srch.selectionDlg) )
|
||
{
|
||
XtManageChild(hw->help_dialog.srch.selectionDlg);
|
||
XtMapWidget(hw->help_dialog.srch.selectionDlg);
|
||
}
|
||
}
|
||
else /* if it is managed, bring it forward */
|
||
{
|
||
Widget parent = XtParent(hw->help_dialog.srch.srchForm);
|
||
XRaiseWindow ( XtDisplay(parent), XtWindow(parent) );
|
||
}
|
||
|
||
/* change focus */
|
||
|
||
if (hw->help_dialog.srch.hitsFound == True)
|
||
XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
|
||
else
|
||
XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
|
||
|
||
|
||
|
||
} /* end if create a new dialog */
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void _DtHelpGlobSrchUpdateCurVol()
|
||
*
|
||
* Parameters: new the help widget
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Purpose: Adjusts the current volume of the dialog
|
||
*
|
||
*****************************************************************************/
|
||
void _DtHelpGlobSrchUpdateCurVol(
|
||
Widget w)
|
||
{
|
||
String path;
|
||
DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
|
||
|
||
#if 1
|
||
if ( NULL == hw->help_dialog.srch.srchForm )
|
||
#else
|
||
if ( NULL == hw->help_dialog.srch.srchForm
|
||
|| XtIsManaged(hw->help_dialog.srch.srchForm) == False )
|
||
#endif
|
||
return; /* RETURN */
|
||
|
||
/* get full pathname for the volume */
|
||
path = NULL;
|
||
if (hw->help_dialog.display.helpVolume)
|
||
path = _DtHelpFileLocate(DtHelpVOLUME_TYPE,
|
||
/* FIX: will helpVolume have matching path? */
|
||
hw->help_dialog.display.helpVolume,
|
||
_DtHelpFileSuffixList,False,R_OK);
|
||
|
||
if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
|
||
&& hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC
|
||
&& NULL != path
|
||
&& NULL != hw->help_dialog.srch.curVolPath
|
||
&& _DtHelpFileIsSameP(path,hw->help_dialog.srch.curVolPath,
|
||
GetVolumeInfoCB, _DtHELP_FILE_NAME,
|
||
hw->help_dialog.help.pDisplayArea) )
|
||
{
|
||
/* leave current status as is */
|
||
XtFree(path);
|
||
return; /* RETURN */
|
||
}
|
||
|
||
|
||
/* a different current volume or change of topic */
|
||
{
|
||
XmString labelString;
|
||
Arg args[5];
|
||
|
||
/* if still searching previous cur volume, stop any search in progress */
|
||
if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
|
||
&& hw->help_dialog.srch.workProcId)
|
||
{
|
||
/* cancel the search */
|
||
StopSearchCB(NULL,(XtPointer) hw, NULL);
|
||
|
||
/* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
|
||
SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
|
||
|
||
/* zero search data */
|
||
hw->help_dialog.srch.volLeftCnt = 0;
|
||
hw->help_dialog.srch.curSrchVol = NULL;
|
||
|
||
/* assumption is, that even though the search was incomplete,
|
||
nothing bad will happen if we don't free the hit data,
|
||
and the search could resume where left off, if necessary. */
|
||
}
|
||
|
||
CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
|
||
XtSetArg(args[0],XmNlabelString,labelString);
|
||
XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
|
||
XmStringFree(labelString);
|
||
|
||
/* set the cur vol btn sensitivity */
|
||
UpdateCurVolBtnSens(hw,False);
|
||
|
||
/* set state of start button correctly */
|
||
UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
|
||
|
||
/* and search if needed */
|
||
if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources )
|
||
{
|
||
/* if to search a volume, start the search */
|
||
if (hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC)
|
||
StartSearchCB(NULL,(XtPointer) hw, NULL);
|
||
else /* if current isn't a volume, clear the display & update status */
|
||
{
|
||
DeleteListContents(&hw->help_dialog.srch);
|
||
StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void _DtHelpGlobSrchInitVars()
|
||
*
|
||
* Parameters: srch search main data structure
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Purpose: Init the contents of the control data structure
|
||
*
|
||
*****************************************************************************/
|
||
void _DtHelpGlobSrchInitVars(
|
||
_DtHelpGlobSearchStuff * srch)
|
||
{
|
||
/* set the font resource */
|
||
if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
|
||
srch->hitPrefixFont = XtNewString(srch->hitPrefixFont);
|
||
|
||
/* File Selection Dialog font list */
|
||
srch->volTitlesFontList = NULL;
|
||
|
||
/* Set our search dialog widgets to NULL */
|
||
srch->srchForm = NULL;
|
||
srch->actionBtn = NULL;
|
||
srch->curVolRadBtn = NULL;
|
||
srch->allVolRadBtn = NULL;
|
||
srch->selVolRadBtn = NULL;
|
||
srch->selectBtn = NULL;
|
||
srch->fullIndexRadBtn = NULL;
|
||
srch->containsRadBtn = NULL;
|
||
srch->wordField = NULL;
|
||
srch->statusLabel = NULL;
|
||
srch->resultList = NULL;
|
||
srch->gotoBtn = NULL;
|
||
srch->closeBtn = NULL;
|
||
srch->helpBtn = NULL;
|
||
srch->selectionDlg = NULL;
|
||
|
||
/* init dialog content variables */
|
||
srch->curVolPath = NULL;
|
||
srch->rawWordStr = NULL;
|
||
srch->normWordStr = NULL;
|
||
srch->localeWordStr = NULL;
|
||
srch->wordFieldFirstChar = 0;
|
||
srch->wordFieldLen = 0;
|
||
srch->statusLineUsage = 0; /* empty */
|
||
|
||
/* init srch processing variables */
|
||
srch->iconv3Codeset = NULL; /* iconv(3)-compatible code set of current locale */
|
||
srch->iconv3Context = NULL;
|
||
srch->srchSources = _DtHelpGlobSrchVolumeUndef; /* radio btn usage */
|
||
srch->curSrchVol = NULL; /* volume currently in search */
|
||
srch->hitsFontLoaded= False; /* is font loaded? */
|
||
srch->volScanDone = False; /* is the volume list complete? */
|
||
srch->fullIndex = False;
|
||
srch->hitsFound = False; /* state of search */
|
||
srch->readyToStart = False; /* state of search */
|
||
srch->searchInProgress= False; /* state of search */
|
||
srch->curVolRadBtnSens = False;
|
||
srch->volLeftCnt = 0;
|
||
srch->volListHead = NULL; /* info on search topics found */
|
||
srch->workProcId = 0;
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
* Function: void _DtHelpGlobSrchCleanAndClose()
|
||
*
|
||
* Parameters: srch search main data structure
|
||
* destroy flag to signal srch dialog should be destroyed
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Purpose: Free the contents of the control data structure
|
||
*
|
||
*****************************************************************************/
|
||
void _DtHelpGlobSrchCleanAndClose(
|
||
_DtHelpGlobSearchStuff * srch,
|
||
Boolean destroy)
|
||
{
|
||
/* close conversion context */
|
||
_DtHelpCeIconvClose(&srch->iconv3Context);
|
||
|
||
/* free the font list */
|
||
if(srch->volTitlesFontList)
|
||
{
|
||
XmFontListFree(srch->volTitlesFontList);
|
||
srch->volTitlesFontList = NULL;
|
||
}
|
||
|
||
/*
|
||
* Make sure CloseSearchCB does not try using an invalid
|
||
* widget id in its XtUnmanageChild and XtUnmapWidget calls.
|
||
*/
|
||
if (destroy)
|
||
srch->srchForm = NULL;
|
||
|
||
/* make dialog invisible; update sensitivities */
|
||
CloseSearchCB(NULL,(XtPointer)srch, NULL);
|
||
|
||
/* Destroy our index search dialog? */
|
||
if (destroy)
|
||
{
|
||
/* set the font resource */
|
||
if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
|
||
XtFree(srch->hitPrefixFont);
|
||
|
||
/*
|
||
* mark widgets as destroyed.
|
||
* The XtDestroyWidget that called me will have called the destroy
|
||
* callback of the widgets. So I don't have to do anything except
|
||
* make sure I know they are destroyed.
|
||
*/
|
||
srch->selectionDlg = NULL;
|
||
srch->srchForm = NULL;
|
||
srch->resultList = NULL;
|
||
|
||
/* free other data released to search dialog */
|
||
VolListFree(srch);
|
||
|
||
/* free the locale word string, if allocated
|
||
* (i.e. diff from normWordStr) */
|
||
if(srch->localeWordStr!=srch->normWordStr)
|
||
{
|
||
XtFree(srch->localeWordStr);
|
||
srch->localeWordStr=NULL;
|
||
}
|
||
XtFree(srch->normWordStr);
|
||
srch->normWordStr=NULL;
|
||
XtFree(srch->rawWordStr);
|
||
srch->rawWordStr=NULL;
|
||
XtFree(srch->curVolPath);
|
||
srch->curVolPath=NULL;
|
||
XtFree(srch->iconv3Codeset);
|
||
srch->iconv3Codeset = NULL;
|
||
}
|
||
}
|