GlobSearch.c 184 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: GlobSearch.c /main/21 1999/11/11 10:59:15 mgreess $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. **
  27. ** File: GlobSearch.c
  28. **
  29. ** Project: DtHelp Project
  30. **
  31. ** Description: Builds and displays an instance of a DtHelp GlobSearch
  32. ** Dialog.
  33. **
  34. ** (c) Copyright 1993, 1994 Hewlett-Packard Company
  35. ** (c) Copyright 1993, 1994 International Business Machines Corp.
  36. ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  37. ** (c) Copyright 1993, 1994 Novell, Inc.
  38. **
  39. **
  40. **
  41. ****************************************************************************
  42. ************************************<+>*************************************/
  43. #include <sys/param.h>
  44. #include <stdio.h>
  45. #include <string.h>
  46. #if defined(sun)
  47. #include <sys/utsname.h>
  48. #endif
  49. #include <limits.h>
  50. #include <stdlib.h> /* for MB_CUR_MAX */
  51. #include <unistd.h> /* R_OK */
  52. #include <locale.h> /* getlocale(), LOCALE_STATUS */
  53. #ifndef NO_REGEX
  54. # ifdef NO_REGCOMP
  55. # if defined(SVR4)
  56. # include <libgen.h> /* for regcmp, regex */
  57. # endif
  58. # else
  59. # include <regex.h> /* for regcomp, regexec */
  60. # endif
  61. #endif
  62. #include <Xm/Xm.h>
  63. #include <Xm/XmP.h>
  64. #include <Xm/Frame.h>
  65. #include <Xm/TextF.h>
  66. #include <Xm/Form.h>
  67. #include <Xm/LabelG.h>
  68. #include <Xm/ScrolledW.h>
  69. #include <Xm/SeparatoG.h>
  70. #include <Xm/PushBG.h>
  71. #include <Xm/List.h>
  72. #include <Xm/DialogS.h>
  73. #include <Xm/MwmUtil.h>
  74. #include <Xm/Protocols.h>
  75. #include <Xm/RowColumn.h>
  76. #include <Xm/SelectioB.h>
  77. #include <Xm/ToggleBG.h>
  78. #include <X11/Intrinsic.h>
  79. #include <X11/Shell.h>
  80. #include <X11/ShellP.h>
  81. #include <X11/Xutil.h>
  82. #include <X11/keysymdef.h>
  83. #include <Dt/Help.h>
  84. #include <Dt/HelpDialog.h>
  85. /*
  86. * private includes
  87. */
  88. #include "bufioI.h"
  89. #include "Access.h"
  90. #include "DisplayAreaP.h"
  91. #include "AccessI.h"
  92. #include "StringFuncsI.h"
  93. #include "DisplayAreaI.h"
  94. #include "HelpDialogP.h"
  95. #include "HelpDialogI.h"
  96. #include "HelpAccessI.h"
  97. #include "HelpUtilI.h"
  98. #include "HelposI.h"
  99. #include "HourGlassI.h"
  100. #include "GlobSearchI.h"
  101. #include "FileListUtilsI.h"
  102. #include "FileUtilsI.h"
  103. #include "FormatI.h"
  104. #include "HelpXlate.h"
  105. #include "VolSelectI.h"
  106. #include "Lock.h"
  107. /******** TYPES ***********/
  108. typedef enum {
  109. SEARCH_RESULTS_STATUS = 1,
  110. WORKING_STATUS = 2,
  111. SCANNING_STATUS = 3,
  112. BLANK_STATUS = 4,
  113. NO_VOL_STATUS = 5,
  114. FIRST_PROMPT_STATUS = 6
  115. } ResultsStatus;
  116. static Boolean VolumeHasIndexP (
  117. _DtHelpGlobSrchSources srchSource,
  118. int helpType,
  119. char * baseName);
  120. static void DeleteListContents(
  121. _DtHelpGlobSearchStuff * srch);
  122. static void StatusLabelUpdate(
  123. DtHelpDialogWidget hw,
  124. ResultsStatus status,
  125. Boolean forceUpdate,
  126. int intArg);
  127. static void ResultsListUpdate(
  128. DtHelpDialogWidget hw,
  129. _DtHelpFileEntry newFile);
  130. static void StopSearchCB(
  131. Widget w,
  132. XtPointer clientData,
  133. XtPointer callData);
  134. static void VolNameDisplay(
  135. DtHelpDialogWidget hw,
  136. _DtHelpFileEntry file,
  137. Boolean insertVol);
  138. static int VolHitsDisplay (
  139. DtHelpDialogWidget hw,
  140. _DtHelpFileEntry file);
  141. static void UpdateSearchVolumesCB(
  142. Widget widget,
  143. XtPointer clientData,
  144. XtPointer callData);
  145. static void UpdateSearchStartStatusCB(
  146. Widget w,
  147. XtPointer clientData,
  148. XtPointer callData);
  149. /********** CONSTANTS *************/
  150. #define DIR_SLASH '/'
  151. #define EOS '\0'
  152. /* message catalog set number for GlobSearch.c */
  153. #define GSSET 5
  154. #define DONT_SET (-1) /* used as third value of a Boolean */
  155. #define HIT_FONT_RES_NAME "*helpSearchMonoFont"
  156. #define HIT_FONT_RES_CLASS "*HelpSearchMonoFont"
  157. #define PREFIX_FONT_SPEC "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
  158. #define PREFIX_FONT_SPEC1 "-dt-application-bold-r-normal-*-*-140-*-*-m-*-iso8859-1"
  159. #define PREFIX_FONT_SPEC2 "-dt-interface user-bold-r-normal-m*-*-*-*-*-m-*-iso8859-1"
  160. #define PREFIX_FONT_SPEC3 "courb14" /* non CDE platforms */
  161. #define PREFIX_FONT_TAG "prefixFontTag"
  162. #define START_SEARCH_CAT s_GlobSrchDlgBtnCatNum[0]
  163. #define START_SEARCH_STR s_GlobSrchDlgBtnStrs[0]
  164. #define START_SEARCH_MNEM "S"
  165. #define CONT_SEARCH_CAT s_GlobSrchDlgBtnCatNum[1]
  166. #define CONT_SEARCH_STR s_GlobSrchDlgBtnStrs[1]
  167. #define CONT_SEARCH_MNEM "S"
  168. #define STOP_SEARCH_CAT s_GlobSrchDlgBtnCatNum[2]
  169. #define STOP_SEARCH_STR s_GlobSrchDlgBtnStrs[2]
  170. #define STOP_SEARCH_MNEM "S"
  171. #define CLOSE_BTN_CAT s_GlobSrchDlgBtnCatNum[3]
  172. #define CLOSE_BTN_STR s_GlobSrchDlgBtnStrs[3]
  173. #define CLOSE_BTN_MNEM "C"
  174. #define HELP_BTN_CAT s_GlobSrchDlgBtnCatNum[4]
  175. #define HELP_BTN_STR s_GlobSrchDlgBtnStrs[4]
  176. #define HELP_BTN_MNEM "H"
  177. /********** MACROS ************/
  178. #define max(a,b) ((a) > (b) ? (a) : (b))
  179. /********** Global VARIABLES ************/
  180. char _DtHelpDefaultSrchHitPrefixFont[] = PREFIX_FONT_SPEC;
  181. /********** VARIABLES ************/
  182. static const char *DirSlash = "/";
  183. static char * s_GlobSrchDlgBtnStrs[] = {
  184. "Start Search",
  185. "Continue Search",
  186. "Stop Search",
  187. "Close",
  188. "Help",
  189. NULL };
  190. /* catalog index numbers for the strings */
  191. static unsigned char s_GlobSrchDlgBtnCatNum[] = {
  192. 12, 13, 14, 15, 16 };
  193. static char * s_PrefixFontListTag = NULL;
  194. /* Setup for the Retrun Translation set for the text field */
  195. static char defaultBtnTranslations[] = "<Key>Return: Activate()";
  196. /* static char defaultListTranslations[] = "<Key>Return: Activate()"; */
  197. /* static char defaultMgrTranslations[] = "<Key>Return: ManagerParentActivate()"; */
  198. #if DOC
  199. /************************************************************************
  200. The startPosition and nextVolPosition values of the DtHelpGlobSrchVol
  201. structure are used as follows:
  202. startPosition: the position of the volume in the results list
  203. if hitCnt == 0, startPosition is the same value as the
  204. most recent volume with hits
  205. nextVolPosition: the position of the next volume in the results list
  206. if hitCnt == 0, nextVolPosition is the same value as the
  207. most recent volume with hits
  208. The value must be adjusted to include the positions
  209. occupied by hits and topics that are listed for the volume
  210. These variables are maintained using the AdjustPositionValues()
  211. routine, which increment/decrement the position values of all
  212. files after the start. So, when doing a search and display,
  213. as results are added to the list, the position values of volumes
  214. later in the list are always up to date.
  215. ************************************************************************/
  216. #endif
  217. /*======================================================================*/
  218. /*======================================================================*/
  219. /*======================================================================*/
  220. /*======================================================================*/
  221. /*****************************************************************************
  222. * Function: void MergeFontListIntoWidgetFonts()
  223. *
  224. * Parameters: widget a widget with a XmNfontList resource
  225. * newFontsList font list with fonts to merge into widget
  226. *
  227. * Return Value: void
  228. *
  229. * Purpose: Merges the fonts from the newFontsList into the fontlist
  230. * of the widget
  231. *
  232. *****************************************************************************/
  233. static void MergeFontListIntoWidgetFonts(
  234. Widget widget,
  235. XmFontList newFontsList)
  236. {
  237. XmFontList fontList = NULL;
  238. XmFontContext context;
  239. XmFontListEntry entry;
  240. Arg args[2];
  241. /* get current resultList fontlist */
  242. XtSetArg(args[0], XmNfontList, &fontList);
  243. XtGetValues(widget,args,1);
  244. if (NULL == fontList) return; /* RETURN on error */
  245. /* work with copy, because FontListAppendEntry() destroys input FL */
  246. fontList = XmFontListCopy(fontList);
  247. /* walk through the volTitlesFontList entries and add them in */
  248. XmFontListInitFontContext(&context,newFontsList);
  249. for ( entry = XmFontListNextEntry(context);
  250. NULL != entry;
  251. entry = XmFontListNextEntry(context) )
  252. {
  253. fontList = XmFontListAppendEntry(fontList,entry);
  254. }
  255. if (context) XmFontListFreeFontContext(context);
  256. /* install the changed list */
  257. XtSetArg(args[0], XmNfontList, fontList);
  258. XtSetValues(widget,args,1);
  259. if (fontList) XmFontListFree(fontList);
  260. }
  261. /*****************************************************************************
  262. * Function: void UpdateCurVolBtnSens()
  263. *
  264. * Parameters: new the help widget
  265. *
  266. * Return Value: True if cur vol has an index
  267. * False if not
  268. *
  269. * Purpose: Checks on current volume for an index
  270. and sets buttons appropriately
  271. *
  272. *****************************************************************************/
  273. static Boolean UpdateCurVolBtnSens(
  274. DtHelpDialogWidget hw,
  275. Boolean selectVolBtn)
  276. {
  277. XmToggleButtonCallbackStruct status; /* the call data */
  278. Boolean curState;
  279. Widget sourceBtn;
  280. /* set the cur vol btn sensitivity */
  281. /* set the volumes/show selection btns by generating a false event */
  282. status.reason = XmCR_VALUE_CHANGED;
  283. status.set = True;
  284. status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
  285. #if 0
  286. if ( VolumeHasIndexP (
  287. hw->help_dialog.srch.srchSources,
  288. hw->help_dialog.display.helpType,
  289. hw->help_dialog.display.helpVolume) )
  290. {
  291. curState = True;
  292. sourceBtn = hw->help_dialog.srch.curVolRadBtn;
  293. }
  294. else
  295. {
  296. curState = False;
  297. sourceBtn = hw->help_dialog.srch.allVolRadBtn;
  298. }
  299. /* ??? XtSetSensitive(hw->help_dialog.srch.curVolRadBtn,curState); */
  300. hw->help_dialog.srch.curVolRadBtnSens = curState;
  301. if (selectVolBtn) UpdateSearchVolumesCB(sourceBtn,hw,&status);
  302. #else
  303. curState = True;
  304. sourceBtn = hw->help_dialog.srch.curVolRadBtn;
  305. hw->help_dialog.srch.curVolRadBtnSens = curState;
  306. if (selectVolBtn)
  307. UpdateSearchVolumesCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
  308. #endif
  309. return curState;
  310. }
  311. /************************************************************************
  312. * Function: LoadPrefixFont()
  313. *
  314. * Loads the prefix font, if that hasn't yet occurred
  315. *
  316. ************************************************************************/
  317. static void LoadPrefixFont(
  318. DtHelpDialogWidget hw)
  319. {
  320. XmFontListEntry entry;
  321. XmFontList curFontList = NULL;
  322. XmFontList newFontList = NULL;
  323. char * fontSpec = NULL;
  324. Arg args[3];
  325. if (hw->help_dialog.srch.hitsFontLoaded) return; /* RETURN */
  326. /* this code is for when the resource is part of the widget */
  327. fontSpec = hw->help_dialog.srch.hitPrefixFont;
  328. /* get current font list */
  329. XtSetArg(args[0], XmNfontList, &curFontList);
  330. XtGetValues(hw->help_dialog.srch.resultList,args,1);
  331. /* work with copy, because FontListAppendEntry() destroys input FL */
  332. newFontList = XmFontListCopy(curFontList);
  333. /* load and merge fonts */
  334. s_PrefixFontListTag = PREFIX_FONT_TAG;
  335. entry = XmFontListEntryLoad(XtDisplay(hw->help_dialog.srch.srchForm),
  336. fontSpec,XmFONT_IS_FONT, s_PrefixFontListTag);
  337. newFontList = XmFontListAppendEntry(newFontList,entry);
  338. XmFontListEntryFree(&entry);
  339. /* install font */
  340. if (NULL == newFontList)
  341. { /* error case */
  342. s_PrefixFontListTag = XmFONTLIST_DEFAULT_TAG;
  343. }
  344. else
  345. {
  346. /* set new font list */
  347. XtSetArg(args[0], XmNfontList, newFontList);
  348. XtSetValues(hw->help_dialog.srch.resultList,args,1);
  349. if (newFontList) XmFontListFree(newFontList);
  350. }
  351. hw->help_dialog.srch.hitsFontLoaded = True;
  352. }
  353. /************************************************************************
  354. * Function: VolumeHasIndexP()
  355. *
  356. * Looks for the specified volume in the file system and
  357. * tests whether the volume has an index associated with it.
  358. *
  359. ************************************************************************/
  360. static Boolean VolumeHasIndexP (
  361. _DtHelpGlobSrchSources srchSource,
  362. int helpType,
  363. char * baseName)
  364. {
  365. char * path = NULL;
  366. _DtHelpVolumeHdl vol;
  367. int keyWordCount = 0;
  368. char **currentKeyList = NULL;
  369. /* if help content isn't a volume, it has no index */
  370. if ( _DtHelpGlobSrchCurVolume == srchSource
  371. && helpType != DtHELP_TYPE_TOPIC )
  372. return False; /* RETURN */
  373. /* try to locate file and its entry, if present */
  374. path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, baseName,
  375. _DtHelpFileSuffixList,False,R_OK);
  376. if (_DtHelpOpenVolume(path, &vol) == 0 )
  377. {
  378. /* Get the keyword list values */
  379. keyWordCount = _DtHelpCeGetKeywordList(vol,&(currentKeyList));
  380. /* no need to free currentKeyList because these are mgd by CE */
  381. _DtHelpCloseVolume(vol);
  382. }
  383. XtFree(path);
  384. return (keyWordCount > 0);
  385. }
  386. /************************************************************************
  387. * Function: GetVolumeInfoCB()
  388. *
  389. * Get the info on the volume and return it
  390. * Any of the 'out' parameters may be NULL.
  391. *
  392. ************************************************************************/
  393. static Boolean GetVolumeInfoCB (
  394. XtPointer pDisplayArea, /* in: display area in use */
  395. char * volumePath, /* in: full path to file */
  396. char ** ret_title, /* out: mallocd doc title text string */
  397. XmString * ret_titleXmStr,/* out: mallocd doc title string */
  398. char ** ret_docId, /* out: mallocd doc Id string */
  399. char ** ret_timeStamp, /* out: mallocd doc time string */
  400. int * ret_nameKey, /* out: hash value for fast discimination */
  401. XmFontList * io_fontList, /* io: fontList for title */
  402. Boolean * ret_mod) /* out: has font list been changed */
  403. {
  404. char empty = EOS;
  405. _DtHelpVolumeHdl vol;
  406. char * baseName = volumePath; /* no path component */
  407. /* calc baseName */
  408. if(_DtHelpCeStrrchr(volumePath, DirSlash, MB_CUR_MAX, &baseName)==0)
  409. baseName++;
  410. /* open volume */
  411. if ( _DtHelpOpenVolume(volumePath, &vol) != 0 )
  412. { /* if can't open, do best possible */
  413. if (ret_titleXmStr)
  414. *ret_titleXmStr = XmStringCreateLocalized(baseName);
  415. if (ret_title) *ret_title= XtNewString(baseName);
  416. if (ret_nameKey) *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
  417. return False;
  418. }
  419. /** volume is open, now get the data **/
  420. if (ret_title)
  421. {
  422. char * locTitle = NULL;
  423. /* locTitle is owned by caller */
  424. _DtHelpGetAsciiVolumeTitle(pDisplayArea, vol, &locTitle);
  425. if (locTitle == NULL)
  426. locTitle = XtNewString(baseName);
  427. *ret_title = locTitle;
  428. }
  429. if (ret_titleXmStr)
  430. {
  431. XmString locTitleXmStr = NULL;
  432. /* locTitle is owned by caller */
  433. _DtHelpFormatVolumeTitle(pDisplayArea,vol,
  434. &locTitleXmStr,io_fontList,ret_mod);
  435. if (locTitleXmStr == NULL)
  436. locTitleXmStr = XmStringCreateLocalized(baseName);
  437. *ret_titleXmStr = locTitleXmStr;
  438. }
  439. if (ret_docId || ret_timeStamp)
  440. {
  441. char * locDocId = NULL;
  442. char * locTimeStamp = NULL;
  443. /* locDocId & locTimeStamp will point to private memory; do not modify */
  444. _DtHelpCeGetDocStamp(vol,&locDocId, &locTimeStamp);
  445. if (ret_docId)
  446. *ret_docId = locDocId ? locDocId : XtNewString(&empty);
  447. if (ret_timeStamp)
  448. *ret_timeStamp = locTimeStamp?locTimeStamp:XtNewString(&empty);
  449. }
  450. if (ret_nameKey)
  451. {
  452. *ret_nameKey = _DtHelpCeStrHashToKey(baseName);
  453. }
  454. _DtHelpCloseVolume(vol);
  455. return True;
  456. }
  457. /************************************************************************
  458. * Function: AdjustPositionValues()
  459. * Adjust the position values of all volumes in the list by the amount given
  460. *
  461. ************************************************************************/
  462. static void AdjustPositionValues(
  463. _DtHelpFileList fileList,
  464. int adjStartAmount,
  465. int adjNextAmount,
  466. int adjustThisFile)
  467. {
  468. _DtHelpGlobSrchVol * curVol;
  469. if ( NULL == fileList
  470. || NULL == (curVol = (_DtHelpGlobSrchVol *) fileList->clientData) )
  471. return; /* RETURN */
  472. /* do we need to find first next file that has hits and is in list? */
  473. if(False == adjustThisFile)
  474. {
  475. curVol->nextVolPosition += adjNextAmount;
  476. for ( fileList = _DtHelpFileListGetNext(NULL,fileList); /* begin with next */
  477. NULL != fileList;
  478. fileList = _DtHelpFileListGetNext(NULL,fileList) )
  479. {
  480. _DtHelpGlobSrchVol * vol=(_DtHelpGlobSrchVol *)fileList->clientData;
  481. if (vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
  482. break; /* BREAK */
  483. vol->nextVolPosition += adjNextAmount;
  484. }
  485. /* all further files require same adj amts */
  486. adjStartAmount = adjNextAmount;
  487. }
  488. /* add in the adjust amount to all files */
  489. for ( /* do nothing */;
  490. NULL != fileList;
  491. fileList = _DtHelpFileListGetNext(NULL,fileList) )
  492. {
  493. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) fileList->clientData;
  494. if (vol)
  495. {
  496. vol->startPosition += adjStartAmount;
  497. vol->nextVolPosition += adjNextAmount;
  498. }
  499. /* overwrite, once we've done the first file, if haven't already */
  500. adjStartAmount = adjNextAmount;
  501. }
  502. }
  503. /************************************************************************
  504. * Function: HitLoadTopics()
  505. *
  506. * Loads the topics referred to by a hit
  507. * Returns: 0 if loaded ok, -1 otherwise
  508. ************************************************************************/
  509. static int HitLoadTopics (
  510. DtHelpDialogWidget hw,
  511. _DtHelpFileEntry file,
  512. _DtHelpGlobSrchHit * hit)
  513. {
  514. _DtHelpVolumeHdl volHandle;
  515. char * * origTopicIdList = NULL;
  516. int topicCnt;
  517. int i;
  518. XmString * titlesList = NULL;
  519. char * * idList = NULL;
  520. char * * fileList = NULL;
  521. XmFontList fontList = NULL;
  522. Boolean mod = False;
  523. Boolean allMods = False;
  524. Arg args[5];
  525. if (hit->topicsLoaded) return 0; /* RETURN: ok */
  526. if (_DtHelpOpenVolume(file->fullFilePath, &volHandle) != 0 )
  527. return -1; /* RETURN: error */
  528. topicCnt = _DtHelpCeFindKeyword(volHandle,hit->indexEntry,&origTopicIdList);
  529. if (topicCnt <= 0) return -1; /* RETURN: error */
  530. /* get results font list */
  531. XtSetArg(args[0], XmNfontList, &fontList);
  532. XtGetValues(hw->help_dialog.srch.resultList,args,1);
  533. #if defined(DONT_USE_CDExc22774)
  534. /* Don't need to copy, _DtHelpFormatVolumeTitle copies
  535. * before modifying.
  536. */
  537. /* FIX: check whether this is a memory leak. It isn't if the
  538. GetValues of XmFontList returns its own list, not a copy */
  539. /* work with copy, because FontListAppendEntry() destroys input FL */
  540. fontList = XmFontListCopy(fontList);
  541. #endif
  542. /* get the titles of all topics */
  543. for (i=0; i<topicCnt; i++)
  544. {
  545. XmString titleStr = NULL;
  546. Boolean valid = False;
  547. XmFontList lastFontList = NULL;
  548. /*
  549. * mod==True indicates _DtHelpFormatTopicTitle copied fontList
  550. * once already. Save a pointer to it so we can free the font list
  551. * if _DtHelpFormatTopicTitle copies it again.
  552. */
  553. lastFontList = fontList;
  554. valid = _DtHelpFormatTopicTitle(hw->help_dialog.help.pDisplayArea,
  555. volHandle,origTopicIdList[i], &titleStr, &fontList, &mod);
  556. if (mod && NULL != lastFontList) XmFontListFree(lastFontList);
  557. lastFontList = NULL;
  558. allMods |= mod; /* track for all iterations */
  559. if(valid!=0 || NULL==titleStr)
  560. {
  561. titleStr=XmStringCreateLocalized(origTopicIdList[i]);
  562. } /* if couldn't get title */
  563. /* note that titleStr is an XmString, not an (Xt) String */
  564. titlesList = (XmString *)_DtHelpCeAddPtrToArray (
  565. (void **)titlesList, (void *) titleStr);
  566. idList = (char **)_DtHelpCeAddPtrToArray (
  567. (void **)idList,
  568. (void *) XtNewString(origTopicIdList[i]));
  569. fileList = (char **)_DtHelpCeAddPtrToArray (
  570. (void **)fileList,
  571. (void *) XtNewString(file->fullFilePath));
  572. } /* for all topics of this index entry */
  573. /* install font list, if changed */
  574. if (allMods)
  575. {
  576. XtSetArg(args[0], XmNfontList, fontList);
  577. XtSetValues(hw->help_dialog.srch.resultList,args,1);
  578. if (fontList) XmFontListFree(fontList);
  579. }
  580. /* put results into hit */
  581. hit->topicTitles = titlesList;
  582. hit->topicIdList = idList;
  583. hit->topicFileList = fileList;
  584. hit->topicCnt = topicCnt;
  585. hit->topicsLoaded = True;
  586. _DtHelpCloseVolume(volHandle);
  587. return 0;
  588. }
  589. /************************************************************************
  590. * Function: HitNameDisplay()
  591. *
  592. * Updates the name of the hit, not delete or insert
  593. ************************************************************************/
  594. static int HitNameDisplay (
  595. DtHelpDialogWidget hw,
  596. _DtHelpFileEntry file,
  597. _DtHelpGlobSrchHit * hit,
  598. int hitPos,
  599. Boolean insertHit)
  600. {
  601. char * expandPrefix;
  602. char * contractPrefix;
  603. char * gotoPrefix;
  604. XmString prefixString;
  605. XmString labelString;
  606. char * tmpStr;
  607. char buf[30];
  608. /* FIX: this method of getting/using the prefixes
  609. is a performance nightmare; plus subject to font variability */
  610. expandPrefix = (char *)_DTGETMESSAGE (GSSET, 28," +");
  611. contractPrefix = (char *)_DTGETMESSAGE (GSSET, 29," -");
  612. gotoPrefix = (char *)_DTGETMESSAGE (GSSET, 30," ");
  613. /* if more than one topic for this index, signal it */
  614. tmpStr = gotoPrefix; /* index entry has one topic */
  615. if ( hit->topicCnt > 1 )
  616. {
  617. if (hit->topicsDisplayed) /* topics currently displayed */
  618. tmpStr = contractPrefix;
  619. else /* topics not displayed */
  620. tmpStr = expandPrefix;
  621. sprintf(buf, "%s%3d ", tmpStr, hit->topicCnt); /* 4d too spacy */
  622. tmpStr = buf;
  623. }
  624. LoadPrefixFont(hw);
  625. prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
  626. XmCHARSET_TEXT, NULL);
  627. labelString = XmStringConcat(prefixString,hit->indexTitle);
  628. /* recall indexTitle is an XmString in the volume's indexXmStrsList */
  629. /* install/insert the item */
  630. if (insertHit)
  631. XmListAddItemUnselected(hw->help_dialog.srch.resultList,
  632. labelString,hitPos);
  633. else
  634. XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
  635. &labelString,1,hitPos);
  636. XmStringFree(prefixString);
  637. XmStringFree(labelString);
  638. return (insertHit ? 1 : 0);
  639. }
  640. /************************************************************************
  641. * Function: HitTopicsDisplay()
  642. *
  643. * Loads the topics referred to by a hit and displays them
  644. * Returns the number of topics displayed
  645. ************************************************************************/
  646. static int HitTopicsDisplay (
  647. DtHelpDialogWidget hw,
  648. _DtHelpFileEntry file,
  649. _DtHelpGlobSrchHit * hit,
  650. int firstTopicListPosition)
  651. {
  652. XmString * pTopicString;
  653. XmString prefixString;
  654. XmString *items;
  655. char * tmpStr;
  656. int i;
  657. if ( False == hit->topicsLoaded && HitLoadTopics(hw,file,hit) < 0 )
  658. return 0; /* RETURN: error */
  659. if ( hit->topicsDisplayed ) return 0; /* RETURN: ok */
  660. LoadPrefixFont(hw);
  661. /*tmpStr = (char *)_DTGETMESSAGE (GSSET, 32," * ");*/
  662. tmpStr = (char *)_DTGETMESSAGE (GSSET, 31," ");
  663. prefixString = XmStringGenerate(tmpStr, s_PrefixFontListTag,
  664. XmCHARSET_TEXT, NULL);
  665. if (hit->topicCnt > 0)
  666. {
  667. items = (XmString *) XtMalloc (sizeof (XmString) * hit->topicCnt);
  668. /* put XmString-formatted topic titles into list */
  669. for (i = 0, pTopicString = hit->topicTitles; NULL != *pTopicString;
  670. pTopicString++, i++ )
  671. items[i] = XmStringConcat(prefixString,*pTopicString);
  672. XmListAddItemsUnselected(hw->help_dialog.srch.resultList, items,
  673. hit->topicCnt, firstTopicListPosition);
  674. for (i = 0; i < hit->topicCnt; i++)
  675. XmStringFree(items[i]);
  676. XtFree((char *) items);
  677. }
  678. XmStringFree(prefixString);
  679. /* set state */
  680. hit->topicsDisplayed = True;
  681. hit->showTopicsWithHit = True;
  682. return hit->topicCnt;
  683. }
  684. /************************************************************************
  685. * Function: HitTopicsUndisplay()
  686. *
  687. * Releases the topics referred to by a hit and undisplays them
  688. * Returns number of topics removed from display and hit.
  689. ************************************************************************/
  690. static int HitTopicsUndisplay (
  691. DtHelpDialogWidget hw,
  692. _DtHelpFileEntry file,
  693. _DtHelpGlobSrchHit * hit,
  694. int firstTopicListPosition)
  695. {
  696. int topPos;
  697. Arg args[5];
  698. if ( False == hit->topicsDisplayed ) return 0; /* RETURN */
  699. XtSetArg(args[0], XmNtopItemPosition, &topPos);
  700. XtGetValues(hw->help_dialog.srch.resultList,args,1);
  701. /* count the topics -- they are also being collapsed */
  702. if (hit->topicCnt > 0)
  703. XmListDeleteItemsPos(hw->help_dialog.srch.resultList,
  704. hit->topicCnt, firstTopicListPosition);
  705. hit->topicsDisplayed = False;
  706. /* NOTE: don't reset hit->showTopicsWithHit here; require that
  707. to be explicitly reset in ProcessResultSelection() */
  708. XmListSetPos(hw->help_dialog.srch.resultList, topPos);
  709. return hit->topicCnt;
  710. }
  711. /************************************************************************
  712. * Function: HitFree()
  713. *
  714. * Frees the memory associated with a hit and returns the next hit
  715. * member of the structure
  716. ************************************************************************/
  717. static _DtHelpGlobSrchHit * HitFree (
  718. _DtHelpGlobSrchHit * hit,
  719. Boolean freeHitItself)
  720. {
  721. XmString * nextStr;
  722. _DtHelpGlobSrchHit * nextHit;
  723. if (NULL == hit) return NULL;
  724. nextHit = hit->next;
  725. /* Free the mem of the topics id list */
  726. _DtHelpCeFreeStringArray(hit->topicIdList);
  727. hit->topicIdList = NULL; /* mem not owned by me */
  728. /* Free the mem of the topics files list */
  729. _DtHelpCeFreeStringArray(hit->topicFileList);
  730. hit->topicFileList = NULL;
  731. /* topicTitles are XmStrings and we can't use FreeStringArray() */
  732. for ( nextStr = hit->topicTitles;
  733. NULL != nextStr && NULL != *nextStr;
  734. nextStr++)
  735. XmStringFree (*nextStr);
  736. XtFree((char *) hit->topicTitles); /* its an XmString * */
  737. hit->topicTitles = NULL;
  738. /* set flags */
  739. hit->topicsLoaded = False;
  740. hit->topicsDisplayed = False;
  741. if (freeHitItself)
  742. {
  743. /* Free the index entry */
  744. XtFree(hit->indexEntry);
  745. XtFree((String)hit);
  746. }
  747. return nextHit;
  748. }
  749. /************************************************************************
  750. * Function: HitListFree()
  751. *
  752. * Walks along a hit list and frees its contents
  753. ************************************************************************/
  754. static void HitListFree(
  755. _DtHelpGlobSrchVol * vol,
  756. Boolean freeHitsThemselves)
  757. {
  758. _DtHelpGlobSrchHit * hit;
  759. if (NULL == vol) return; /* RETURN */
  760. for ( hit = vol->hitListHead;
  761. NULL != hit;
  762. hit = HitFree(hit,freeHitsThemselves) )
  763. { /* nothing */ }
  764. /* reset search flags */
  765. vol->nothingDone = True;
  766. vol->topicSearchDone = False;
  767. vol->indexSearchDone = False;
  768. vol->searchCompleted = False;
  769. vol->searchedCnt = 0;
  770. vol->gatheredFullIndex = False;
  771. /* reset hit flags */
  772. vol->hitsDisplayed = False;
  773. vol->showHitsWithVol = False;
  774. vol->zeroHitsOk = False;
  775. vol->hitCnt = 0;
  776. /* reset list display flags */
  777. vol->startPosition = 1;
  778. vol->nextVolPosition = 1;
  779. /* don't free indexXmStrsList here because they
  780. are reused for every search on this volume */
  781. vol->curIndexXmStr = vol->indexXmStrsList;
  782. /* indexEntriesList,volhandle inited elsewhere */
  783. if (freeHitsThemselves)
  784. {
  785. vol->hitListHead = NULL;
  786. vol->hitListTail = NULL;
  787. }
  788. }
  789. /************************************************************************
  790. * Function: HitListFreeAllVolHits()
  791. *
  792. * Walks along all the volumes and frees their hits
  793. ************************************************************************/
  794. static void
  795. HitListFreeAllVolHits (
  796. DtHelpDialogWidget hw,
  797. Boolean freeFullIndex)
  798. {
  799. _DtHelpGlobSrchVol * vol;
  800. _DtHelpFileEntry curFile;
  801. /* walk the files, freeing all hits and their data */
  802. for ( curFile = hw->help_dialog.srch.volListHead;
  803. NULL != curFile;
  804. curFile = _DtHelpFileListGetNext(NULL,curFile) )
  805. {
  806. vol = (_DtHelpGlobSrchVol *) curFile->clientData;
  807. if (NULL == vol) continue; /* CONTINUE */
  808. if (vol->gatheredFullIndex && freeFullIndex == False) continue;
  809. HitListFree(vol,True); /* True: free hits themselves */
  810. }
  811. hw->help_dialog.srch.hitsFound = False;
  812. }
  813. /************************************************************************
  814. * Function: HitListGetNth()
  815. *
  816. * Retrieves the Nth entry from the hits contained in the VolList
  817. *
  818. * This code follows the same counting paradigm used when adding
  819. * the items to the srchResultList widget, so that we can just use the
  820. * position value returned by it to retrieve the selected item.
  821. *
  822. * This paradigm also counts the presence of a volume as an item
  823. * if it contains any hits, and doesn't count it if it contains
  824. * no hits. It also counts the topicTitles that are associated
  825. * with a hit and displayed indented beneath it.
  826. *
  827. * The position count is 1 based, which corresponds with the
  828. * XmList approach.
  829. *
  830. * Return params:
  831. * ret_hit: retuns NULL if an error or a pointer to the hit structure.
  832. * ret_locationId: returns NULL is position is for the hit
  833. * structure itself, returns a pointer to private
  834. * memory containing the location id if position
  835. * is a topic belonging to the hit.
  836. *
  837. * Returns: 0 if ok, -1 if error
  838. ************************************************************************/
  839. static int HitListGetNth (
  840. _DtHelpFileList volListHead,
  841. int position,
  842. _DtHelpFileEntry * ret_file,
  843. _DtHelpGlobSrchHit * * ret_hit,
  844. char * * ret_locationId,
  845. char * * ret_helpFile)
  846. {
  847. _DtHelpGlobSrchHit * hit = NULL;
  848. _DtHelpGlobSrchVol * curVol;
  849. _DtHelpFileEntry curFile = NULL;
  850. _DtHelpFileEntry posFile = NULL;
  851. char * * locationIdList = NULL;
  852. char * * fileNameList = NULL;
  853. int curPos;
  854. if (NULL == volListHead) goto done; /* GOTO on error */
  855. /* walk along the volumes to find the one containing the position
  856. Because we need the most recent file with hits before the
  857. nextFile that has too high a position, only set posFile when
  858. we aren't ready to stop yet and we're on a file with hits. */
  859. for ( curFile = volListHead;
  860. NULL != curFile;
  861. curFile = _DtHelpFileListGetNext(curFile,curFile) )
  862. {
  863. /* it is impt to use > test so that multiple volumes with the same
  864. start position are properly handled. This occurs when they
  865. have no hits in them. */
  866. curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
  867. if (NULL == curVol) continue;
  868. #if 0
  869. if (curVol->startPosition > position) break; /* BREAK */
  870. if (curVol->hitCnt > 0) posFile = curFile; /* recent with hits */
  871. #else
  872. if (curVol->showVolInList && curVol->nextVolPosition > position)
  873. {
  874. posFile = curFile;
  875. break; /* BREAK */
  876. }
  877. #endif
  878. }
  879. if(NULL == posFile) goto done; /* GOTO on error */
  880. /*** walk along the hits to find the one matching the position ***/
  881. curVol = (_DtHelpGlobSrchVol *) posFile->clientData;
  882. curPos = curVol->startPosition;
  883. hit = NULL;
  884. locationIdList = NULL;
  885. fileNameList = NULL;
  886. /* (position == curPos) ==> volume name itself was selected */
  887. if ( curPos < position )
  888. { /* a hit inside the volume */
  889. if ( curVol->hitsDisplayed )
  890. {
  891. for ( curPos++, hit = curVol->hitListHead;
  892. curPos < position && NULL != hit;
  893. curPos++, hit = hit->next )
  894. {
  895. if (False == hit->topicsDisplayed) continue; /* CONTINUE */
  896. /* walk all displayed topics to see if the position is here */
  897. for ( locationIdList=hit->topicIdList,fileNameList=hit->topicFileList;
  898. NULL != locationIdList[0];
  899. locationIdList++, fileNameList++ )
  900. {
  901. /* use GOTO to escape with all pointers correct and
  902. without introducing an additional flag variable */
  903. if (++curPos == position) goto done; /* GOTO */
  904. } /* for all locations of a hit before the position */
  905. } /* for all members of the hit list before the position */
  906. } /* if hits are currently shown */
  907. else posFile = NULL; /* an error occurred */
  908. } /* if position is in the hit list */
  909. done:
  910. if (ret_hit) *ret_hit = hit;
  911. if (ret_file) *ret_file = posFile;
  912. if (ret_locationId)
  913. {
  914. if ( locationIdList ) *ret_locationId = locationIdList[0];
  915. else *ret_locationId = NULL;
  916. }
  917. if (ret_helpFile)
  918. {
  919. if ( fileNameList ) *ret_helpFile = fileNameList[0];
  920. else *ret_helpFile = NULL;
  921. }
  922. /* WARNING: depends on pointers and integers the same size */
  923. #ifdef __LP64__
  924. return (0 == ((int64_t)hit|(int64_t)posFile|(int64_t)locationIdList)) ? -1 : 0;
  925. #else
  926. return (0 == ((int)hit|(int)posFile|(int)locationIdList)) ? -1 : 0;
  927. #endif
  928. }
  929. /************************************************************************
  930. * Function: HitListAddFound()
  931. *
  932. * Adds a hit to the hit list of the specified volume
  933. * The hits are added either to the end of the list,
  934. * so that the srchResultList presents the items in the order found,
  935. * or in a sorted order.
  936. * If a hit on that topic already exists, just the existing
  937. * hit structure is returned.
  938. *
  939. * Return Parameters:
  940. * Ret_hit points to the hit data. This is not a copy--do not
  941. * free the pointer.
  942. *
  943. * Return value:
  944. * Returns 0 if no error, -1 if an error occurred.
  945. ************************************************************************/
  946. static int HitListAddFound (
  947. _DtHelpFileEntry curFile,
  948. XmString indexTitle,
  949. char * indexEntry,
  950. Boolean insertSorted,
  951. _DtHelpGlobSrchHit **ret_hit)
  952. {
  953. _DtHelpGlobSrchHit * prev;
  954. _DtHelpGlobSrchHit * next;
  955. _DtHelpGlobSrchHit * srcHit;
  956. _DtHelpGlobSrchVol * vol;
  957. int newKey;
  958. extern _CEStrcollProc _DtHelpCeGetStrcollProc();
  959. _CEStrcollProc strcollfn = _DtHelpCeGetStrcollProc();
  960. if (NULL == curFile) return -1; /* RETURN */
  961. vol = (_DtHelpGlobSrchVol *) curFile->clientData;
  962. if (NULL == vol) return -1; /* RETURN */
  963. /* walk along the hits, looking for one matching the new hit */
  964. /* recall that position is 1-based */
  965. newKey = _DtHelpCeStrHashToKey(indexEntry);
  966. prev = next = NULL;
  967. if ( insertSorted ) /* find position and check for duplicates */
  968. {
  969. /* walk along list */
  970. for( next = vol->hitListHead;
  971. NULL != next;
  972. prev = next, next = next->next )
  973. {
  974. int ret;
  975. /* do a NLS case insensitive compare using NLS collating */
  976. if ( (ret = (*strcollfn)(next->indexEntry,indexEntry)) >= 0 )
  977. {
  978. if (0 == ret)
  979. {
  980. if(ret_hit) *ret_hit = next;
  981. return 0; /* RETURN */
  982. }
  983. /* prev and next are set correctly */
  984. break; /* BREAK */
  985. }
  986. }
  987. }
  988. else /* check for duplicates */
  989. {
  990. /* walk along list */
  991. for( next = vol->hitListHead;
  992. NULL != next;
  993. prev = next, next = next->next )
  994. {
  995. if ( newKey == next->indexKey /* quick compare */
  996. && strcmp(indexEntry,next->indexEntry) == 0 ) /* long compare */
  997. {
  998. if(ret_hit) *ret_hit = next;
  999. return 0; /* RETURN */
  1000. }
  1001. }
  1002. /* prev and next are set correctly (at end of list) */
  1003. }
  1004. /* handle a new hit */
  1005. srcHit = (_DtHelpGlobSrchHit *)XtCalloc(1,sizeof(_DtHelpGlobSrchHit));
  1006. if (NULL == srcHit) return -1; /* RETURN */
  1007. /* init hit values */
  1008. /* leave srcHit->hitCnt == 0 here */
  1009. if (NULL == indexTitle)
  1010. srcHit->indexTitle = XmStringCreateLocalized(indexEntry);
  1011. else
  1012. srcHit->indexTitle = indexTitle;
  1013. srcHit->indexEntry = XtNewString(indexEntry);
  1014. srcHit->indexKey = newKey;
  1015. srcHit->volume = curFile;
  1016. /* integrate hit into the list */
  1017. srcHit->next = next;
  1018. if (prev) prev->next = srcHit;
  1019. else vol->hitListHead = srcHit;
  1020. if (!next) vol->hitListTail = srcHit;
  1021. /* add in the volume contribution */
  1022. vol->hitCnt++;
  1023. /* return stuff */
  1024. if(ret_hit) *ret_hit = srcHit;
  1025. return 0;
  1026. }
  1027. /************************************************************************
  1028. * Function: CountSelectedVolumes()
  1029. *
  1030. * Counts the number volumes with the searchThisVolume flag set
  1031. * for which the search has yet to complete
  1032. *
  1033. ************************************************************************/
  1034. static int CountSelectedVolumes (
  1035. _DtHelpFileList volListHead,
  1036. Boolean countSearchCompletedVolumes)
  1037. {
  1038. int count = 0;
  1039. /* walk all volumes */
  1040. for ( /* nothing */;
  1041. NULL != volListHead;
  1042. volListHead = _DtHelpFileListGetNext(NULL, volListHead) )
  1043. {
  1044. _DtHelpGlobSrchVol * vol;
  1045. /* get the volume info */
  1046. vol = (_DtHelpGlobSrchVol *) volListHead->clientData;
  1047. /* if (NULL != vol && vol->searchThisVolume && False == vol->searchCompleted)*/
  1048. if (vol && vol->searchThisVolume)
  1049. {
  1050. if ( (False == vol->searchCompleted)
  1051. || (countSearchCompletedVolumes && vol->searchCompleted) )
  1052. count++;
  1053. }
  1054. } /* walk all volumes */
  1055. return count;
  1056. }
  1057. /************************************************************************
  1058. * Function: GetNextSearchFileAndDisplayCompleted()
  1059. *
  1060. * Scans list for next file ready for searching
  1061. * If it encounters a file that has completed it's search
  1062. * and for which the results should be displayed, they are displayed
  1063. *
  1064. ************************************************************************/
  1065. static _DtHelpFileEntry GetNextSearchFileAndDisplayCompleted(
  1066. DtHelpDialogWidget hw,
  1067. _DtHelpFileList listHead,
  1068. _DtHelpFileEntry curFile)
  1069. {
  1070. /* get first file needing work */
  1071. for ( curFile = _DtHelpFileListGetNext(listHead, curFile);
  1072. NULL != curFile;
  1073. curFile = _DtHelpFileListGetNext(NULL, curFile) )
  1074. {
  1075. _DtHelpGlobSrchVol * vol;
  1076. vol = (_DtHelpGlobSrchVol *) curFile->clientData;
  1077. if (NULL == vol) continue; /* CONTINUE */
  1078. /* if file already searched and should be displayed, then do so */
  1079. if ( vol->searchThisVolume && vol->searchCompleted
  1080. && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk) )
  1081. {
  1082. /* record that a hit found */
  1083. if ( vol->hitCnt > 0
  1084. || ( vol->zeroHitsOk
  1085. && _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
  1086. hw->help_dialog.srch.hitsFound = True;
  1087. /* True: adjust count beginning with this file */
  1088. AdjustPositionValues(curFile,0,1,True);
  1089. ResultsListUpdate(hw,curFile);
  1090. /* display the hits as well? */
  1091. if ( vol->showHitsWithVol
  1092. || hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
  1093. {
  1094. VolHitsDisplay(hw,curFile);
  1095. /* update the volume label to show state; False--don't insert */
  1096. VolNameDisplay(hw,curFile,False);
  1097. }
  1098. }
  1099. /* if want to search, and need to, then return it */
  1100. if ( vol->searchThisVolume && False == vol->searchCompleted
  1101. && vol->showVolInList ) /* don' search unless results will be shown */
  1102. break;
  1103. }
  1104. XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
  1105. return curFile;
  1106. }
  1107. /************************************************************************
  1108. * Function: AddVolInfoToFile
  1109. *
  1110. * Creates a volume info entry for each member of the list
  1111. * and initializes its values
  1112. * If searchStatus is False, all volumes are set. If its True,
  1113. * all are set if selectedFilesOnly is false, otherwise only
  1114. * selected files are set to true.
  1115. *
  1116. ************************************************************************/
  1117. static void AddVolInfoToFile(
  1118. _DtHelpFileEntry file,
  1119. Boolean initialSearchStatus,
  1120. Boolean displayStatus,
  1121. Boolean selectedFilesOnly)
  1122. {
  1123. _DtHelpGlobSrchVol * vol;
  1124. if (NULL == file) return; /* RETURN */
  1125. vol = (_DtHelpGlobSrchVol *) file->clientData;
  1126. if (NULL == vol)
  1127. {
  1128. vol = (_DtHelpGlobSrchVol *) XtCalloc(1,sizeof(_DtHelpGlobSrchVol));
  1129. file->clientData = (XtPointer) vol;
  1130. if (NULL == vol) return; /* RETURN: memory alloc error */
  1131. /* calloc() inited almost everything inside to 0 */
  1132. /* set first time creation values */
  1133. vol->nothingDone = True;
  1134. }
  1135. /* now set search and display flags */
  1136. vol->searchThisVolume = initialSearchStatus;
  1137. vol->showVolInList = displayStatus;
  1138. if ( False == file->fileSelected && True == selectedFilesOnly )
  1139. {
  1140. vol->searchThisVolume = False;
  1141. vol->showVolInList = False;
  1142. }
  1143. }
  1144. /************************************************************************
  1145. * Function: AddVolInfoToList
  1146. *
  1147. * Creates a volume info entry for each member of the list
  1148. * and initializes its values
  1149. * If searchStatus is False, all volumes are set. If its True,
  1150. * all are set if selectedFilesOnly is false, otherwise only
  1151. * selected files are set to true.
  1152. *
  1153. ************************************************************************/
  1154. static void AddVolInfoToList(
  1155. _DtHelpFileList listHead,
  1156. Boolean initialSearchStatus,
  1157. Boolean displayStatus,
  1158. Boolean selectedFilesOnly)
  1159. {
  1160. /* walk the files and allocate the vol info as needed */
  1161. for ( /*nothing*/;
  1162. NULL != listHead;
  1163. listHead = _DtHelpFileListGetNext(listHead,listHead) )
  1164. {
  1165. AddVolInfoToFile(listHead,
  1166. initialSearchStatus, displayStatus, selectedFilesOnly);
  1167. }
  1168. }
  1169. /************************************************************************
  1170. * Function: SetVolStatus()
  1171. *
  1172. * Sets all volumes in the list to the specified search and/or display
  1173. * status values.
  1174. *
  1175. * If searchThisVolume is False, all volumes are set. If its True,
  1176. * all are set if selectedFilesOnly is false, otherwise only
  1177. * selected files are set to true. If searchThisVolume is False,
  1178. * then the settings remain unchanged in all volumes.
  1179. *
  1180. ************************************************************************/
  1181. static void SetVolStatus(
  1182. _DtHelpFileList listHead,
  1183. Boolean searchThisVolume,
  1184. Boolean showVolInList,
  1185. Boolean zeroHitsOk,
  1186. Boolean selectedFilesOnly)
  1187. {
  1188. /* walk the files and set the status */
  1189. for ( /*nothing*/;
  1190. NULL != listHead;
  1191. listHead = _DtHelpFileListGetNext(listHead,listHead) )
  1192. {
  1193. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
  1194. if (NULL == vol) continue;
  1195. if ( (False == selectedFilesOnly)
  1196. || (True == listHead->fileSelected && True == selectedFilesOnly) )
  1197. {
  1198. /* just set the inclusion and/or display flags;
  1199. don't reset the search progress flags */
  1200. vol->searchThisVolume = searchThisVolume;
  1201. vol->showVolInList = showVolInList;
  1202. vol->zeroHitsOk = zeroHitsOk;
  1203. }
  1204. }
  1205. }
  1206. /************************************************************************
  1207. * Function: VolNameDisplay()
  1208. *
  1209. * Updates the display of the volume name
  1210. ************************************************************************/
  1211. static void VolNameDisplay(
  1212. DtHelpDialogWidget hw,
  1213. _DtHelpFileEntry file,
  1214. Boolean insertVol)
  1215. {
  1216. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
  1217. XmString prefixString;
  1218. XmString labelString;
  1219. char * tmpStr;
  1220. char buf[40];
  1221. if ( NULL == vol || (False == vol->zeroHitsOk && 0 == vol->hitCnt) )
  1222. return; /* RETURN */
  1223. /* put volume name into list */
  1224. if (vol->hitCnt <= 0) tmpStr = (char *)_DTGETMESSAGE (GSSET, 25," ");
  1225. else if (vol->hitsDisplayed) tmpStr = (char *)_DTGETMESSAGE (GSSET, 27,"-");
  1226. else tmpStr = (char *)_DTGETMESSAGE (GSSET, 26,"+"); /* >0 hits */
  1227. sprintf(buf, "%s%3d ", tmpStr, vol->hitCnt); /* 4d too spacy */
  1228. LoadPrefixFont(hw);
  1229. prefixString = XmStringGenerate(buf, s_PrefixFontListTag,
  1230. XmCHARSET_TEXT, NULL);
  1231. labelString = XmStringConcat(prefixString,file->fileTitleXmStr);
  1232. /* replace or insert to reflect changed contents */
  1233. if (insertVol)
  1234. XmListAddItemUnselected(hw->help_dialog.srch.resultList,
  1235. labelString, vol->startPosition);
  1236. else
  1237. XmListReplaceItemsPosUnselected(hw->help_dialog.srch.resultList,
  1238. &labelString, 1, vol->startPosition);
  1239. XmStringFree(prefixString);
  1240. XmStringFree(labelString);
  1241. }
  1242. /************************************************************************
  1243. * Function: VolHitsDisplay()
  1244. *
  1245. * displays the hits associated with a volume
  1246. * Returns the number of new items added to the list
  1247. ************************************************************************/
  1248. static int VolHitsDisplay (
  1249. DtHelpDialogWidget hw,
  1250. _DtHelpFileEntry file)
  1251. {
  1252. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
  1253. _DtHelpGlobSrchHit * hit;
  1254. int listPos = vol->startPosition; /* vol item position */
  1255. int itemCnt;
  1256. if (True == vol->hitsDisplayed ) return 0; /* RETURN */
  1257. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  1258. if (hw->help_dialog.srch.selectionDlg)
  1259. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  1260. /*** walk through the hits and count and display any open hits ***/
  1261. for ( hit = vol->hitListHead, itemCnt = 0;
  1262. NULL != hit;
  1263. hit = hit->next)
  1264. {
  1265. itemCnt++; /* True: insert Hit into list */
  1266. HitNameDisplay (hw,file,hit,listPos + itemCnt,True);
  1267. /* display topics too? */
  1268. if (hit->showTopicsWithHit)
  1269. {
  1270. int newItems;
  1271. newItems = HitTopicsDisplay(hw,file,hit, listPos + itemCnt + 1);
  1272. HitNameDisplay (hw,file,hit,listPos + itemCnt,False);
  1273. itemCnt += newItems;
  1274. }
  1275. }
  1276. /* new state */
  1277. vol->hitsDisplayed = True;
  1278. vol->showHitsWithVol = True;
  1279. /* adjust count beginning with next file with hits */
  1280. AdjustPositionValues(file, 0, itemCnt, True);
  1281. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  1282. if (hw->help_dialog.srch.selectionDlg)
  1283. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  1284. return itemCnt;
  1285. }
  1286. /************************************************************************
  1287. * Function: VolHitsUndisplay()
  1288. *
  1289. * undisplays the hits associated with a volume
  1290. ************************************************************************/
  1291. static int VolHitsUndisplay (
  1292. DtHelpDialogWidget hw,
  1293. _DtHelpFileEntry file)
  1294. {
  1295. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
  1296. _DtHelpGlobSrchHit * hit;
  1297. Boolean nonVisibleItems;
  1298. int listPos = vol->startPosition; /* vol item position */
  1299. int itemCnt;
  1300. int curDelPos;
  1301. int undisItemCnt;
  1302. int visItemCnt;
  1303. int topNonVisPos;
  1304. int topPos;
  1305. Arg args[5];
  1306. if (False == vol->hitsDisplayed) return 0; /* RETURN */
  1307. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  1308. if (hw->help_dialog.srch.selectionDlg)
  1309. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  1310. XtSetArg(args[0], XmNtopItemPosition, &topPos);
  1311. XtSetArg(args[1], XmNvisibleItemCount, &visItemCnt);
  1312. XtGetValues(hw->help_dialog.srch.resultList,args,2);
  1313. /* these are the num visible items below the volume name */
  1314. topNonVisPos = topPos + visItemCnt; /* 1st non vis pos */
  1315. /* num of items that will be undisplayed */
  1316. undisItemCnt = vol->nextVolPosition - (vol->startPosition + 1);
  1317. /* find out if any items aren't visible */
  1318. nonVisibleItems = False;
  1319. if ( vol->nextVolPosition > topNonVisPos )
  1320. nonVisibleItems = True;
  1321. /*** walk through the hits and count and delete any open topics ***/
  1322. /* Make two passes: the first pass deletes all non-visible
  1323. items. The second pass deletes the remaining visible items.
  1324. The objective is to make collapse as fast and smooth as expand. */
  1325. if (nonVisibleItems)
  1326. { /* delete all items with a position > topNonVisPos */
  1327. curDelPos = listPos + 1; /* starting position */
  1328. for ( hit = vol->hitListHead, itemCnt = 0;
  1329. NULL != hit;
  1330. hit = hit->next )
  1331. {
  1332. /* are we still in the visible region? */
  1333. if (curDelPos < topNonVisPos)
  1334. {
  1335. /* move down the list to next hit */
  1336. curDelPos++; /* this hit's item */
  1337. /* plus any open topics */
  1338. if (hit->topicsDisplayed) curDelPos += hit->topicCnt;
  1339. continue; /* CONTINUE */
  1340. }
  1341. /* we're in non-visible region--undisplay hit */
  1342. XmListDeletePos(hw->help_dialog.srch.resultList, curDelPos);
  1343. /* undisplay any topics */
  1344. if ( hit->topicsDisplayed )
  1345. itemCnt += HitTopicsUndisplay(hw,file,hit,curDelPos);
  1346. }
  1347. } /* if non visible items */
  1348. /* now delete the remaining visible items */
  1349. /* Note that curDelPos is a virtual cursor that helps us
  1350. figure out when to stop undisplaying. Virtually, we''re
  1351. moving the cursor down the list with every delete. Actually,
  1352. the rest of the list bumps up one--that''s why we delete
  1353. at listPos+1. */
  1354. curDelPos = listPos + 1; /* starting position */
  1355. for ( hit = vol->hitListHead, itemCnt = 0;
  1356. (NULL != hit) && (curDelPos < topNonVisPos);
  1357. hit = hit->next )
  1358. {
  1359. curDelPos++; /* undisplay hit item */
  1360. XmListDeletePos(hw->help_dialog.srch.resultList, listPos + 1);
  1361. /* undipslay any open topics */
  1362. if ( hit->topicsDisplayed )
  1363. {
  1364. curDelPos += HitTopicsUndisplay(hw,file,hit,listPos + 1);
  1365. XmListSetPos(hw->help_dialog.srch.resultList, topPos);
  1366. }
  1367. }
  1368. /* new state */
  1369. vol->hitsDisplayed = False;
  1370. /* NOTE: don't reset vol->showHitsWithVol here; require that
  1371. to be explicitly reset in ProcessResultSelection() */
  1372. /* adjust count beginning with next file with hits */
  1373. AdjustPositionValues(file, 0, -undisItemCnt, True);
  1374. XmListSetPos(hw->help_dialog.srch.resultList, topPos);
  1375. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  1376. if (hw->help_dialog.srch.selectionDlg)
  1377. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  1378. return undisItemCnt;
  1379. }
  1380. /************************************************************************
  1381. * Function: VolListFree()
  1382. *
  1383. * Releases all memory used by the volume list
  1384. *
  1385. ************************************************************************/
  1386. static void VolListFree (
  1387. _DtHelpGlobSearchStuff * srch)
  1388. {
  1389. _DtHelpFileList nextFile;
  1390. /* walk all volumes */
  1391. nextFile = srch->volListHead;
  1392. while ( NULL != nextFile )
  1393. {
  1394. _DtHelpGlobSrchVol * vol;
  1395. _DtHelpFileList tmpFile;
  1396. XmString * nextStr;
  1397. /* get the volume info */
  1398. vol = (_DtHelpGlobSrchVol *) nextFile->clientData;
  1399. /** free vol entry contents and container **/
  1400. XtFree(vol->stdLocale);
  1401. XtFree(vol->iconv3Codeset);
  1402. HitListFree(vol,True); /* True: free hits themselves */
  1403. /* no need to free indexEntriesList because these aren't owned by vol */
  1404. vol->indexEntriesList = NULL;
  1405. /* free indexXmStrsList */
  1406. /* indexXmStrs are XmStrings and we can't use FreeStringArray() */
  1407. for ( nextStr = vol->indexXmStrsList;
  1408. NULL != nextStr && NULL != *nextStr;
  1409. nextStr++)
  1410. XmStringFree (*nextStr);
  1411. XtFree((char *) vol->indexXmStrsList); /* its a XmString * */
  1412. vol->indexXmStrsList = NULL;
  1413. tmpFile = nextFile;
  1414. nextFile = _DtHelpFileListGetNext(NULL, nextFile);
  1415. _DtHelpFileFreeEntry(tmpFile); /* also frees the clientData (vol) */
  1416. } /* walk all volumes */
  1417. /* reset related values */
  1418. srch->volListHead = NULL;
  1419. srch->curSrchVol = NULL;
  1420. srch->volLeftCnt = 0;
  1421. /* delete the results */
  1422. DeleteListContents(srch);
  1423. }
  1424. /************************************************************************
  1425. * Function: ScanStatusCB
  1426. *
  1427. * Updates the status display with the number of volumes found
  1428. * as the scan progresses
  1429. *
  1430. ************************************************************************/
  1431. static void ScanStatusCB(
  1432. int count,
  1433. XtPointer clientData)
  1434. {
  1435. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  1436. StatusLabelUpdate(hw,SCANNING_STATUS,True,count);
  1437. }
  1438. /************************************************************************
  1439. * Function: VolListBuild
  1440. *
  1441. * Frees the old list and builds a new one by scanning the
  1442. * help directories for volumes and adding the associated
  1443. * volume information used for searching.
  1444. *
  1445. ************************************************************************/
  1446. static void VolListBuild(
  1447. DtHelpDialogWidget hw,
  1448. Boolean searchStatus,
  1449. Boolean displayStatus,
  1450. Boolean selectedVolumesOnly)
  1451. {
  1452. Boolean mod;
  1453. XmFontList origFontList;
  1454. /* turn on hour glass */
  1455. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  1456. if (hw->help_dialog.srch.selectionDlg)
  1457. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  1458. StatusLabelUpdate(hw,SCANNING_STATUS,True,0);
  1459. origFontList = hw->help_dialog.srch.volTitlesFontList;
  1460. /* and rescan the volumes for the new list */
  1461. _DtHelpFileListScanPaths( &hw->help_dialog.srch.volListHead,
  1462. &hw->help_dialog.srch.volTitlesFontList,&mod,
  1463. DtHelpVOLUME_TYPE, _DtHelpFileSuffixList, False,
  1464. GetVolumeInfoCB,hw->help_dialog.help.pDisplayArea,
  1465. /* sysPathCompare */ _DtHELP_FILE_NAME,
  1466. /*otherPathCompare*/ _DtHELP_FILE_NAME|_DtHELP_FILE_TIME| _DtHELP_FILE_IDSTR,
  1467. /* sortBy */ _DtHELP_FILE_TITLE, ScanStatusCB, (XtPointer)hw);
  1468. /* if new fonts added to list, add them to the resultList */
  1469. if (mod)
  1470. {
  1471. MergeFontListIntoWidgetFonts(
  1472. hw->help_dialog.srch.resultList,
  1473. hw->help_dialog.srch.volTitlesFontList);
  1474. if (origFontList) XmFontListFree(origFontList);
  1475. }
  1476. /* Add on the Vol info and (T,F) allow search on all volumes */
  1477. AddVolInfoToList(hw->help_dialog.srch.volListHead,
  1478. searchStatus, displayStatus, selectedVolumesOnly);
  1479. hw->help_dialog.srch.volScanDone = True;
  1480. StatusLabelUpdate(hw,BLANK_STATUS,True,0);
  1481. /* turn off hour glass */
  1482. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  1483. if (hw->help_dialog.srch.selectionDlg)
  1484. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  1485. }
  1486. #if 0 || defined(DEBUG) /* for debug, set to 1 */
  1487. /************************************************************************
  1488. * Function: OutputVolInfo()
  1489. *
  1490. * Output info on all volumes in the list
  1491. *
  1492. ************************************************************************/
  1493. static void OutputVolInfo(
  1494. _DtHelpFileList listHead)
  1495. {
  1496. for ( /*nothing*/;
  1497. NULL != listHead;
  1498. listHead = _DtHelpFileListGetNext(listHead,listHead) )
  1499. {
  1500. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) listHead->clientData;
  1501. if (NULL == vol) continue;
  1502. /* output the info */
  1503. printf("==================\n");
  1504. printf("fileName: %s, %s\npathName: %s\n",
  1505. listHead->fileName, listHead->fileTitle, listHead->fullFilePath);
  1506. printf("searchThisVolume = %d, hitCnt = %d, startPos = %d\n",
  1507. (int) listHead->fileSelected,
  1508. (int) vol->hitCnt,
  1509. (int) vol->startPosition);
  1510. }
  1511. }
  1512. #endif
  1513. /************************************************************************
  1514. * Function: SearchContinuePossible()
  1515. *
  1516. * Test whether the search can be continued from the
  1517. * current state.
  1518. *
  1519. ************************************************************************/
  1520. static Boolean SearchContinuePossible(
  1521. DtHelpDialogWidget hw,
  1522. char * srchWord)
  1523. {
  1524. char * normSrchWord;
  1525. Boolean possible = False;
  1526. normSrchWord = XtNewString(srchWord);
  1527. _DtHelpCeCompressSpace(normSrchWord);
  1528. _DtHelpCeUpperCase(normSrchWord);
  1529. /* are we searching on the same word as previous search ? */
  1530. /* comparison with srchNormWordStr is correct, given calls to this fn */
  1531. /* FIX: use CheckSearchWord()? */
  1532. if ( ( hw->help_dialog.srch.fullIndex
  1533. || ( NULL != hw->help_dialog.srch.normWordStr
  1534. && NULL != normSrchWord
  1535. && strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
  1536. && NULL != hw->help_dialog.srch.volListHead
  1537. && hw->help_dialog.srch.volLeftCnt > 0 )
  1538. possible = True;
  1539. XtFree(normSrchWord);
  1540. return possible;
  1541. }
  1542. #ifdef not_used
  1543. /************************************************************************
  1544. * Function: SearchOnSameCriteria()
  1545. *
  1546. * Test whether the search criteria have changed
  1547. *
  1548. ************************************************************************/
  1549. static Boolean SearchOnSameCriteria(
  1550. DtHelpDialogWidget hw,
  1551. char * srchWord)
  1552. {
  1553. char * normSrchWord;
  1554. Boolean sameCrit = False;
  1555. normSrchWord = XtNewString(srchWord);
  1556. _DtHelpCeCompressSpace(normSrchWord);
  1557. _DtHelpCeUpperCase(normSrchWord);
  1558. /* are we searching on the same word as previous search ? */
  1559. /* comparison with srchNormWordStr is correct, given calls to this fn */
  1560. if ( hw->help_dialog.srch.fullIndex
  1561. || ( NULL != hw->help_dialog.srch.normWordStr
  1562. && NULL != normSrchWord
  1563. && strcmp(normSrchWord, hw->help_dialog.srch.normWordStr) == 0) )
  1564. sameCrit = True;
  1565. XtFree(normSrchWord);
  1566. return sameCrit;
  1567. }
  1568. #endif /* not_used */
  1569. /************************************************************************
  1570. * Function: UpdateActionButtonLabel()
  1571. *
  1572. * Sets the start button label properly
  1573. *
  1574. ************************************************************************/
  1575. static void UpdateActionButtonLabel(
  1576. DtHelpDialogWidget hw,
  1577. char * srchWord,
  1578. Boolean startContAction)
  1579. {
  1580. Arg args[5];
  1581. XmString labelString;
  1582. XmString curLabelString;
  1583. String textString;
  1584. /* char * mnemonic; */
  1585. /* if action label is to start or continue */
  1586. _DtHelpProcessLock();
  1587. if (startContAction)
  1588. {
  1589. if ( SearchContinuePossible(hw,srchWord) )
  1590. { /* then continue search */
  1591. textString=(char *)_DTGETMESSAGE (GSSET,
  1592. CONT_SEARCH_CAT,CONT_SEARCH_STR);
  1593. labelString = XmStringCreateLocalized(textString);
  1594. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 22,CONT_SEARCH_MNEM));*/
  1595. }
  1596. else
  1597. { /* otherwise start it */
  1598. textString=(char *)_DTGETMESSAGE (GSSET,
  1599. START_SEARCH_CAT,START_SEARCH_STR);
  1600. labelString = XmStringCreateLocalized(textString);
  1601. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
  1602. }
  1603. }
  1604. else /* action label is to stop */
  1605. {
  1606. textString = (char *)_DTGETMESSAGE (GSSET,
  1607. STOP_SEARCH_CAT,STOP_SEARCH_STR);
  1608. labelString = XmStringCreateLocalized(textString);
  1609. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, ??,STOP_SEARCH_MNEM));*/
  1610. }
  1611. _DtHelpProcessUnlock();
  1612. /* get the current state of the button */
  1613. XtSetArg(args[0],XmNlabelString,&curLabelString);
  1614. XtGetValues (hw->help_dialog.srch.actionBtn, args, 1);
  1615. /* update label if it is different; avoid flashing this way */
  1616. if ( XmStringCompare(labelString,curLabelString) == False )
  1617. {
  1618. XtSetArg(args[0],XmNlabelString,labelString);
  1619. XtSetArg(args[1], XmNalignment, XmALIGNMENT_CENTER);
  1620. /* XtSetArg(args[2], XmNmnemonic, mnemonic[0]);*/
  1621. XtSetValues (hw->help_dialog.srch.actionBtn, args, 2);
  1622. XmUpdateDisplay(hw->help_dialog.srch.actionBtn);
  1623. }
  1624. /* release the memory */
  1625. XmStringFree(labelString);
  1626. XmStringFree(curLabelString);
  1627. }
  1628. /*****************************************************************************
  1629. * Function: CheckSearchWord()
  1630. *
  1631. * Parameters:
  1632. *
  1633. * Return Value: True: word has changed
  1634. * False: word is same
  1635. *
  1636. * Purpose: Checks whether the search word is a new
  1637. * one or the same as before. If the same, it frees
  1638. * the word and returns False. If new, it moves the
  1639. * previous word to another variable and installs
  1640. * the new word in its place, using the srchWord mem.
  1641. * ...but only if updateWidgetFields is True
  1642. *
  1643. *****************************************************************************/
  1644. static Boolean CheckSearchWord(
  1645. DtHelpDialogWidget hw,
  1646. char * srchWord,
  1647. Boolean updateWidgetFields)
  1648. {
  1649. wchar_t firstChar;
  1650. char * rawSrchWord;
  1651. /* avoid a core dump */
  1652. if ( NULL == srchWord )
  1653. {
  1654. if ( NULL == hw->help_dialog.srch.normWordStr
  1655. || hw->help_dialog.srch.normWordStr[0] == 0)
  1656. return False; /* word hasn't changed */
  1657. return True; /* RETURN: word has changed */
  1658. }
  1659. _DtHelpCeCompressSpace(srchWord);
  1660. rawSrchWord = XtNewString(srchWord);
  1661. _DtHelpCeUpperCase(srchWord);
  1662. /* FIX: to support regcomp(3), do that here */
  1663. /* are we searching on the same word? */
  1664. if ( NULL != hw->help_dialog.srch.normWordStr
  1665. && strcmp(srchWord, hw->help_dialog.srch.normWordStr) == 0 )
  1666. {
  1667. XtFree(srchWord);
  1668. XtFree(rawSrchWord);
  1669. #if 0
  1670. /* output a message */
  1671. if ( NULL != hw->help_dialog.srch.normWordStr
  1672. && EOS != hw->help_dialog.srch.normWordStr[0])
  1673. StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
  1674. #endif
  1675. return False; /* RETURN: no change */
  1676. }
  1677. if (False == updateWidgetFields) return True; /* RETURN */
  1678. /* update search word fields */
  1679. XtFree(hw->help_dialog.srch.normWordStr);
  1680. XtFree(hw->help_dialog.srch.rawWordStr);
  1681. hw->help_dialog.srch.normWordStr = srchWord;
  1682. hw->help_dialog.srch.rawWordStr = rawSrchWord;
  1683. hw->help_dialog.srch.wordFieldLen = strlen(srchWord); /* note: not nl_strlen
  1684. because used on strncmp not nl_strncmp */
  1685. /* convert first char to a value for easy access for _DtHelpStrchr() */
  1686. if ( mbtowc(&firstChar,srchWord,1) <= 0 ) firstChar = 0;
  1687. hw->help_dialog.srch.wordFieldFirstChar = firstChar;
  1688. /* output a message */
  1689. if ( NULL != hw->help_dialog.srch.normWordStr
  1690. && EOS != hw->help_dialog.srch.normWordStr[0])
  1691. StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
  1692. return True; /* word changed */
  1693. }
  1694. /*****************************************************************************
  1695. * Function: PrepSearchSourceData()
  1696. *
  1697. * Parameters:
  1698. *
  1699. * Return Value: Void.
  1700. *
  1701. * Purpose: Based on the current settings of the volume
  1702. * selection buttons construct or utilitize an
  1703. * existing volume list for processing.
  1704. * Determine whether to continue search or
  1705. * restart by comparing search words and states.
  1706. *
  1707. *****************************************************************************/
  1708. static void PrepSearchSourceData(
  1709. DtHelpDialogWidget hw,
  1710. char * srchWord)
  1711. {
  1712. /* try to install the new word; if returns False, word is same
  1713. as before. True = also update widget fields. */
  1714. /* This test determines whether we might need to continue. */
  1715. if ( hw->help_dialog.srch.fullIndex
  1716. || CheckSearchWord(hw,srchWord,True) == False )
  1717. {
  1718. /* check to see if CheckSearchWord() was called. If it wasn't
  1719. then srchWord has not been freed or saved. We will lose the
  1720. memory unless we free it here. */
  1721. if (hw->help_dialog.srch.fullIndex)
  1722. XtFree(srchWord);
  1723. /* are we continuing an interrupted search? */
  1724. if ( hw->help_dialog.srch.volLeftCnt > 0
  1725. && NULL != hw->help_dialog.srch.volListHead )
  1726. return; /* RETURN: continue with search */
  1727. /* if searching full index, False=don't free vol with full index */
  1728. if (hw->help_dialog.srch.fullIndex)
  1729. HitListFreeAllVolHits(hw,False);
  1730. /* else we're searching on the same word, but completed
  1731. previous search. So reset the volumes to search/display
  1732. according to the current settings of the Volumes radio buttons,
  1733. but leave the results intact.
  1734. */
  1735. /* fall thru to do prep */
  1736. }
  1737. else /* searching for a different word */
  1738. {
  1739. /* free all hit-related data and reset flags */
  1740. HitListFreeAllVolHits(hw,True); /*True=free everything*/
  1741. }
  1742. /*** It's not just a continue. So, we may be beginning a new search
  1743. or continuing a search based on new volume selection params ***/
  1744. /* update display area */
  1745. DeleteListContents(&hw->help_dialog.srch);
  1746. StatusLabelUpdate(hw,WORKING_STATUS,False,0);
  1747. /*** update the volumes list according to sources selected ***/
  1748. if ( _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources )
  1749. {
  1750. /* volume list already built when opening selection dialog */
  1751. /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
  1752. SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
  1753. /* (T,T,T,T): enable search, enable display,
  1754. zero hits ok, only for selected volumes */
  1755. SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
  1756. } /* if selected volumes button */
  1757. else if ( _DtHelpGlobSrchAllVolumes == hw->help_dialog.srch.srchSources )
  1758. {
  1759. /* Scan directories for volumes if necessary */
  1760. if ( False == hw->help_dialog.srch.volScanDone
  1761. || NULL == hw->help_dialog.srch.volListHead)
  1762. {
  1763. /* Add on the Vol info; (T,T,F) search, display, all */
  1764. VolListBuild(hw,True,True,False);
  1765. }
  1766. /* (T,T,F,F): enable search,enable display,no 0 hits,for all vols */
  1767. SetVolStatus(hw->help_dialog.srch.volListHead,True,True,False,False);
  1768. } /* if all volumes button */
  1769. else /*** current volume button ***/
  1770. {
  1771. char * path;
  1772. _DtHelpFileEntry cur;
  1773. /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
  1774. SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
  1775. /* try to locate file and its entry, if present */
  1776. path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
  1777. _DtHelpFileSuffixList,False,R_OK);
  1778. cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
  1779. GetVolumeInfoCB, _DtHELP_FILE_NAME,
  1780. hw->help_dialog.help.pDisplayArea);
  1781. if (NULL == cur && NULL != path) /*file was located but isn't in list*/
  1782. { /* add it to the list */
  1783. Boolean mod;
  1784. XmFontList origFontList;
  1785. origFontList = hw->help_dialog.srch.volTitlesFontList;
  1786. _DtHelpFileListAddFile(&hw->help_dialog.srch.volListHead,
  1787. &hw->help_dialog.srch.volTitlesFontList,&mod,path,NULL,
  1788. GetVolumeInfoCB, _DtHELP_FILE_NAME, _DtHELP_FILE_TITLE,
  1789. hw->help_dialog.help.pDisplayArea);
  1790. if (mod)
  1791. {
  1792. MergeFontListIntoWidgetFonts(
  1793. hw->help_dialog.srch.resultList,
  1794. hw->help_dialog.srch.volTitlesFontList);
  1795. if (origFontList) XmFontListFree(origFontList);
  1796. }
  1797. /* (F,F,F): disable search, disable display, for all volumes */
  1798. AddVolInfoToList(hw->help_dialog.srch.volListHead,False,False,False);
  1799. cur = _DtHelpFileListGetMatch(hw->help_dialog.srch.volListHead,path,
  1800. GetVolumeInfoCB, _DtHELP_FILE_NAME,
  1801. hw->help_dialog.help.pDisplayArea);
  1802. }
  1803. if (cur) /* file present in list */
  1804. {
  1805. /* enable search and display on this volume */
  1806. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) cur->clientData;
  1807. vol->searchThisVolume = True;
  1808. vol->showVolInList = True;
  1809. vol->zeroHitsOk = True; /* show zero hits for search of cur vol */
  1810. }
  1811. else /* file not found */
  1812. {
  1813. /* FIX: put up error dialog and disable the button */
  1814. /*printf("Current volume %s not found\n",
  1815. hw->help_dialog.display.helpVolume);*/
  1816. } /* if file found */
  1817. XtFree(path); /* tests for NULL */
  1818. } /* if selected/all/cur volumes sources */
  1819. #if 0 || defined(DEBUG) /* for debug, set to 1 */
  1820. OutputVolInfo(hw->help_dialog.srch.volListHead);
  1821. #endif
  1822. /* get num volumes to process */
  1823. hw->help_dialog.srch.volLeftCnt =
  1824. CountSelectedVolumes(hw->help_dialog.srch.volListHead,True);
  1825. /* empty the results list */
  1826. XmUpdateDisplay(hw->help_dialog.srch.resultList);
  1827. }
  1828. /************************************************************************
  1829. * Function: CloseSearchCB()
  1830. *
  1831. * Close the Global Search Dialog
  1832. *
  1833. ************************************************************************/
  1834. static void CloseSearchCB (
  1835. Widget w,
  1836. XtPointer clientData,
  1837. XtPointer callData)
  1838. {
  1839. _DtHelpGlobSearchStuff * srch = (_DtHelpGlobSearchStuff *) clientData;
  1840. /* stop any work proc */
  1841. if(srch->workProcId)
  1842. {
  1843. XtRemoveWorkProc(srch->workProcId);
  1844. srch->workProcId = 0;
  1845. }
  1846. /* unmanage the srchForm dialog but don't destroy it */
  1847. if (NULL != srch->srchForm)
  1848. {
  1849. XtUnmanageChild(srch->srchForm);
  1850. XtUnmapWidget(srch->srchForm);
  1851. }
  1852. }
  1853. /*****************************************************************************
  1854. * Function: void DeleteListContents()
  1855. *
  1856. * Parameters:
  1857. *
  1858. * Return Value: Void.
  1859. *
  1860. * Purpose: empties list and resets position values
  1861. *
  1862. *****************************************************************************/
  1863. static void DeleteListContents(
  1864. _DtHelpGlobSearchStuff * srch)
  1865. {
  1866. _DtHelpFileEntry curFile;
  1867. if (NULL != srch->resultList)
  1868. XmListDeleteAllItems(srch->resultList);
  1869. for ( curFile = srch->volListHead;
  1870. NULL != curFile;
  1871. curFile = _DtHelpFileListGetNext(NULL,curFile) )
  1872. {
  1873. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) curFile->clientData;
  1874. if (NULL == vol) continue; /* CONTINUE */
  1875. /* if any hits are displayed and any have open topics,
  1876. walk through and close them */
  1877. if ( vol->hitsDisplayed
  1878. && ((vol->nextVolPosition - vol->startPosition) != vol->hitCnt) )
  1879. {
  1880. _DtHelpGlobSrchHit * hit;
  1881. for ( hit = vol->hitListHead;
  1882. NULL != hit;
  1883. hit = hit->next)
  1884. {
  1885. hit->topicsDisplayed = False;
  1886. }
  1887. }
  1888. vol->startPosition = 1;
  1889. vol->nextVolPosition = 1;
  1890. vol->hitsDisplayed = False;
  1891. }
  1892. }
  1893. /*****************************************************************************
  1894. * Function: void StatusLabelUpdate()
  1895. *
  1896. * Parameters:
  1897. *
  1898. * Return Value: Void.
  1899. *
  1900. * Purpose: Installs proper label over results list
  1901. *
  1902. *****************************************************************************/
  1903. static void StatusLabelUpdate(
  1904. DtHelpDialogWidget hw,
  1905. ResultsStatus status,
  1906. Boolean forceUpdate,
  1907. int intArg)
  1908. {
  1909. char * labelMsg;
  1910. XmString labelString;
  1911. XmString curLabelString;
  1912. Arg args[5];
  1913. char buf[100];
  1914. #if 0
  1915. /* only update if necessary */
  1916. if (status == hw->help_dialog.srch.statusLineUsage && !forceUpdate)
  1917. return;
  1918. #endif
  1919. /* order up the right message */
  1920. hw->help_dialog.srch.statusLineUsage = status;
  1921. switch (status)
  1922. {
  1923. case SCANNING_STATUS:
  1924. labelMsg = (char *)_DTGETMESSAGE(GSSET, 17,"Scanning for volumes... Found %d");
  1925. sprintf(buf,labelMsg,intArg);
  1926. labelMsg = buf;
  1927. break; /* BREAK */
  1928. case WORKING_STATUS:
  1929. labelMsg = (char *)_DTGETMESSAGE(GSSET, 18,
  1930. "Searching... Volumes remaining: %d");
  1931. /* we need +1 because of when this message is used */
  1932. sprintf(buf,labelMsg,hw->help_dialog.srch.volLeftCnt + 1);
  1933. labelMsg = buf;
  1934. break; /* BREAK */
  1935. case SEARCH_RESULTS_STATUS:
  1936. /* if no hits found */
  1937. if (hw->help_dialog.srch.hitsFound == False) /*don't use == True*/
  1938. {
  1939. if (hw->help_dialog.srch.fullIndex)
  1940. {
  1941. if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchAllVolumes)
  1942. labelMsg = (char *)_DTGETMESSAGE (GSSET,19,
  1943. "No index entries found.");
  1944. else
  1945. labelMsg = (char *)_DTGETMESSAGE (GSSET,50,
  1946. "No index entries found. Try All Volumes.");
  1947. }
  1948. else /* searched on a pattern */
  1949. {
  1950. labelMsg = (char *)_DTGETMESSAGE (GSSET,51,
  1951. "No index entries found. Try another word.");
  1952. }
  1953. /* change focus to the search word. Traversal is ignored
  1954. if srchWord is desensitized (Contains btn not selected) */
  1955. if (XtIsSensitive(hw->help_dialog.srch.wordField))
  1956. {
  1957. /*
  1958. * make sure the text field is editable before sending
  1959. * the traversal there.
  1960. */
  1961. XtSetArg(args[0],XmNeditable,True);
  1962. XtSetValues(hw->help_dialog.srch.wordField, args, 1);
  1963. XmProcessTraversal
  1964. (hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
  1965. }
  1966. else
  1967. XmProcessTraversal
  1968. (hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
  1969. }
  1970. else /* if hits found */
  1971. {
  1972. /* select the appropriate message */
  1973. if (hw->help_dialog.srch.fullIndex)
  1974. {
  1975. labelMsg = (char *)_DTGETMESSAGE(GSSET, 20,"Complete Index");
  1976. }
  1977. else
  1978. {
  1979. labelMsg = (char *)_DTGETMESSAGE(GSSET, 21,"Entries with \"%s\"");
  1980. sprintf(buf,labelMsg,hw->help_dialog.srch.rawWordStr);
  1981. labelMsg = buf;
  1982. }
  1983. /* change focus to the results list */
  1984. XmProcessTraversal(
  1985. hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
  1986. } /* if no hits found else */
  1987. break; /* BREAK */
  1988. case NO_VOL_STATUS:
  1989. labelMsg = (char *)_DTGETMESSAGE (GSSET, 22,"No volumes selected");
  1990. break; /* BREAK */
  1991. case FIRST_PROMPT_STATUS:
  1992. labelMsg = (char *)_DTGETMESSAGE(GSSET,23,"Select search options above");
  1993. break; /* BREAK */
  1994. case BLANK_STATUS:
  1995. default:
  1996. /* DBG: when an empty string, form constraints are wrong; make a space */
  1997. labelMsg = " ";
  1998. break; /* BREAK */
  1999. }
  2000. /* make a label string */
  2001. labelString = XmStringCreateLocalized(labelMsg);
  2002. /* get the current string of the label */
  2003. curLabelString = NULL;
  2004. XtSetArg(args[0],XmNlabelString,&curLabelString);
  2005. XtGetValues (hw->help_dialog.srch.statusLabel, args, 1);
  2006. /* update label if it is different; avoid flashing this way */
  2007. if ( NULL != curLabelString && NULL != labelString
  2008. && XmStringCompare(labelString,curLabelString) == False )
  2009. {
  2010. /* update msg over results list */
  2011. XtSetArg(args[0],XmNlabelString,labelString);
  2012. XtSetValues(hw->help_dialog.srch.statusLabel,args,1);
  2013. }
  2014. XmStringFree(labelString);
  2015. XmStringFree(curLabelString);
  2016. XmUpdateDisplay(hw->help_dialog.srch.statusLabel);
  2017. }
  2018. /*****************************************************************************
  2019. * Function: void ResultsListUpdate()
  2020. *
  2021. * Parameters:
  2022. *
  2023. * Return Value: Void.
  2024. *
  2025. * Purpose: empty list and display results status message
  2026. *
  2027. *****************************************************************************/
  2028. static void ResultsListUpdate(
  2029. DtHelpDialogWidget hw,
  2030. _DtHelpFileEntry newFile)
  2031. {
  2032. _DtHelpFileEntry testFile;
  2033. /* check that in fact, there are no results that will be overwritten */
  2034. for ( testFile = hw->help_dialog.srch.volListHead;
  2035. NULL != testFile;
  2036. testFile = _DtHelpFileListGetNext(NULL,testFile) )
  2037. {
  2038. _DtHelpGlobSrchVol * vol;
  2039. vol = (_DtHelpGlobSrchVol *)testFile->clientData;
  2040. if (vol && vol->showVolInList && (vol->hitCnt > 0 || vol->zeroHitsOk))
  2041. break; /* BREAK */
  2042. }
  2043. /* clean the list out if this is the first new result */
  2044. /* this presumes that files are processed in order in the list */
  2045. if (testFile == newFile)
  2046. {
  2047. DeleteListContents(&hw->help_dialog.srch);
  2048. AdjustPositionValues(newFile,0,1,True);
  2049. }
  2050. /* True: insert new item */
  2051. VolNameDisplay(hw,newFile,True);
  2052. /* Update status label */
  2053. StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0); /* FIX: False */
  2054. }
  2055. /*****************************************************************************
  2056. * Function: void SearchForPattern()
  2057. *
  2058. * Parameters:
  2059. *
  2060. * Return Value: True if pattern found, False if not found
  2061. *
  2062. * Purpose: Find a pattern in a string
  2063. *
  2064. * WARNING: may convert string to uppercase in place
  2065. * depending on which code is compiled.
  2066. *****************************************************************************/
  2067. static Boolean SearchForPattern(
  2068. char * string,
  2069. char * pattern,
  2070. int patternLen)
  2071. {
  2072. #if defined(NO_REGEX) /* don't support regex in string searches */
  2073. char * hit;
  2074. _DtHelpCeUpperCase(string);
  2075. /* FIX: make this code much faster by using an improved
  2076. pattern search algorithm, such as Rabin-Karp. */
  2077. /* hit is set to NULL if no matching char is found */
  2078. while (_DtHelpCeStrchr(string, pattern, MB_CUR_MAX, &hit) == 0)
  2079. {
  2080. if ( strncmp(hit,pattern,patternLen) == 0 )
  2081. break; /* BREAK */
  2082. else
  2083. string = hit + mblen(hit,1);
  2084. }
  2085. return (NULL != hit); /* RETURN True or False */
  2086. #else /* if NO_REGEX */
  2087. # ifndef NO_REGCOMP
  2088. regex_t re;
  2089. int ret = -1;
  2090. /* use regexec to pattern match */
  2091. /* a 0 return value indicates success */
  2092. if ( regcomp(&re,pattern,REG_NOSUB|REG_ICASE|REG_EXTENDED) == 0 )
  2093. {
  2094. /* a 0 return value indicates success */
  2095. ret = regexec(&re,string,0,NULL,0);
  2096. regfree(&re);
  2097. }
  2098. return (ret == 0); /* RETURN True or False */
  2099. # else /* NO_REGCOMP */
  2100. char *compiledRE;
  2101. char *ret = NULL;
  2102. /* a non NULL return value indicates success */
  2103. compiledRE = (char *)regcmp(pattern, (char *) NULL);
  2104. if (compiledRE)
  2105. {
  2106. /* a non NULL return value indicates success */
  2107. ret = regex(compiledRE, string);
  2108. free(compiledRE);
  2109. }
  2110. return (ret != NULL); /* RETURN True or False */
  2111. # endif /* NO_REGCOMP */
  2112. #endif /* if NO_REGEX */
  2113. }
  2114. /*****************************************************************************
  2115. * Function: void OpenVolForSearch()
  2116. *
  2117. * Parameters:
  2118. *
  2119. * Return Value: False if an error
  2120. * True if no error
  2121. *
  2122. * Purpose: Opens a volume for searching,
  2123. * gets the volume locale, if
  2124. * different from system locale,
  2125. * saves system locale in vol,
  2126. * installs volume locale
  2127. *
  2128. * Note that the system locale
  2129. *****************************************************************************/
  2130. static Boolean OpenVolForSearch(
  2131. DtHelpDialogWidget hw,
  2132. char * fullFilePath,
  2133. _DtHelpGlobSrchVol * curVol)
  2134. {
  2135. Boolean openedVolume = False;
  2136. /* open the volume if not open */
  2137. if ( NULL == curVol->volHandle )
  2138. {
  2139. _DtHelpOpenVolume(fullFilePath, &curVol->volHandle);
  2140. if (NULL == curVol->volHandle) return False; /* RETURN */
  2141. if (curVol->gotLocale == False)
  2142. {
  2143. char *ptr = NULL;
  2144. curVol->stdLocale = _DtHelpGetVolumeLocale(curVol->volHandle);
  2145. if (_DtHelpCeStrchr(curVol->stdLocale, ".", 1, &ptr) == 0)
  2146. {
  2147. ++ptr;
  2148. if (ptr == NULL || *ptr == '\0') ptr = NULL;
  2149. }
  2150. curVol->iconv3Codeset = strdup(ptr ? ptr : "UTF-8");
  2151. curVol->gotLocale = True;
  2152. }
  2153. openedVolume = True;
  2154. /* get the codeset of the application's locale, if haven't gotten it */
  2155. if ( NULL == hw->help_dialog.srch.iconv3Codeset )
  2156. _DtHelpCeGetLcCtype(NULL, NULL, &(hw->help_dialog.srch.iconv3Codeset));
  2157. /** only saves or changes the locale if necessary **/
  2158. /* create an iconv3 context to convert codeset of */
  2159. /* the volume to the codeset of the application */
  2160. if ( _DtHelpCeIconvContextSuitable(hw->help_dialog.srch.iconv3Context,
  2161. curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset) == False )
  2162. {
  2163. /* close old, open new */
  2164. _DtHelpCeIconvClose(&hw->help_dialog.srch.iconv3Context);
  2165. _DtHelpCeIconvOpen(&hw->help_dialog.srch.iconv3Context,
  2166. curVol->iconv3Codeset,hw->help_dialog.srch.iconv3Codeset,' ',' ');
  2167. }
  2168. }
  2169. /* else volume already open */
  2170. /* if just opened volume */
  2171. if (openedVolume)
  2172. {
  2173. /* we just share pointers; when freeing localeWordStr, we need to
  2174. test whether they are different before freeing */
  2175. hw->help_dialog.srch.localeWordStr = hw->help_dialog.srch.normWordStr;
  2176. }
  2177. /* get the str coll function, iff needed */
  2178. if (NULL == curVol->strcollProc)
  2179. {
  2180. /* get strcollProc for vol locale */
  2181. curVol->strcollProc = _DtHelpCeGetStrcollProc();
  2182. }
  2183. return True;
  2184. }
  2185. /*****************************************************************************
  2186. * Function: void CloseVolAfterSearch()
  2187. *
  2188. * Parameters:
  2189. *
  2190. * Return Value: Void.
  2191. *
  2192. * Purpose: Closes a volume opened for searching,
  2193. * installs system locale, if diff from volume.
  2194. *
  2195. *****************************************************************************/
  2196. static void CloseVolAfterSearch(
  2197. DtHelpDialogWidget hw,
  2198. _DtHelpGlobSrchVol * curVol)
  2199. {
  2200. /* close the volume if open */
  2201. if ( NULL != curVol->volHandle )
  2202. {
  2203. _DtHelpCloseVolume(curVol->volHandle);
  2204. curVol->volHandle = NULL;
  2205. /* free the locale word string, if allocated */
  2206. if(hw->help_dialog.srch.localeWordStr!=hw->help_dialog.srch.normWordStr)
  2207. {
  2208. XtFree(hw->help_dialog.srch.localeWordStr);
  2209. hw->help_dialog.srch.localeWordStr = NULL;
  2210. }
  2211. }
  2212. /* don't free the iconv context...may apply to the next volume */
  2213. }
  2214. /*****************************************************************************
  2215. * Function: void SearchTopic()
  2216. *
  2217. * Parameters:
  2218. *
  2219. * Return Value: Void.
  2220. *
  2221. * Purpose: Get a single topic and search for the search word in it
  2222. *
  2223. *****************************************************************************/
  2224. static void SearchTopic(
  2225. DtHelpDialogWidget hw,
  2226. _DtHelpFileEntry curFile,
  2227. _DtHelpGlobSrchVol * curVol,
  2228. char * srchWord,
  2229. int srchWordLen,
  2230. int numSearches)
  2231. {
  2232. #if 0
  2233. int i;
  2234. /* if the volume is not open; don't continue */
  2235. if ( NULL == curVol->volHandle )
  2236. return; /* RETURN */
  2237. if ( NULL == curVol->indexEntriesList )
  2238. _CEVolumeTopicList(curVol->volHandle,&curVol->indexEntriesList);
  2239. if ( NULL == curVol->volHandle || NULL == curVol->indexEntriesList )
  2240. {
  2241. curVol->topicSearchInProgress = False;
  2242. curVol->topicSearchDone = True;
  2243. curVol->indexSearchInProgress = True;
  2244. if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
  2245. return; /* RETURN */
  2246. }
  2247. curVol->topicSearchInProgress = True;
  2248. /* search the topics */
  2249. /* note that indexEntriesList[0] is correct; ptr is incremented */
  2250. /* we can increment the pointer because we don't own this memory;
  2251. the open volume does. */
  2252. for (i=0;
  2253. i < numSearches && NULL != curVol->indexEntriesList[0];
  2254. i++, curVol->indexEntriesList++ )
  2255. {
  2256. char * topicTitle = NULL;
  2257. Boolean validTopic;
  2258. validTopic = _DtHelpGetTopicTitle( curVol->volHandle,
  2259. curVol->indexEntriesList[0],&topicTitle);
  2260. if(validTopic)
  2261. {
  2262. /* look for a hit and process if there was one */
  2263. if (SearchForPattern(topicTitle,srchWord,srchWordLen) == True)
  2264. {
  2265. HitListAddFound(curFile, curVol->indexEntriesList[0], True, NULL);
  2266. }
  2267. }
  2268. /* clean up and advance to next topic */
  2269. XtFree(topicTitle);
  2270. curVol->searchedCnt++;
  2271. } /* for all topics to search */
  2272. #endif
  2273. if ( NULL == curVol->indexEntriesList /* no topics queried */
  2274. || NULL == curVol->indexEntriesList[0] ) /* no more topics available */
  2275. {
  2276. /* hand off to next stage */
  2277. curVol->indexEntriesList = NULL;
  2278. curVol->topicSearchInProgress = False;
  2279. curVol->topicSearchDone = True;
  2280. curVol->indexSearchInProgress = True;
  2281. }
  2282. }
  2283. /*****************************************************************************
  2284. * Function: void SearchIndex()
  2285. *
  2286. * Parameters:
  2287. *
  2288. * Return Value: void
  2289. *
  2290. * Purpose: Get a single Index and search for the search word in it
  2291. *
  2292. * Commentary: There are two strings for each index entry.
  2293. * One string is the straight text in
  2294. * the codeset of the volume. The
  2295. * other string is a XmString that
  2296. * has a font tag that will allow
  2297. * it to be displayed in the
  2298. * correct codeset.
  2299. *
  2300. * Preconditions: This code requires that the volume to be search
  2301. * has already been opened [OpenVolForSearch()],
  2302. * that the locale of the volume has been installed,
  2303. * and that the search word is in the same code
  2304. * set as the volume and has been converted to
  2305. * upper case.
  2306. *
  2307. *****************************************************************************/
  2308. static void SearchIndex(
  2309. DtHelpDialogWidget hw,
  2310. _DtHelpFileEntry curFile,
  2311. _DtHelpGlobSrchVol * curVol,
  2312. _DtHelpCeIconvContext iconvContext,
  2313. char * srchWord,
  2314. int srchWordLen,
  2315. int numSearches)
  2316. {
  2317. int i;
  2318. char * indexEntry = NULL;
  2319. size_t entryLen = 100; /* starting size */
  2320. Arg args[5];
  2321. /* if the volume is not open; don't continue */
  2322. if ( NULL == curVol->volHandle )
  2323. return; /* RETURN */
  2324. /* get the XmStrings of the entries */
  2325. if ( NULL == curVol->indexXmStrsList )
  2326. {
  2327. XmFontList fontList = NULL;
  2328. Boolean mod = False;
  2329. int numEntries = 0;
  2330. /* get results font list */
  2331. XtSetArg(args[0], XmNfontList, &fontList);
  2332. XtGetValues(hw->help_dialog.srch.resultList,args,1);
  2333. #if 1
  2334. /* Don't need to copy, _DtHelpFormatVolumeTitle copies
  2335. * before modifying.
  2336. */
  2337. /* work with copy, because FontListAppendEntry() destroys input FL */
  2338. fontList = XmFontListCopy(fontList);
  2339. #endif
  2340. /* get the entries */
  2341. _DtHelpFormatIndexEntries(hw->help_dialog.help.pDisplayArea,
  2342. curVol->volHandle,&numEntries, &curVol->indexXmStrsList,
  2343. &fontList, &mod);
  2344. /* install the changed list */
  2345. if (mod)
  2346. {
  2347. XtSetArg(args[0], XmNfontList, fontList);
  2348. XtSetValues(hw->help_dialog.srch.resultList,args,1);
  2349. if (fontList) XmFontListFree(fontList);
  2350. }
  2351. }
  2352. /* get the pure strings for searching */
  2353. if ( NULL == curVol->indexEntriesList )
  2354. {
  2355. /* recall that the array and strings pointed to by
  2356. the indexEntriesList is owned by the open volume */
  2357. _DtHelpCeGetKeywordList(curVol->volHandle,&curVol->indexEntriesList);
  2358. /* and re-init curIndexXmStr */
  2359. curVol->curIndexXmStr = curVol->indexXmStrsList;
  2360. }
  2361. if ( NULL == curVol->volHandle
  2362. || NULL == curVol->indexEntriesList
  2363. || NULL == curVol->indexXmStrsList )
  2364. {
  2365. curVol->indexSearchInProgress = False;
  2366. curVol->indexSearchDone = True;
  2367. curVol->searchCompleted = True;
  2368. if ( NULL == curVol->volHandle ) curVol->searchCompleted = True;
  2369. return; /* RETURN */
  2370. }
  2371. curVol->indexSearchInProgress = True;
  2372. /* alloc memory for index processing */
  2373. indexEntry = XtMalloc(sizeof(char)*(entryLen+1));
  2374. if (NULL == indexEntry) return; /* RETURN */
  2375. /* get a index entry */
  2376. for (i=0;
  2377. i < numSearches && NULL != curVol->indexEntriesList[0];
  2378. i++, curVol->indexEntriesList++, curVol->curIndexXmStr++ )
  2379. {
  2380. /* prevent overflow of buffer */
  2381. if (strlen(curVol->indexEntriesList[0]) > entryLen)
  2382. {
  2383. entryLen = strlen(curVol->indexEntriesList[0]) + 50;
  2384. indexEntry = XtRealloc(indexEntry,entryLen+1);
  2385. if (NULL == indexEntry) break; /* BREAK */
  2386. }
  2387. indexEntry[0] = EOS; /* init to empty string */
  2388. /* look for a hit and process if there was one */
  2389. /* if srchWord is NULL, all entries are hits */
  2390. /* copy, and possible iconv, the index string into the */
  2391. /* the codeset of srchWord (the application) */
  2392. if ( NULL == srchWord
  2393. || ( _DtHelpCeIconvStr(iconvContext,curVol->indexEntriesList[0],
  2394. &indexEntry, &entryLen,indexEntry,entryLen) == 0
  2395. && SearchForPattern(indexEntry, srchWord, srchWordLen) == True ) )
  2396. {
  2397. _DtHelpGlobSrchHit * hit = NULL;
  2398. char * * topicIdList;
  2399. HitListAddFound ( curFile, curVol->curIndexXmStr[0],
  2400. curVol->indexEntriesList[0], True, &hit);
  2401. /* topicIdList is set but not allocated & need not be freed */
  2402. hit->topicCnt = _DtHelpCeFindKeyword(curVol->volHandle,
  2403. hit->indexEntry,&topicIdList);
  2404. }
  2405. /* clean up and advance to next topic */
  2406. curVol->searchedCnt++;
  2407. }
  2408. if ( NULL == curVol->indexEntriesList /*no topics queried*/
  2409. || NULL == curVol->indexEntriesList[0] )/*no more index entries avail*/
  2410. {
  2411. /* hand off to next stage */
  2412. curVol->indexEntriesList = NULL; /* init */
  2413. curVol->curIndexXmStr = curVol->indexXmStrsList; /* re-init */
  2414. curVol->indexSearchInProgress = False;
  2415. curVol->indexSearchDone = True;
  2416. curVol->searchCompleted = True;
  2417. }
  2418. XtFree(indexEntry);
  2419. }
  2420. /*****************************************************************************
  2421. * Function: void SearchVolume()
  2422. *
  2423. * Parameters:
  2424. *
  2425. * Return Value: Void.
  2426. *
  2427. * Purpose: do the search operation
  2428. * This routine does incremental search--it searchs
  2429. * a little, then returns to allow further processing.
  2430. * It is called whenever Xt detects no other events.
  2431. *
  2432. *****************************************************************************/
  2433. static void SearchVolume(
  2434. DtHelpDialogWidget hw,
  2435. _DtHelpFileEntry curFile,
  2436. _DtHelpGlobSrchVol * curVol,
  2437. int numSearches)
  2438. {
  2439. XmString labelString;
  2440. Arg args[10];
  2441. char buf[50];
  2442. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  2443. if (hw->help_dialog.srch.selectionDlg)
  2444. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  2445. /* Process according to state */
  2446. if ( curVol->nothingDone )
  2447. {
  2448. curVol->nothingDone = False;
  2449. curVol->topicSearchInProgress = True;
  2450. /* Update the search status string */
  2451. sprintf(buf,(char *)_DTGETMESSAGE(GSSET,18,
  2452. "Searching... Volumes remaining: %d"),
  2453. hw->help_dialog.srch.volLeftCnt);
  2454. labelString = XmStringCreateLocalized(buf);
  2455. XtSetArg(args[0],XmNlabelString,labelString);
  2456. XtSetValues (hw->help_dialog.srch.statusLabel, args, 1);
  2457. XmStringFree(labelString);
  2458. XmUpdateDisplay((Widget) hw->help_dialog.srch.statusLabel);
  2459. }
  2460. OpenVolForSearch(hw,curFile->fullFilePath,curVol);
  2461. if ( curVol->topicSearchInProgress )
  2462. {
  2463. SearchTopic(hw, curFile,curVol,hw->help_dialog.srch.localeWordStr,
  2464. hw->help_dialog.srch.wordFieldLen, numSearches);
  2465. }
  2466. /* NOTE: because this isn't an "else if", we could potentially
  2467. search for 2*numSearches; but I know that I've disabled the
  2468. topic search. Furthermore, my code depends upon the possibility
  2469. of searching an entire volume in one call to the routine, if
  2470. desired, and having an else if would break that.
  2471. */
  2472. if ( curVol->indexSearchInProgress )
  2473. {
  2474. char * srchWord;
  2475. srchWord = hw->help_dialog.srch.localeWordStr;
  2476. /* FullIndex search indicated by a null search word string */
  2477. if (hw->help_dialog.srch.fullIndex) srchWord = NULL;
  2478. SearchIndex(hw, curFile, curVol, hw->help_dialog.srch.iconv3Context,
  2479. srchWord, hw->help_dialog.srch.wordFieldLen, numSearches);
  2480. }
  2481. /* If search was completed, update dependent stuff */
  2482. if (curVol->searchCompleted)
  2483. {
  2484. /* handle completion */
  2485. CloseVolAfterSearch(hw,curVol);
  2486. curVol->indexEntriesList = NULL; /* mem not owned by GlobSrch */
  2487. if (hw->help_dialog.srch.fullIndex)
  2488. curVol->gatheredFullIndex = True;
  2489. hw->help_dialog.srch.volLeftCnt--;
  2490. if (hw->help_dialog.srch.volLeftCnt < 0)
  2491. hw->help_dialog.srch.volLeftCnt = 0;
  2492. }
  2493. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  2494. if (hw->help_dialog.srch.selectionDlg)
  2495. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  2496. }
  2497. /*****************************************************************************
  2498. * Function: void SearchFile()
  2499. *
  2500. * Parameters:
  2501. *
  2502. * Return Value: Void.
  2503. *
  2504. * Purpose: do the search operation on an entire file
  2505. * It searches the entire file at once
  2506. * and displays the results in the list.
  2507. *
  2508. *****************************************************************************/
  2509. static void SearchFile(
  2510. DtHelpDialogWidget hw,
  2511. _DtHelpFileEntry file)
  2512. {
  2513. _DtHelpGlobSrchVol * vol;
  2514. /* get volume info, adding if necessary */
  2515. vol = (_DtHelpGlobSrchVol *) file->clientData;
  2516. /* (T,T,F): enable search, enable display, any volume */
  2517. if (NULL == vol) AddVolInfoToFile(file, True, True, False);
  2518. vol = (_DtHelpGlobSrchVol *) file->clientData;
  2519. if (NULL == vol) return;
  2520. /* conduct search of entire volume in one call */
  2521. hw->help_dialog.srch.volLeftCnt = 1;
  2522. vol->searchThisVolume = True;
  2523. vol->showVolInList = True;
  2524. vol->zeroHitsOk = True;
  2525. SearchVolume(hw,file,vol,INT_MAX);
  2526. /* update status */
  2527. StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);/*FIX: False*/
  2528. /* update the list to show the volume */
  2529. AdjustPositionValues(file,0,1,True);
  2530. /* True: do insert new item */
  2531. VolNameDisplay(hw,file,True);
  2532. if (vol->showHitsWithVol)
  2533. {
  2534. VolHitsDisplay(hw,file);
  2535. /* False: don't insert new item */
  2536. VolNameDisplay(hw,file,False);
  2537. }
  2538. }
  2539. /*****************************************************************************
  2540. * Function: void DoBackgroundSearchWP(
  2541. * XtPointer clientData)
  2542. *
  2543. *
  2544. *
  2545. * Parameters:
  2546. *
  2547. * Return Value: Void.
  2548. *
  2549. * Purpose: do the search operation in the background
  2550. * This routine does incremental search--it searchs
  2551. * a little, then returns to allow further processing.
  2552. * It is called whenever Xt detects no other events.
  2553. *
  2554. *****************************************************************************/
  2555. static Boolean DoBackgroundSearchWP(
  2556. XtPointer clientData)
  2557. {
  2558. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2559. _DtHelpFileEntry curFile;
  2560. _DtHelpGlobSrchVol * curVol = NULL;
  2561. if ( 0 == hw->help_dialog.srch.volLeftCnt )
  2562. goto searchComplete; /* GOTO: done! */
  2563. /* get file to work on */
  2564. curFile = hw->help_dialog.srch.curSrchVol;
  2565. if ( NULL == curFile )
  2566. {
  2567. curFile = GetNextSearchFileAndDisplayCompleted(
  2568. hw, hw->help_dialog.srch.volListHead, NULL);
  2569. if ( NULL == curFile ) goto searchComplete; /* GOTO: done */
  2570. hw->help_dialog.srch.curSrchVol = curFile;
  2571. } /* if no current file */
  2572. /* get volume info */
  2573. curVol = (_DtHelpGlobSrchVol *) curFile->clientData;
  2574. #define NUM_SEARCHES_PER_CALL 30
  2575. SearchVolume(hw,curFile,curVol,NUM_SEARCHES_PER_CALL);
  2576. /* If search was completed, update dependent stuff */
  2577. if (curVol->searchCompleted)
  2578. {
  2579. /* update the search results list */
  2580. /* True: adjust count beginning with this file */
  2581. if (curVol->hitCnt > 0 || curVol->zeroHitsOk)
  2582. {
  2583. /* record that a hit found */
  2584. if ( curVol->hitCnt > 0
  2585. || ( curVol->zeroHitsOk
  2586. && _DtHelpGlobSrchSelectedVolumes == hw->help_dialog.srch.srchSources))
  2587. hw->help_dialog.srch.hitsFound = True;
  2588. /* update the list to show the volume */
  2589. AdjustPositionValues(curFile,0,1,True);
  2590. ResultsListUpdate(hw,curFile);
  2591. /* update the list to show the hits? */
  2592. if (hw->help_dialog.srch.srchSources == _DtHelpGlobSrchCurVolume)
  2593. {
  2594. VolHitsDisplay(hw,curFile);
  2595. /* False: don't insert new item */
  2596. VolNameDisplay(hw,curFile,False);
  2597. }
  2598. XmUpdateDisplay((Widget) hw->help_dialog.srch.resultList);
  2599. }
  2600. /* prepare for next search */
  2601. hw->help_dialog.srch.curSrchVol =
  2602. GetNextSearchFileAndDisplayCompleted(hw,NULL,curFile);
  2603. } /* if search completed */
  2604. /* return */
  2605. if ( hw->help_dialog.srch.volLeftCnt > 0
  2606. || False == curVol->searchCompleted )
  2607. return False; /* RETURN: False ==> continue processing */
  2608. /* Do this when no more files are left to search */
  2609. searchComplete:
  2610. {
  2611. XmPushButtonCallbackStruct status;
  2612. /* zero search data before stopping */
  2613. hw->help_dialog.srch.volLeftCnt = 0; /* just in case */
  2614. hw->help_dialog.srch.curSrchVol = NULL; /* just in case */
  2615. /* generate a fake event to reset the dialog */
  2616. status.reason = XmCR_ACTIVATE;
  2617. status.event = NULL;
  2618. status.click_count = 1;
  2619. StopSearchCB(hw->help_dialog.srch.actionBtn,
  2620. (XtPointer)hw,(XtPointer)&status);
  2621. return True; /* RETURN: True ==> stop processing */
  2622. }
  2623. }
  2624. /*****************************************************************************
  2625. * Function: void StartSearchCB(Widget w,
  2626. * XtPointer clientData,
  2627. * XtPointer callData);
  2628. *
  2629. *
  2630. *
  2631. * Parameters:
  2632. *
  2633. * Return Value: Void.
  2634. *
  2635. * Purpose: Create a new user bookmark
  2636. *
  2637. * Warning: This CB is also used by the volume selection buttons
  2638. * to activate a search when they are selected. The routine
  2639. * cannot rely upon the w or callData params. The clientData
  2640. * will always be the help widget.
  2641. *****************************************************************************/
  2642. static void StartSearchCB(
  2643. Widget w, /* don't use */
  2644. XtPointer clientData,
  2645. XtPointer callData) /* don't use */
  2646. {
  2647. char *srchWord = NULL;
  2648. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2649. XtAppContext appCntx;
  2650. int n;
  2651. Arg args[5];
  2652. /* set state of start button correctly */
  2653. UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
  2654. /* if help content isn't a volume, it has no index */
  2655. if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
  2656. && hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC )
  2657. return; /* RETURN */
  2658. /* retrieve the name */
  2659. srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
  2660. /* test for empty (also emtpy spaces) and only process if not emtpy */
  2661. _DtHelpCeCompressSpace(srchWord);
  2662. if ( (strlen(srchWord) > (size_t) 0 || hw->help_dialog.srch.fullIndex)
  2663. && hw->help_dialog.srch.workProcId == 0)
  2664. /* test on workProcId prevents multiple activations due to
  2665. race condition on desensitizing the start button */
  2666. {
  2667. _DtHelpTurnOnHourGlass(XtParent(hw));
  2668. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  2669. if (hw->help_dialog.srch.selectionDlg)
  2670. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  2671. /*XtSetSensitive (hw->help_dialog.srch.actionBtn,False);*/
  2672. XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False);
  2673. XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,False);
  2674. XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,False);
  2675. XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
  2676. /* 9/26/94: these two XtSetArgs (and following SetValues) cause a core dump
  2677. for the SunOS 5.3 optimized executable. It isn't a problem for the
  2678. non-optimized or debuggable versions or any versions on AIX 3.2 or
  2679. HP-UX 9.05. */
  2680. #if !defined(sun)
  2681. n = 0;
  2682. XtSetArg(args[n],XmNeditable,False); n++;
  2683. XtSetArg(args[n],XmNcursorPositionVisible,False); n++;
  2684. XtSetValues (hw->help_dialog.srch.wordField, args, n);
  2685. #endif
  2686. XmUpdateDisplay(hw->help_dialog.srch.srchForm);
  2687. /* process the source selection and retain in widget srchWord memory */
  2688. PrepSearchSourceData(hw, srchWord);
  2689. /* activate search thread; do it even with a 0 count, because the
  2690. process reactivates the dialog after search is completed */
  2691. appCntx = XtWidgetToApplicationContext((Widget) hw);
  2692. hw->help_dialog.srch.workProcId =
  2693. XtAppAddWorkProc(appCntx,DoBackgroundSearchWP, (XtPointer) hw);
  2694. hw->help_dialog.srch.searchInProgress = True;
  2695. /* don't free srchWord */
  2696. /* turn on "Stop" label */
  2697. UpdateActionButtonLabel(hw,NULL,False);
  2698. _DtHelpTurnOffHourGlass(XtParent(hw));
  2699. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  2700. if (hw->help_dialog.srch.selectionDlg)
  2701. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  2702. }
  2703. else
  2704. {
  2705. if ( strlen(srchWord) == 0 )
  2706. StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
  2707. XtFree(srchWord);
  2708. }
  2709. }
  2710. /*****************************************************************************
  2711. * Function: void StartSelectedVolumeSearchCB(Widget w,
  2712. * XtPointer clientData,
  2713. * XtPointer callData);
  2714. *
  2715. *
  2716. *
  2717. * Parameters:
  2718. *
  2719. * Return Value: Void.
  2720. *
  2721. * Purpose: Begin a search on the selected volume
  2722. *
  2723. *****************************************************************************/
  2724. static void StartSelectedVolumeSearchCB(
  2725. Widget w,
  2726. XtPointer clientData,
  2727. XtPointer callData)
  2728. {
  2729. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2730. _DtHelpFileEntry file;
  2731. String srchWord;
  2732. Boolean noSelectedFiles = True;
  2733. /* if not full index search */
  2734. if (hw->help_dialog.srch.fullIndex == False)
  2735. {
  2736. /* get the current contents of the search word field */
  2737. srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
  2738. /* test the word ; False=dontUpdate--do this in PrepSearchSourceData() */
  2739. if ( CheckSearchWord(hw,srchWord,False) == True )
  2740. { /* word has changed since last search; do a whole new search */
  2741. StartSearchCB(NULL,(XtPointer) hw, NULL);
  2742. return; /* RETURN */
  2743. }
  2744. /* if the text field is empty, do nothing */
  2745. if ( strlen(hw->help_dialog.srch.normWordStr) == 0 )
  2746. return; /* RETURN */
  2747. }
  2748. /* set this to true to counteract False if no hits */
  2749. hw->help_dialog.srch.hitsFound = True;
  2750. /* Word is the same, just the selection has changed. */
  2751. /* Determine which one was selected or deselected */
  2752. for ( file = hw->help_dialog.srch.volListHead;
  2753. NULL != file;
  2754. file = _DtHelpFileListGetNext(NULL,file) )
  2755. {
  2756. _DtHelpGlobSrchVol * vol;
  2757. vol = (_DtHelpGlobSrchVol *) file->clientData;
  2758. if (NULL == vol) continue;
  2759. /* update flag */
  2760. if (file->fileSelected) noSelectedFiles = False;
  2761. /* test for contradictory flags; fileSelected reflects dialog list */
  2762. if (file->fileSelected != vol->showVolInList)
  2763. {
  2764. /* file has been deselected */
  2765. if (False == file->fileSelected)
  2766. {
  2767. if (vol->showVolInList)
  2768. {
  2769. /* update list: delete hits, topics, and volume title */
  2770. if (vol->hitsDisplayed) VolHitsUndisplay(hw,file);
  2771. /* delete hits first, then volume */
  2772. XmListDeletePos(
  2773. hw->help_dialog.srch.resultList,vol->startPosition);
  2774. AdjustPositionValues(file, 0, -1, True);
  2775. vol->showVolInList = False;
  2776. vol->searchThisVolume = False;
  2777. }
  2778. }
  2779. else /* file has been selected */
  2780. {
  2781. SearchFile(hw,file);
  2782. } /* if file de/selected */
  2783. } /* if contradictory flags */
  2784. } /* for all volumes */
  2785. /* update state */
  2786. if (noSelectedFiles) StatusLabelUpdate(hw,NO_VOL_STATUS,True,0);
  2787. }
  2788. /*****************************************************************************
  2789. * Function: void UpdateSearchStartStatusCB(Widget w,
  2790. * XtPointer clientData,
  2791. * XtPointer callData);
  2792. *
  2793. *
  2794. *
  2795. * Parameters:
  2796. *
  2797. * Return Value: Void.
  2798. *
  2799. * Purpose: update the status of the search status button
  2800. * Routine is called whenever text is changed in the search
  2801. * word field.
  2802. *
  2803. *****************************************************************************/
  2804. static void UpdateSearchStartStatusCB(
  2805. Widget w,
  2806. XtPointer clientData,
  2807. XtPointer callData)
  2808. {
  2809. char *srchWord = NULL;
  2810. /*XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) callData;*/
  2811. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2812. Boolean newState;
  2813. /* retrieve the name */
  2814. srchWord = XmTextFieldGetString(hw->help_dialog.srch.wordField);
  2815. /* test for empty (also emtpy spaces) */
  2816. _DtHelpCeCompressSpace(srchWord);
  2817. /* FIX: change the locale from the volume locale back to the system
  2818. locale temporarily (if not already in that locale) */
  2819. _DtHelpCeUpperCase(srchWord);
  2820. /* only sensitize if working on a help volume and word is not emtpy
  2821. or not needed */
  2822. newState = True;
  2823. if ( ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
  2824. && hw->help_dialog.display.helpType != DtHELP_TYPE_TOPIC)
  2825. || ( strlen(srchWord) == (size_t) 0
  2826. && hw->help_dialog.srch.fullIndex == False))
  2827. newState = False;
  2828. XtSetSensitive (hw->help_dialog.srch.actionBtn,newState);
  2829. /* if word has changed from word of previous search, change to Start */
  2830. UpdateActionButtonLabel(hw,srchWord,True);
  2831. XtFree(srchWord);
  2832. }
  2833. /*****************************************************************************
  2834. * Function: void StopSearchCB(Widget w,
  2835. * XtPointer clientData,
  2836. * XtPointer callData);
  2837. *
  2838. *
  2839. *
  2840. * Parameters:
  2841. *
  2842. * Return Value: Void.
  2843. *
  2844. * Purpose: Stop the search
  2845. *
  2846. *****************************************************************************/
  2847. static void StopSearchCB(
  2848. Widget w,
  2849. XtPointer clientData,
  2850. XtPointer callData)
  2851. {
  2852. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2853. int n;
  2854. Arg args[10];
  2855. Boolean cur;
  2856. /* stop the search thread */
  2857. if(hw->help_dialog.srch.workProcId != 0)
  2858. XtRemoveWorkProc(hw->help_dialog.srch.workProcId);
  2859. hw->help_dialog.srch.workProcId = 0;
  2860. hw->help_dialog.srch.searchInProgress = False;
  2861. /* update statuses */
  2862. #ifdef OLD_WAY
  2863. XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,
  2864. hw->help_dialog.srch.curVolRadBtnSens);
  2865. #else
  2866. XtSetSensitive (hw->help_dialog.srch.curVolRadBtn, TRUE);
  2867. #endif
  2868. XtSetSensitive (hw->help_dialog.srch.allVolRadBtn,True);
  2869. XtSetSensitive (hw->help_dialog.srch.selVolRadBtn,True);
  2870. n = 0;
  2871. XtSetArg(args[n],XmNeditable,True); n++;
  2872. XtSetArg(args[n],XmNcursorPositionVisible,True); n++;
  2873. XtSetValues (hw->help_dialog.srch.wordField, args, n);
  2874. /* update select btn status; only when selected and dialog closed */
  2875. XtSetArg(args[0],XmNset,&cur);
  2876. XtGetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
  2877. XtSetSensitive(hw->help_dialog.srch.selectBtn,
  2878. cur && ( NULL == hw->help_dialog.srch.selectionDlg
  2879. || !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
  2880. /* set the action button label appropriately */
  2881. UpdateActionButtonLabel(hw,hw->help_dialog.srch.normWordStr,True);
  2882. /* post message of results */
  2883. StatusLabelUpdate(hw,SEARCH_RESULTS_STATUS,True,0);
  2884. }
  2885. /*****************************************************************************
  2886. * Function: void ActionButtonCB(Widget w,
  2887. * XtPointer clientData,
  2888. * XtPointer callData);
  2889. *
  2890. *
  2891. *
  2892. * Parameters:
  2893. *
  2894. * Return Value: Void.
  2895. *
  2896. * Purpose: Act upon the action
  2897. *
  2898. *****************************************************************************/
  2899. static void ActionButtonCB(
  2900. Widget w,
  2901. XtPointer clientData,
  2902. XtPointer callData)
  2903. {
  2904. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2905. if ( hw->help_dialog.srch.searchInProgress == False )
  2906. StartSearchCB(w,clientData,callData);
  2907. else
  2908. StopSearchCB(w,clientData,callData);
  2909. }
  2910. #ifdef not_used
  2911. /*****************************************************************************
  2912. * Function: void GotoResultCB(Widget w,
  2913. * XtPointer clientData,
  2914. * XtPointer callData);
  2915. *
  2916. *
  2917. *
  2918. * Parameters:
  2919. *
  2920. * Return Value: Void.
  2921. *
  2922. * Purpose: Goto a result topic
  2923. *
  2924. *****************************************************************************/
  2925. static void GotoResultCB(
  2926. Widget w,
  2927. XtPointer clientData,
  2928. XtPointer callData)
  2929. {
  2930. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  2931. char * helpFile = NULL;
  2932. int * topicPosList=NULL;
  2933. int topicPosition;
  2934. Boolean status;
  2935. int i;
  2936. /* Determine the item selected and find that item in our list */
  2937. status = XmListGetSelectedPos(hw->help_dialog.srch.resultList, &topicPosList,&i);
  2938. /* if true, an item selected */
  2939. if (status && topicPosList)
  2940. {
  2941. _DtHelpGlobSrchHit * entry = NULL;
  2942. _DtHelpFileEntry file = NULL;
  2943. char * locationId = NULL;
  2944. topicPosition = topicPosList[0] - 1; /* convert to 0 based */
  2945. XtFree((String)topicPosList);
  2946. /* Get the entry */
  2947. HitListGetNth(hw->help_dialog.srch.volListHead,
  2948. topicPosition,&file,&entry,&locationId,&helpFile);
  2949. /* jump to selected location */
  2950. XtFree(hw->help_dialog.display.locationId);
  2951. hw->help_dialog.display.locationId = XtNewString(locationId);
  2952. XtFree(hw->help_dialog.display.helpVolume);
  2953. hw->help_dialog.display.helpVolume = XtNewString(helpFile);
  2954. hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
  2955. hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
  2956. _DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
  2957. }
  2958. else
  2959. {
  2960. if (topicPosList) XtFree((String)topicPosList);
  2961. /* FIX: Put up a message to suggest selecting an item first */
  2962. /* Don't close the dialog */
  2963. }
  2964. }
  2965. #endif /* not_used */
  2966. #if 0 /* save--used in code commented out elsewhere in this file */
  2967. /*****************************************************************************
  2968. * Function: void CloseHelpCB()
  2969. *
  2970. * Parameters:
  2971. *
  2972. * Return Value: Void.
  2973. *
  2974. * Purpose: Close and destroy the help widget
  2975. *
  2976. *****************************************************************************/
  2977. static void CloseHelpCB(
  2978. Widget w,
  2979. XtPointer clientData,
  2980. XtPointer callData)
  2981. {
  2982. XtUnmanageChild(w);
  2983. XtDestroyWidget(w);
  2984. }
  2985. #endif /* save--used in code commented out elsewhere in this file */
  2986. /*****************************************************************************
  2987. * Function: void GotoLocation(hw,helpVolume,location)
  2988. *
  2989. * Parameters:
  2990. *
  2991. * Return Value: Void.
  2992. *
  2993. * Purpose: Goto a topic by opening a new help dialog window
  2994. *
  2995. *****************************************************************************/
  2996. static void GotoLocation(
  2997. DtHelpDialogWidget hw,
  2998. char * helpVolume,
  2999. char * locationId)
  3000. {
  3001. #if 0 /* don't delete...useful as reference */
  3002. {
  3003. Widget helpDlg;
  3004. Arg args[15];
  3005. int n;
  3006. /* This opens a new help window on the topic */
  3007. n = 0;
  3008. XtSetArg( args[n], XmNtitle, "Help" ); n++;
  3009. XtSetArg( args[n], DtNhelpType, DtHELP_TYPE_TOPIC ); n++;
  3010. XtSetArg( args[n], DtNlocationId, locationId ); n++;
  3011. XtSetArg( args[n], DtNhelpVolume, helpVolume ); n++;
  3012. helpDlg = DtCreateHelpDialog(XtParent(hw),"mainHelpDialog",args,n);
  3013. XtAddCallback(helpDlg,DtNcloseCallback,CloseHelpCB,helpDlg);
  3014. XtManageChild(helpDlg);
  3015. }
  3016. #else
  3017. {
  3018. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  3019. if (hw->help_dialog.srch.selectionDlg)
  3020. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  3021. /* jump to selected location in same window */
  3022. XtFree(hw->help_dialog.display.locationId);
  3023. hw->help_dialog.display.locationId = XtNewString(locationId);
  3024. XtFree(hw->help_dialog.display.helpVolume);
  3025. hw->help_dialog.display.helpVolume = XtNewString(helpVolume);
  3026. hw->help_dialog.ghelp.volumeFlag = False; /* force search for volume */
  3027. hw->help_dialog.display.helpType = DtHELP_TYPE_TOPIC;
  3028. _DtHelpSetupDisplayType(hw, TRUE, DtHISTORY_AND_JUMP);
  3029. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  3030. if (hw->help_dialog.srch.selectionDlg)
  3031. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.selectionDlg));
  3032. }
  3033. #endif
  3034. }
  3035. /*****************************************************************************
  3036. * Function: void ProcessResultSelectionCB(Widget w,
  3037. * XtPointer clientData,
  3038. * XtPointer callData);
  3039. *
  3040. *
  3041. *
  3042. * Parameters:
  3043. *
  3044. * Return Value: Void.
  3045. *
  3046. * Purpose: Process user selection of an item in the result List.
  3047. *
  3048. *****************************************************************************/
  3049. static void ProcessResultSelectionCB(
  3050. Widget w,
  3051. XtPointer clientData,
  3052. XtPointer callData)
  3053. {
  3054. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  3055. int * topicPosList = NULL;
  3056. int topicPosition;
  3057. Boolean status;
  3058. int n;
  3059. /* Determine the item selected and find that item in our list */
  3060. status = XmListGetSelectedPos(
  3061. hw->help_dialog.srch.resultList, &topicPosList,&n);
  3062. /* if true, an item selected */
  3063. if (status && topicPosList)
  3064. {
  3065. _DtHelpFileEntry file = NULL;
  3066. _DtHelpGlobSrchHit * hit = NULL;
  3067. char * locationId = NULL;
  3068. char * helpFile = NULL;
  3069. topicPosition = topicPosList[0]; /* 1 based */
  3070. XtFree((String)topicPosList);
  3071. /* Get the entry */
  3072. if ( HitListGetNth(hw->help_dialog.srch.volListHead,
  3073. topicPosition,&file,&hit,&locationId,&helpFile) == 0 )
  3074. {
  3075. _DtHelpTurnOnHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  3076. /* deactivate it */
  3077. XmListDeselectPos(hw->help_dialog.srch.resultList,topicPosition);
  3078. /* was a volume item selected? */
  3079. if ( NULL == hit )
  3080. {
  3081. _DtHelpGlobSrchVol * vol = (_DtHelpGlobSrchVol *) file->clientData;
  3082. if (vol->hitCnt > 0)
  3083. {
  3084. if (False == vol->hitsDisplayed)
  3085. {
  3086. VolHitsDisplay(hw,file); /* toggle state */
  3087. }
  3088. else
  3089. {
  3090. VolHitsUndisplay(hw,file);
  3091. vol->showHitsWithVol = False;
  3092. }
  3093. /* update the volume label to show the state */
  3094. /* False: don't insert hw item */
  3095. VolNameDisplay(hw,file,False);
  3096. }
  3097. /* else don't otherwise handle a 0-hits volume */
  3098. }
  3099. /* was an expandable index selected */
  3100. else if (NULL == locationId && hit->topicCnt > 1)
  3101. {
  3102. int topicCnt = 0;
  3103. /* if we're turning them on, build a list */
  3104. if (False == hit->topicsDisplayed)
  3105. {
  3106. topicCnt = HitTopicsDisplay(hw,file,hit,topicPosition+1);
  3107. }
  3108. else
  3109. {
  3110. topicCnt = - HitTopicsUndisplay(hw,file,hit,topicPosition+1);
  3111. hit->showTopicsWithHit = False;
  3112. }
  3113. /* update the hit label to show the state; False--don't insert */
  3114. HitNameDisplay(hw,file,hit,topicPosition,False);
  3115. /* add to all the following */
  3116. if (topicCnt != 0)
  3117. {
  3118. /* adjust count beginning with next file with hits */
  3119. AdjustPositionValues(file, 0, topicCnt, True);
  3120. }
  3121. }
  3122. /* a location or index with one topic was selected */
  3123. else
  3124. {
  3125. /* if a single click, goto the location */
  3126. if (hit->topicCnt == 1)
  3127. {
  3128. if ( HitLoadTopics(hw,file,hit) == 0 )
  3129. {
  3130. GotoLocation(hw, file->fullFilePath, hit->topicIdList[0]);
  3131. HitFree(hit,False); /*release what was loaded 3 lines up*/
  3132. }
  3133. else
  3134. { /* volume couldn't be opened or some other error */
  3135. /* FIX: error message */
  3136. }
  3137. } /* if an index with a single topic */
  3138. else
  3139. { /* a location from an open multi-topic index entry */
  3140. GotoLocation(hw, file->fullFilePath, locationId);
  3141. }
  3142. } /* else index with one topic or topic was selected */
  3143. /* finish up processing a selection */
  3144. _DtHelpTurnOffHourGlass(XtParent(hw->help_dialog.srch.srchForm));
  3145. } /* got the nth item */
  3146. }
  3147. else /* could not find the nth hit */
  3148. {
  3149. if (topicPosList) XtFree((String)topicPosList);
  3150. }
  3151. }
  3152. /*****************************************************************************
  3153. * Function: void CloseVolSelDialogCB(Widget w,
  3154. * XtPointer clientData,
  3155. * XtPointer callData);
  3156. *
  3157. * Parameters:
  3158. *
  3159. * Return Value: Void.
  3160. *
  3161. * Purpose: Resets the selection dialog variable to NULL
  3162. *
  3163. *****************************************************************************/
  3164. static void CloseVolSelDialogCB(
  3165. Widget widget,
  3166. XtPointer clientData,
  3167. XtPointer callData)
  3168. {
  3169. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  3170. /* unmanage & destroy the dialog zero the variable */
  3171. if ( hw->help_dialog.srch.selectionDlg
  3172. && XtIsManaged(hw->help_dialog.srch.selectionDlg) )
  3173. XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
  3174. /* start a search to be sure we got all changes; FIX: need this??? */
  3175. /*StartSearchCB(NULL,hw,NULL);*/
  3176. XtSetSensitive(hw->help_dialog.srch.selectBtn,True);
  3177. /* change focus */
  3178. if (hw->help_dialog.srch.hitsFound == True)
  3179. XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
  3180. else
  3181. XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
  3182. }
  3183. /*****************************************************************************
  3184. * Function: void CreateVolSelDialog(
  3185. *
  3186. * Parameters:
  3187. *
  3188. * Return Value: Void.
  3189. *
  3190. * Purpose: Creates selection dialog to chose volumes
  3191. *
  3192. *****************************************************************************/
  3193. static void CreateVolSelDialog(
  3194. DtHelpDialogWidget hw)
  3195. {
  3196. Widget selDlg;
  3197. _DtHelpFileDlgChildren dlgChld;
  3198. Atom wm_delete_window;
  3199. Arg args[5];
  3200. /* desensitize the button */
  3201. XtSetSensitive(hw->help_dialog.srch.selectBtn,False);
  3202. /* only create one */
  3203. if ( NULL != hw->help_dialog.srch.selectionDlg )
  3204. {
  3205. XtManageChild(hw->help_dialog.srch.selectionDlg);
  3206. return;
  3207. }
  3208. /* open the modal dialog and let user select the volumes */
  3209. selDlg = _DtHelpFileListCreateSelectionDialog(
  3210. hw, hw->help_dialog.srch.srchForm, False,
  3211. (char *)_DTGETMESSAGE (GSSET, 40,
  3212. "Help - Search Volume Selection"),
  3213. &hw->help_dialog.srch.volTitlesFontList,
  3214. hw->help_dialog.srch.volListHead, &dlgChld);
  3215. hw->help_dialog.srch.selectionDlg = selDlg;
  3216. XtAddCallback(dlgChld.closeBtn, XmNactivateCallback,
  3217. CloseVolSelDialogCB,(XtPointer)hw);
  3218. XtAddCallback(dlgChld.form, XmNunmapCallback,
  3219. CloseVolSelDialogCB,(XtPointer)hw);
  3220. /* set the default response to a WM_DELETE_WINDOW message
  3221. to no response instead of UNMAP. */
  3222. XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
  3223. XtSetValues(dlgChld.shell, args, 1);
  3224. wm_delete_window = XmInternAtom(XtDisplay(dlgChld.shell),
  3225. "WM_DELETE_WINDOW", FALSE);
  3226. XmAddWMProtocolCallback(dlgChld.shell,wm_delete_window,
  3227. (XtCallbackProc)CloseVolSelDialogCB, (XtPointer)hw);
  3228. XtAddCallback(dlgChld.list, XmNsingleSelectionCallback,
  3229. StartSelectedVolumeSearchCB, (XtPointer) hw);
  3230. XtAddCallback(dlgChld.list, XmNmultipleSelectionCallback,
  3231. StartSelectedVolumeSearchCB, (XtPointer) hw);
  3232. XtAddCallback(dlgChld.list, XmNextendedSelectionCallback,
  3233. StartSelectedVolumeSearchCB, (XtPointer) hw);
  3234. XtAddCallback(dlgChld.list, XmNdefaultActionCallback,
  3235. StartSelectedVolumeSearchCB, (XtPointer) hw);
  3236. }
  3237. /*****************************************************************************
  3238. * Function: void OpenSelectDialogCB(Widget w,
  3239. * XtPointer clientData,
  3240. * XtPointer callData);
  3241. *
  3242. *
  3243. *
  3244. * Parameters:
  3245. *
  3246. * Return Value: Void.
  3247. *
  3248. * Purpose: Process user selection of the select button
  3249. *
  3250. *****************************************************************************/
  3251. static void OpenSelectDialogCB(
  3252. Widget widget,
  3253. XtPointer clientData,
  3254. XtPointer callData)
  3255. {
  3256. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  3257. /* only build the list of files if it hasn't been done */
  3258. if ( False == hw->help_dialog.srch.volScanDone
  3259. || NULL == hw->help_dialog.srch.volListHead)
  3260. {
  3261. /* Add on the Vol info; (T,T,T) search, display, selected only */
  3262. VolListBuild(hw,True,True,True);
  3263. }
  3264. /* FIX: the modal behaviour doesn't seem to be set; is it desired/needed? */
  3265. /* don't need to worry about having open twice, since
  3266. the dialog is always opened in modal mode from the search dialog */
  3267. /* open the dialog and let user select the volumes */
  3268. CreateVolSelDialog(hw);
  3269. }
  3270. /*****************************************************************************
  3271. * Function: void UpdateSearchVolumesCB(Widget w,
  3272. * XtPointer clientData,
  3273. * XtPointer callData);
  3274. *
  3275. *
  3276. *
  3277. * Parameters:
  3278. *
  3279. * Return Value: Void.
  3280. *
  3281. * Purpose: Process user selection of a button in the Volumes Radio box
  3282. *
  3283. *****************************************************************************/
  3284. static void UpdateSearchVolumesCB(
  3285. Widget widget,
  3286. XtPointer clientData,
  3287. XtPointer callData)
  3288. {
  3289. XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
  3290. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  3291. Arg args[5];
  3292. /* change focus */
  3293. if (hw->help_dialog.srch.hitsFound == True)
  3294. XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
  3295. else
  3296. XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
  3297. /* if turning off the button, just reinforce the current settings.
  3298. This message occurs when an on button is hit again. */
  3299. if ( False == status->set )
  3300. {
  3301. XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
  3302. XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
  3303. XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
  3304. XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
  3305. XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
  3306. XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
  3307. return;
  3308. }
  3309. /*** if work when something is turned on; ignore the off messages
  3310. except when the button is the selected volumes button; we
  3311. want to catch every click on that button */
  3312. if ( XmCR_VALUE_CHANGED == status->reason
  3313. && True == status->set
  3314. && NULL != status->event ) /* event is NULL for 1st of the two calls
  3315. to this routine that are made when a
  3316. button is pressed. */
  3317. {
  3318. /*** now update the sources value according to button selected ***/
  3319. hw->help_dialog.srch.volLeftCnt = 0; /* change invalidates prior search */
  3320. UpdateActionButtonLabel(hw,NULL,True);
  3321. XtSetArg(args[0], XmNset, hw->help_dialog.srch.allVolRadBtn == widget);
  3322. XtSetValues(hw->help_dialog.srch.allVolRadBtn,args,1);
  3323. XtSetArg(args[0], XmNset, hw->help_dialog.srch.curVolRadBtn == widget);
  3324. XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
  3325. XtSetArg(args[0], XmNset, hw->help_dialog.srch.selVolRadBtn == widget);
  3326. XtSetValues(hw->help_dialog.srch.selVolRadBtn,args,1);
  3327. /*** selected volumes button activated ***/
  3328. if (hw->help_dialog.srch.selVolRadBtn == widget)
  3329. {
  3330. /* set state */
  3331. hw->help_dialog.srch.srchSources = _DtHelpGlobSrchSelectedVolumes;
  3332. /* only build the list of files if it hasn't been done */
  3333. if ( False == hw->help_dialog.srch.volScanDone
  3334. || NULL == hw->help_dialog.srch.volListHead)
  3335. {
  3336. /* Add on the Vol info; (T,T,T) search, display, selected only */
  3337. VolListBuild(hw,True,True,True);
  3338. }
  3339. /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
  3340. SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
  3341. /* (T,T,T,T): enable search, enable display,
  3342. zero hits ok, only for selected volumes */
  3343. /* Set these here so that the CountSelectedVolumes() works right */
  3344. SetVolStatus(hw->help_dialog.srch.volListHead,True,True,True,True);
  3345. /* count all volumes selected, including those already searched */
  3346. if (CountSelectedVolumes(hw->help_dialog.srch.volListHead,True)==0)
  3347. {
  3348. StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
  3349. DeleteListContents(&hw->help_dialog.srch);
  3350. CreateVolSelDialog(hw);
  3351. /* NOTE: don't start search here, start it from the callback */
  3352. /* set state of start button correctly */
  3353. UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
  3354. }
  3355. else /* volumes already selected; just display */
  3356. {
  3357. hw->help_dialog.srch.hitsFound = False; /*DBG*/
  3358. StartSearchCB(NULL,(XtPointer) hw, NULL);
  3359. }
  3360. } /* if selected volumes button */
  3361. /*** all volumes button ***/
  3362. else if (hw->help_dialog.srch.allVolRadBtn == widget)
  3363. {
  3364. /* close the selection dialog, if open */
  3365. if (hw->help_dialog.srch.selectionDlg)
  3366. XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
  3367. /* set sources state */
  3368. hw->help_dialog.srch.srchSources = _DtHelpGlobSrchAllVolumes;
  3369. hw->help_dialog.srch.hitsFound = False; /*DBG*/
  3370. StartSearchCB(NULL,(XtPointer) hw, NULL);
  3371. }
  3372. /*** current volume button ***/
  3373. else
  3374. {
  3375. /* close the selection dialog, if open */
  3376. if (hw->help_dialog.srch.selectionDlg)
  3377. XtUnmanageChild(hw->help_dialog.srch.selectionDlg);
  3378. /* set sources state */
  3379. hw->help_dialog.srch.srchSources = _DtHelpGlobSrchCurVolume;
  3380. hw->help_dialog.srch.hitsFound = False; /*DBG*/
  3381. StartSearchCB(NULL,(XtPointer) hw, NULL);
  3382. }
  3383. /* update the Select... button status */
  3384. /* do this last, so that while searching for volumes (VolListBuild),
  3385. the button is not active. */
  3386. XtSetSensitive(hw->help_dialog.srch.selectBtn,
  3387. (hw->help_dialog.srch.selVolRadBtn == widget)
  3388. && ( NULL == hw->help_dialog.srch.selectionDlg
  3389. || !XtIsManaged(hw->help_dialog.srch.selectionDlg) ) );
  3390. } /* if value changed */
  3391. }
  3392. /*****************************************************************************
  3393. * Function: void UpdateIndexSelectionCB(Widget w,
  3394. * XtPointer clientData,
  3395. * XtPointer callData);
  3396. *
  3397. *
  3398. *
  3399. * Parameters:
  3400. *
  3401. * Return Value: Void.
  3402. *
  3403. * Purpose: Process user selection of a button in the Entries Radio box
  3404. *
  3405. *****************************************************************************/
  3406. static void UpdateIndexSelectionCB(
  3407. Widget widget,
  3408. XtPointer clientData,
  3409. XtPointer callData)
  3410. {
  3411. XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
  3412. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  3413. Boolean containsState;
  3414. int n;
  3415. Arg args[5];
  3416. /* change focus */
  3417. if (hw->help_dialog.srch.hitsFound == True)
  3418. XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
  3419. else
  3420. XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
  3421. /* if turning off the button, just reinforce the current settings.
  3422. This message occurs when an on button is hit again. */
  3423. if ( False == status->set )
  3424. {
  3425. containsState = (hw->help_dialog.srch.containsRadBtn == widget);
  3426. XtSetArg(args[0], XmNset, !containsState);
  3427. XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
  3428. XtSetArg(args[0], XmNset, containsState);
  3429. XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
  3430. return;
  3431. }
  3432. /*** if work when something is turned on; ignore the off messages
  3433. except when the button is the selected volumes button; we
  3434. want to catch every click on that button */
  3435. if ( XmCR_VALUE_CHANGED == status->reason
  3436. && True == status->set
  3437. && NULL != status->event ) /* event is NULL for 1st of the two calls
  3438. to this routine that are made when a
  3439. button is pressed. */
  3440. {
  3441. /* if search in progress, stop it */
  3442. if(hw->help_dialog.srch.searchInProgress||hw->help_dialog.srch.workProcId)
  3443. {
  3444. XmPushButtonCallbackStruct status;
  3445. /* generate a fake event to reset the dialog */
  3446. status.reason = XmCR_ACTIVATE;
  3447. status.event = NULL;
  3448. status.click_count = 1;
  3449. StopSearchCB(hw->help_dialog.srch.actionBtn,
  3450. (XtPointer)hw,(XtPointer)&status);
  3451. }
  3452. containsState = (hw->help_dialog.srch.containsRadBtn == widget);
  3453. XtSetArg(args[0], XmNset, !containsState);
  3454. XtSetValues(hw->help_dialog.srch.fullIndexRadBtn,args,1);
  3455. XtSetArg(args[0], XmNset, containsState);
  3456. XtSetValues(hw->help_dialog.srch.containsRadBtn,args,1);
  3457. /* sensitize/desensitize the Contains text field */
  3458. XtSetSensitive(hw->help_dialog.srch.wordField,containsState);
  3459. n=0;
  3460. XtSetArg(args[n],XmNeditable,containsState); n++;
  3461. XtSetArg(args[n],XmNcursorPositionVisible,containsState); n++;
  3462. XtSetValues(hw->help_dialog.srch.wordField,args,n);
  3463. /* set widget status here; do this way bec. srchFullIndex is a bit flag */
  3464. hw->help_dialog.srch.fullIndex = (containsState ? False : True); /*flag*/
  3465. /* set state of start button correctly */
  3466. UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
  3467. if (containsState)
  3468. { /* if changing to "Containing" */
  3469. /* change focus to the search word */
  3470. XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
  3471. /* user will need to hit CR to initiate search */
  3472. }
  3473. else
  3474. { /* if changing to full index */
  3475. /* indicate that no contains word is valid by deleting it */
  3476. /* FIX: I'm concerned that normWordStr & localeWordStr aren't in synch */
  3477. XtFree(hw->help_dialog.srch.normWordStr);
  3478. hw->help_dialog.srch.normWordStr = NULL;
  3479. /* search full index */
  3480. StartSearchCB(NULL,(XtPointer) hw, NULL);
  3481. }
  3482. /* and search to update results to the new state */
  3483. } /* if value changed */
  3484. }
  3485. /*****************************************************************************
  3486. * Function: void ContainsDisarmCB(Widget w,
  3487. * XtPointer clientData,
  3488. * XtPointer callData);
  3489. *
  3490. *
  3491. *
  3492. * Parameters:
  3493. *
  3494. * Return Value: Void.
  3495. *
  3496. * Purpose: Process disarm of the contains radio button
  3497. *
  3498. *****************************************************************************/
  3499. static void ContainsDisarmCB(
  3500. Widget widget,
  3501. XtPointer clientData,
  3502. XtPointer callData)
  3503. {
  3504. XmToggleButtonCallbackStruct *status = (XmToggleButtonCallbackStruct *) callData;
  3505. DtHelpDialogWidget hw = (DtHelpDialogWidget) clientData;
  3506. /* Force focus to the word field if set. */
  3507. if (True==status->set)
  3508. XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
  3509. }
  3510. /*****************************************************************************
  3511. * Function: CreateCurVolBtnLabel()
  3512. *
  3513. *
  3514. * Parameters:
  3515. *
  3516. * Return Value: True or False if current vol has an index
  3517. *
  3518. * Purpose: Creates the label for the current volume button
  3519. *
  3520. *****************************************************************************/
  3521. static Boolean CreateCurVolBtnLabel(
  3522. DtHelpDialogWidget hw,
  3523. Boolean * out_curVolAvailable,
  3524. XmString * out_labelString,
  3525. char * * out_mnemonic)
  3526. {
  3527. char * path = NULL;
  3528. char * preTitle;
  3529. char * postTitle;
  3530. XmString volTitleString = NULL;
  3531. XmString preTitleString = NULL;
  3532. XmString postTitleString = NULL;
  3533. XmString newTitle;
  3534. XmString labelString;
  3535. char * mnemonic;
  3536. Boolean curVolAvail;
  3537. int n;
  3538. Arg args[5];
  3539. #if 0 /* DBG */
  3540. if (out_curVolAvailable)
  3541. *out_curVolAvailable = False;
  3542. if (out_labelString)
  3543. *out_labelString = XmStringCreateLocalized("dum");
  3544. if (out_mnemonic)
  3545. *out_mnemonic = "";
  3546. return False;
  3547. #endif
  3548. /* if help content is a volume, get the title */
  3549. if ( hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC )
  3550. {
  3551. /* determine whether a current volume index is available */
  3552. curVolAvail = VolumeHasIndexP(
  3553. hw->help_dialog.srch.srchSources,
  3554. hw->help_dialog.display.helpType,
  3555. hw->help_dialog.display.helpVolume);
  3556. /* change False to True to search home dir; may want this */
  3557. path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, hw->help_dialog.display.helpVolume,
  3558. _DtHelpFileSuffixList,False,R_OK);
  3559. /* title needs to be an XmString to use volume's font */
  3560. if (path)
  3561. {
  3562. XmFontList fontList = NULL;
  3563. Boolean mod = False;
  3564. /* get the font list of the btn */
  3565. n = 0;
  3566. XtSetArg (args[n], XmNfontList, &fontList); n++;
  3567. XtGetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
  3568. #if defined(DONT_USE_CDExc22774)
  3569. /* copy the list before passing it in for modification */
  3570. fontList = XmFontListCopy (fontList);
  3571. #endif
  3572. GetVolumeInfoCB(hw->help_dialog.help.pDisplayArea,path,
  3573. NULL,&volTitleString,NULL,NULL,NULL,&fontList,&mod);
  3574. /* if font list was changed, install it */
  3575. if (mod)
  3576. {
  3577. /* set the font list of the btn */
  3578. n = 0;
  3579. XtSetArg (args[n], XmNfontList, fontList); n++;
  3580. XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, n);
  3581. if (fontList) XmFontListFree (fontList);
  3582. }
  3583. }
  3584. /* just in case */
  3585. if (NULL == volTitleString)
  3586. volTitleString = XmStringCreateLocalized(
  3587. hw->help_dialog.display.helpVolume);
  3588. } /* if helpType == TOPIC */
  3589. else
  3590. { /* if helpType != TOPIC */
  3591. curVolAvail = False;
  3592. switch (hw->help_dialog.display.helpType)
  3593. {
  3594. case DtHELP_TYPE_STRING:
  3595. case DtHELP_TYPE_DYNAMIC_STRING:
  3596. volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3597. (GSSET, 32,"Help Message")));
  3598. break;
  3599. case DtHELP_TYPE_FILE:
  3600. volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3601. (GSSET, 33,"Help File")));
  3602. break;
  3603. case DtHELP_TYPE_MAN_PAGE:
  3604. volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3605. (GSSET, 34,"Manual Page")));
  3606. break;
  3607. default:
  3608. volTitleString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3609. (GSSET, 35,"Unknown Format")));
  3610. break;
  3611. } /* switch on helpType */
  3612. } /* if helpType != TOPIC */
  3613. /* record path in the widget */
  3614. XtFree(hw->help_dialog.srch.curVolPath);
  3615. hw->help_dialog.srch.curVolPath = path;
  3616. /* create title */
  3617. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3618. (GSSET, 3,"Current")));
  3619. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 4,"r"));*/
  3620. mnemonic = 0;
  3621. /* append volume name to title */
  3622. preTitle = (char *)_DTGETMESSAGE(GSSET, 60," (");
  3623. preTitleString = XmStringCreateLocalized(preTitle);
  3624. postTitle = (char *)_DTGETMESSAGE(GSSET, 61,")");
  3625. postTitleString = XmStringCreateLocalized(postTitle);
  3626. newTitle = XmStringConcat(labelString,preTitleString);
  3627. XmStringFree(labelString);
  3628. XmStringFree(preTitleString);
  3629. labelString = newTitle;
  3630. newTitle = XmStringConcat(labelString,volTitleString);
  3631. XmStringFree(labelString);
  3632. XmStringFree(volTitleString);
  3633. labelString = newTitle;
  3634. newTitle = XmStringConcat(labelString,postTitleString);
  3635. XmStringFree(labelString);
  3636. XmStringFree(postTitleString);
  3637. labelString = newTitle;
  3638. /* set the out values */
  3639. if (out_curVolAvailable) *out_curVolAvailable = curVolAvail;
  3640. if (out_mnemonic) *out_mnemonic = mnemonic;
  3641. if (out_labelString) *out_labelString = labelString;
  3642. else XmStringFree(labelString);
  3643. return curVolAvail;
  3644. }
  3645. /*****************************************************************************
  3646. * Function: void CreateGlobSrchDialog()
  3647. *
  3648. *
  3649. * Parameters:
  3650. *
  3651. * Return Value:
  3652. *
  3653. * Purpose: Creates and displays an instance of the search dialog.
  3654. *
  3655. *****************************************************************************/
  3656. static void CreateGlobSrchDialog(
  3657. Widget nw,
  3658. char * searchWord)
  3659. {
  3660. Widget parentForm;
  3661. Widget separator;
  3662. Widget srchShell;
  3663. /* Widget topWidget; */
  3664. Widget volumesFrame;
  3665. Widget volumesForm;
  3666. Widget showFrame;
  3667. Widget showForm;
  3668. Widget frameTitle;
  3669. XmString labelString;
  3670. /* char * mnemonic; */
  3671. Dimension widgetHeight;
  3672. Dimension widgetBorderHeight;
  3673. char * title;
  3674. DtHelpListStruct *pHelpInfo;
  3675. Atom wm_delete_window;
  3676. DtHelpDialogWidget hw = (DtHelpDialogWidget) nw ;
  3677. XtTranslations btnTransTable;
  3678. /* XtTranslations listTransTable; */
  3679. /* XtTranslations mgrTransTable; */
  3680. Boolean curVolAvailable;
  3681. int n;
  3682. Arg args[20];
  3683. /* get state of the volume */
  3684. curVolAvailable = VolumeHasIndexP (
  3685. hw->help_dialog.srch.srchSources,
  3686. hw->help_dialog.display.helpType,
  3687. hw->help_dialog.display.helpVolume);
  3688. /* Set up the translations table stuff */
  3689. btnTransTable = XtParseTranslationTable(defaultBtnTranslations);
  3690. /* listTransTable = XtParseTranslationTable(defaultListTranslations); */
  3691. /* mgrTransTable = XtParseTranslationTable(defaultMgrTranslations); */
  3692. /* Create the shell used for the dialog. */
  3693. title = XtNewString(((char *)_DTGETMESSAGE(GSSET,1,"Help - Index Search")));
  3694. n = 0;
  3695. XtSetArg (args[n], XmNtitle, title); n++;
  3696. XtSetArg (args[n], XmNallowShellResize, True); n++;
  3697. srchShell = XmCreateDialogShell((Widget) hw, "searchShell", args, n);
  3698. XtFree(title);
  3699. /* Set the useAsyncGeo on the shell */
  3700. n = 0;
  3701. XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
  3702. XtSetValues (XtParent(srchShell), args, n); /* parent is new's shell */
  3703. #if 0
  3704. /* Adjust the decorations for the dialog shell of the dialog */
  3705. n = 0;
  3706. XtSetArg(args[n], XmNmwmFunctions, 0); n++;
  3707. XtSetArg (args[n], XmNmwmDecorations,
  3708. MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
  3709. XtSetValues (srchShell, args, n);
  3710. #endif
  3711. /* Grab the window mgr close and install a close dialog
  3712. callback when closed from dialog WM menu; this prevents
  3713. the dialog from closing the host application. */
  3714. wm_delete_window = XmInternAtom(XtDisplay(srchShell),
  3715. "WM_DELETE_WINDOW", FALSE);
  3716. XtSetArg(args[0], XmNdeleteResponse, XmDO_NOTHING);
  3717. XmAddWMProtocolCallback(srchShell,wm_delete_window,
  3718. CloseSearchCB, (XtPointer)&hw->help_dialog.srch);
  3719. XtSetValues(srchShell, args, 1);
  3720. /* set the callback that positions the dialog when popped up */
  3721. XtAddCallback (srchShell, XmNpopupCallback,
  3722. (XtCallbackProc)_DtHelpMapCB, (XtPointer) XtParent(hw));
  3723. /*** Create the form used for the dialog. ***/
  3724. /* setting RESIZE_NONE is important to prevent the resultList from
  3725. dynamically resizing as items with various fonts are added and
  3726. deleted from it. */
  3727. n = 0;
  3728. XtSetArg (args[n], XmNmarginWidth, 1); n++;
  3729. XtSetArg (args[n], XmNmarginHeight, 1); n++;
  3730. XtSetArg (args[n], XmNshadowThickness, 1); n++;
  3731. XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT); n++;
  3732. XtSetArg (args[n], XmNautoUnmanage, False); n++;
  3733. XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  3734. parentForm = XmCreateForm (srchShell, "parentForm", args, n);
  3735. hw->help_dialog.srch.srchForm = parentForm;
  3736. /*==============================================================*/
  3737. /****** Create the volumes region ******/
  3738. n = 0;
  3739. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3740. XtSetArg (args[n], XmNtopOffset, 5); n++;
  3741. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3742. XtSetArg (args[n], XmNrightOffset, 5); n++;
  3743. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3744. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3745. XtSetArg (args[n], XmNmarginWidth, 5); n++;
  3746. XtSetArg (args[n], XmNmarginHeight, 2); n++;
  3747. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
  3748. volumesFrame = XmCreateFrame(parentForm, "volFrame", args, n);
  3749. XtManageChild (volumesFrame);
  3750. /* put form inside frame */
  3751. volumesForm = XmCreateForm (volumesFrame, "volumesForm", args, 0);
  3752. XtManageChild (volumesForm);
  3753. /* create the frame title */
  3754. labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,2, "Search")));
  3755. n = 0;
  3756. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3757. XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
  3758. XtSetArg (args[n], XmNtraversalOn, False); n++;
  3759. frameTitle = XmCreateLabelGadget(volumesFrame, "volFrameTitle", args, n);
  3760. XtManageChild (frameTitle);
  3761. XmStringFree (labelString);
  3762. /* create Current Volume radio button */
  3763. /* Use a dummy label until CreateCurVolBtnLabel can be used.
  3764. It refs the srchCurVolRadBtn widget and other things that need
  3765. initalizing. */
  3766. labelString = XmStringCreateLocalized (" ");
  3767. n = 0;
  3768. XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3769. XtSetArg (args[n], XmNset, TRUE); n++;
  3770. XtSetArg(args[n], XmNlabelString, labelString); n++;
  3771. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  3772. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3773. XtSetArg (args[n], XmNtopOffset, 0); n++;
  3774. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3775. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3776. /* Attaching to form causes the hilite outline of the button to
  3777. stretch to the form edge when selected. But it also forces
  3778. the form to resize when the current volume title is too big
  3779. for the available space. */
  3780. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3781. XtSetArg (args[n], XmNrightOffset, 10); n++;
  3782. XtSetArg (args[n], XmNbottomOffset, 0); n++;
  3783. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  3784. XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
  3785. hw->help_dialog.srch.curVolRadBtn =
  3786. XmCreateToggleButtonGadget(volumesForm,"srchCurVolRadBtn",args,n);
  3787. XtAddCallback(hw->help_dialog.srch.curVolRadBtn,XmNvalueChangedCallback,
  3788. UpdateSearchVolumesCB, (XtPointer) hw);
  3789. /* ??? XtSetSensitive (hw->help_dialog.srch.curVolRadBtn,False); */
  3790. XtManageChild (hw->help_dialog.srch.curVolRadBtn);
  3791. XmStringFree (labelString);
  3792. /* create All Volumes radio button */
  3793. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3794. (GSSET, 5,"All Volumes")));
  3795. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 7,"A"));*/
  3796. n = 0;
  3797. XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3798. XtSetArg (args[n], XmNset, FALSE); n++;
  3799. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3800. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  3801. XtSetArg (args[n], XmNmarginWidth, 2); n++;
  3802. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3803. XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.curVolRadBtn); n++;
  3804. XtSetArg (args[n], XmNtopOffset, 1); n++;
  3805. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3806. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3807. XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
  3808. hw->help_dialog.srch.allVolRadBtn =
  3809. XmCreateToggleButtonGadget(volumesForm,"srchAllVolRadBtn",args, n);
  3810. XtAddCallback(hw->help_dialog.srch.allVolRadBtn,XmNvalueChangedCallback,
  3811. UpdateSearchVolumesCB, (XtPointer) hw);
  3812. XtManageChild (hw->help_dialog.srch.allVolRadBtn);
  3813. XmStringFree (labelString);
  3814. /* create Selected Volumes radio button */
  3815. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3816. (GSSET, 6,"Selected")));
  3817. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 9,"d"));*/
  3818. n = 0;
  3819. XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3820. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3821. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  3822. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3823. XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
  3824. XtSetArg (args[n], XmNtopOffset, 1); n++;
  3825. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3826. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3827. XtSetArg (args[n], XmNbottomOffset, 2); n++;
  3828. XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
  3829. hw->help_dialog.srch.selVolRadBtn =
  3830. XmCreateToggleButtonGadget(volumesForm,"srchSelVolRadBtn", args, n);
  3831. XtAddCallback(hw->help_dialog.srch.selVolRadBtn,XmNvalueChangedCallback,
  3832. UpdateSearchVolumesCB, (XtPointer) hw);
  3833. XtManageChild (hw->help_dialog.srch.selVolRadBtn);
  3834. XmStringFree (labelString);
  3835. /* Create Selected... button */
  3836. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3837. (GSSET, 7,"Select Volumes...")));
  3838. n = 0;
  3839. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3840. XtSetArg (args[n], XmNtopOffset, 0); n++;
  3841. XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.allVolRadBtn); n++;
  3842. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3843. XtSetArg (args[n], XmNrightOffset, 10); n++;
  3844. XtSetArg (args[n], XmNbottomOffset, 2); n++;
  3845. XtSetArg (args[n], XmNmarginTop, 0); n++;
  3846. XtSetArg (args[n], XmNmarginHeight, 3); n++;
  3847. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3848. hw->help_dialog.srch.selectBtn =
  3849. XmCreatePushButtonGadget(volumesForm,"selectBtn", args, n);
  3850. XtAddCallback (hw->help_dialog.srch.selectBtn, XmNactivateCallback,
  3851. OpenSelectDialogCB, (XtPointer) hw);
  3852. XtManageChild (hw->help_dialog.srch.selectBtn);
  3853. XtSetSensitive (hw->help_dialog.srch.selectBtn,False);
  3854. XmStringFree (labelString);
  3855. /****** Create the show selection region ******/
  3856. n = 0;
  3857. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3858. XtSetArg (args[n], XmNtopWidget, volumesFrame); n++;
  3859. XtSetArg (args[n], XmNtopOffset, 5); n++;
  3860. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3861. XtSetArg (args[n], XmNrightOffset, 5); n++;
  3862. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3863. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3864. XtSetArg (args[n], XmNmarginWidth, 5); n++;
  3865. XtSetArg (args[n], XmNmarginHeight, 2); n++;
  3866. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;/*EXP*/
  3867. showFrame = XmCreateFrame(parentForm, "showFrame", args, n);
  3868. XtManageChild (showFrame);
  3869. /* FIX: is this doing enough? Goal: CR activation of FullIndex */
  3870. /* Setup the proper translation on the title box widget */
  3871. /* XtAugmentTranslations(showFrame, mgrTransTable); */
  3872. /* put form inside frame */
  3873. showForm = XmCreateForm (showFrame, "showForm", args, 0);
  3874. XtManageChild (showForm);
  3875. /* create the frame title */
  3876. labelString = XmStringCreateLocalized ((_DTGETMESSAGE(GSSET,8, "Show")));
  3877. n = 0;
  3878. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3879. XtSetArg (args[n], XmNtraversalOn, False); n++;
  3880. XtSetArg (args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
  3881. frameTitle = XmCreateLabelGadget(showFrame, "showFrameTitle", args, n);
  3882. XtManageChild (frameTitle);
  3883. XmStringFree (labelString);
  3884. /* create the All Entries button */
  3885. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3886. (GSSET, 9,"Complete Index")));
  3887. n = 0;
  3888. XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3889. XtSetArg (args[n], XmNset, True); n++;
  3890. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3891. XtSetArg (args[n], XmNmarginHeight, 1); n++;
  3892. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3893. XtSetArg (args[n], XmNtopOffset, 0); n++;
  3894. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3895. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3896. XtSetArg (args[n], XmNbottomOffset, 0); n++;
  3897. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  3898. XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
  3899. hw->help_dialog.srch.fullIndexRadBtn =
  3900. XmCreateToggleButtonGadget(showForm,"srchFullIndexRadBtn",args,n);
  3901. XtAddCallback(hw->help_dialog.srch.fullIndexRadBtn,XmNvalueChangedCallback,
  3902. UpdateIndexSelectionCB, (XtPointer) hw);
  3903. XtManageChild (hw->help_dialog.srch.fullIndexRadBtn);
  3904. XmStringFree (labelString);
  3905. /* create Contains radio button */
  3906. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  3907. (GSSET, 10,"Entries with:")));
  3908. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 16,"n"));*/
  3909. n = 0;
  3910. XtSetArg (args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3911. XtSetArg (args[n], XmNset, False); n++;
  3912. XtSetArg (args[n], XmNlabelString, labelString); n++;
  3913. XtSetArg (args[n], XmNmarginHeight, 1); n++;
  3914. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3915. XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn);n++;
  3916. XtSetArg (args[n], XmNtopOffset, 1); n++;
  3917. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3918. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3919. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  3920. XtSetArg (args[n], XmNbottomOffset, 4); n++;
  3921. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  3922. XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
  3923. hw->help_dialog.srch.containsRadBtn =
  3924. XmCreateToggleButtonGadget(showForm,"srchContainsRadBtn",args,n);
  3925. XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNvalueChangedCallback,
  3926. UpdateIndexSelectionCB, (XtPointer) hw);
  3927. XtAddCallback(hw->help_dialog.srch.containsRadBtn,XmNdisarmCallback,
  3928. ContainsDisarmCB, (XtPointer) hw);
  3929. XtManageChild (hw->help_dialog.srch.containsRadBtn);
  3930. XmStringFree (labelString);
  3931. /* create the search name text field */
  3932. n = 0;
  3933. XtSetArg (args[n], XmNvalue, ""); n++;
  3934. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3935. XtSetArg (args[n], XmNtopWidget,hw->help_dialog.srch.fullIndexRadBtn); n++;
  3936. XtSetArg (args[n], XmNtopOffset, 0); n++;
  3937. XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  3938. XtSetArg (args[n], XmNleftWidget,hw->help_dialog.srch.containsRadBtn); n++;
  3939. XtSetArg (args[n], XmNleftOffset, 5); n++;
  3940. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3941. XtSetArg (args[n], XmNrightOffset, 10); n++;
  3942. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  3943. XtSetArg (args[n], XmNbottomOffset, 3); n++;
  3944. XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
  3945. XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
  3946. hw->help_dialog.srch.wordField =
  3947. XmCreateTextField (showForm,"srchWord",args, n);
  3948. XtSetSensitive(hw->help_dialog.srch.wordField,False);
  3949. XtManageChild (hw->help_dialog.srch.wordField);
  3950. /* Because the actionBtn is the default button on the form,
  3951. and it activates a search, we do not need to (nor do we want
  3952. to, since ActionButtonCB toggles between states) make it
  3953. a callback on activation of the text field */
  3954. XtAddCallback (hw->help_dialog.srch.wordField, XmNvalueChangedCallback,
  3955. UpdateSearchStartStatusCB, (XtPointer) hw);
  3956. /* Setup the proper translation on the text field widget */
  3957. XtAugmentTranslations(hw->help_dialog.srch.wordField, btnTransTable);
  3958. /* separator */
  3959. /* Create a separator search specs and result area */
  3960. n = 0;
  3961. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3962. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3963. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3964. XtSetArg (args[n], XmNtopWidget, showFrame); n++;
  3965. XtSetArg (args[n], XmNtopOffset, 10); n++;
  3966. separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
  3967. XtManageChild (separator);
  3968. /*==============================================================*/
  3969. /****** result related stuff *******/
  3970. /* Create result List Label */
  3971. n = 0;
  3972. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3973. XtSetArg (args[n], XmNtopWidget, separator); n++;
  3974. XtSetArg (args[n], XmNtopOffset, 10); n++;
  3975. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3976. XtSetArg (args[n], XmNleftOffset, 10); n++;
  3977. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3978. XtSetArg (args[n], XmNrightOffset, 10); n++;
  3979. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  3980. hw->help_dialog.srch.statusLabel =
  3981. XmCreateLabelGadget (parentForm, "resultListLabel", args, n);
  3982. StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,True,0); /* installs a label */
  3983. XtManageChild (hw->help_dialog.srch.statusLabel);
  3984. /* Create our result topics scrolled list (not placed on form) */
  3985. n = 0;
  3986. XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
  3987. XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
  3988. XtSetArg (args[n], XmNhighlightOnEnter, True); n++;
  3989. XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
  3990. hw->help_dialog.srch.resultList =
  3991. XmCreateScrolledList (parentForm, "resultList", args, n);
  3992. XtManageChild (hw->help_dialog.srch.resultList);
  3993. XtAddCallback (hw->help_dialog.srch.resultList, XmNsingleSelectionCallback,
  3994. ProcessResultSelectionCB, (XtPointer) hw);
  3995. XtAddCallback (hw->help_dialog.srch.resultList, XmNdefaultActionCallback,
  3996. ProcessResultSelectionCB, (XtPointer) hw);
  3997. /* Set the constraints on our scrolled list (place on form) */
  3998. n = 0;
  3999. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  4000. XtSetArg (args[n], XmNtopWidget, hw->help_dialog.srch.statusLabel); n++;
  4001. XtSetArg (args[n], XmNtopOffset, 5); n++;
  4002. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  4003. XtSetArg (args[n], XmNleftOffset, 10); n++;
  4004. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  4005. XtSetArg (args[n], XmNrightOffset, 10); n++;
  4006. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  4007. XtSetArg (args[n], XmNbottomOffset, 70); n++;
  4008. /* 70 is just a rough value that will be updated with a calculated
  4009. value below, after we know the height of the buttons */
  4010. XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
  4011. /* Create a separator between the buttons */
  4012. n = 0;
  4013. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  4014. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  4015. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  4016. XtSetArg (args[n], XmNtopWidget,
  4017. XtParent (hw->help_dialog.srch.resultList)); n++;
  4018. XtSetArg (args[n], XmNtopOffset, 5); n++;
  4019. separator = XmCreateSeparatorGadget (parentForm, "separator", args, n);
  4020. XtManageChild (separator);
  4021. /***** search spec-related stuff *****/
  4022. /* Create start button (left of stop button)*/
  4023. _DtHelpProcessLock();
  4024. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  4025. (GSSET, START_SEARCH_CAT,START_SEARCH_STR)));
  4026. _DtHelpProcessUnlock();
  4027. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 20,START_SEARCH_MNEM));*/
  4028. n = 0;
  4029. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  4030. XtSetArg (args[n], XmNtopWidget, separator); n++;
  4031. XtSetArg (args[n], XmNtopOffset, 5); n++;
  4032. /* L & R position set below */
  4033. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  4034. XtSetArg (args[n], XmNbottomOffset, 5); n++;
  4035. /*XtSetArg (args[n], XmNmarginHeight, 3); n++;*/
  4036. XtSetArg (args[n], XmNlabelString, labelString); n++;
  4037. XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
  4038. hw->help_dialog.srch.actionBtn =
  4039. XmCreatePushButtonGadget(parentForm,"actionBtn", args, n);
  4040. XtAddCallback (hw->help_dialog.srch.actionBtn, XmNactivateCallback,
  4041. ActionButtonCB, (XtPointer) hw);
  4042. XtSetSensitive (hw->help_dialog.srch.actionBtn,False);
  4043. XtManageChild (hw->help_dialog.srch.actionBtn);
  4044. XmStringFree (labelString);
  4045. XtSetArg (args[0], XmNdefaultButton, hw->help_dialog.srch.actionBtn);
  4046. XtSetValues (parentForm, args, 1);
  4047. /* Build the Cancel Button */
  4048. _DtHelpProcessLock();
  4049. labelString = XmStringCreateLocalized(((char *)_DTGETMESSAGE
  4050. (GSSET, CLOSE_BTN_CAT,CLOSE_BTN_STR)));
  4051. _DtHelpProcessUnlock();
  4052. /*mnemonic = ((char *)_DTGETMESSAGE(GSSET, 25,CLOSE_BTN_MNEM));*/
  4053. n = 0;
  4054. XtSetArg (args[n], XmNlabelString, labelString); n++;
  4055. /* L & R position set below */
  4056. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  4057. XtSetArg (args[n], XmNtopWidget, separator); n++;
  4058. XtSetArg (args[n], XmNtopOffset, 5); n++;
  4059. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  4060. XtSetArg (args[n], XmNbottomOffset, 5); n++;
  4061. XtSetArg (args[n], XmNmarginHeight, 3); n++;
  4062. XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
  4063. hw->help_dialog.srch.closeBtn =
  4064. XmCreatePushButtonGadget (parentForm, "srchCloseBtn", args, n);
  4065. XtAddCallback(hw->help_dialog.srch.closeBtn,
  4066. XmNactivateCallback, CloseSearchCB,(XtPointer) &hw->help_dialog.srch);
  4067. XtManageChild (hw->help_dialog.srch.closeBtn);
  4068. XmStringFree (labelString);
  4069. /* Build the Help button */
  4070. _DtHelpProcessLock();
  4071. labelString = XmStringCreateLocalized((char *)_DTGETMESSAGE
  4072. (GSSET, HELP_BTN_CAT,HELP_BTN_STR));
  4073. _DtHelpProcessUnlock();
  4074. /*mnemonic = (char *)_DTGETMESSAGE(GSSET, 27,HELP_BTN_MNEM);*/
  4075. n = 0;
  4076. XtSetArg (args[n], XmNlabelString, labelString); n++;
  4077. /* L & R position set below */
  4078. XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  4079. XtSetArg (args[n], XmNtopWidget, separator); n++;
  4080. XtSetArg (args[n], XmNtopOffset, 5); n++;
  4081. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  4082. XtSetArg (args[n], XmNbottomOffset, 5); n++;
  4083. XtSetArg (args[n], XmNmarginHeight, 3); n++;
  4084. XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
  4085. hw->help_dialog.srch.helpBtn =
  4086. XmCreatePushButtonGadget (parentForm, "srchHelpBtn", args, n);
  4087. XtManageChild (hw->help_dialog.srch.helpBtn);
  4088. XmStringFree (labelString);
  4089. pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexHelpBtn_STR,
  4090. (Widget) hw, &hw->help_dialog.help,
  4091. &hw->help_dialog.help.pHelpListHead);
  4092. XtAddCallback(hw->help_dialog.srch.helpBtn, XmNactivateCallback,
  4093. _DtHelpCB, (XtPointer) pHelpInfo);
  4094. /*==============================================================*/
  4095. /****** finishing touches *******/
  4096. /* set the Form cancel button (for KCancel) */
  4097. n = 0;
  4098. XtSetArg (args[n], XmNcancelButton, hw->help_dialog.srch.closeBtn); n++;
  4099. XtSetValues (parentForm, args, n);
  4100. { /* position buttons */
  4101. /* This code adds up the sizes of the buttons to go into
  4102. the bottom row and calculates the form position percentages.
  4103. All buttons are the same size, and are able to hold all
  4104. the strings that may be dynamically placed in them.
  4105. All buttons are 5% apart. */
  4106. /* This code is specifically written to handle 3 buttons
  4107. and assumes that the first 3 strings are to the ActionBtn */
  4108. #define NUMSTRS 5
  4109. Dimension maxWidth = 0;
  4110. Dimension borderWidth = 0;
  4111. Dimension sumWidth = 0;
  4112. float scale = 0.0;
  4113. float posList[11]; /* need 11 due to algorithm, which uses index 10 */
  4114. XmFontList fontList = NULL;
  4115. int i;
  4116. /* get the fontList for the button */
  4117. XtSetArg (args[0], XmNborderWidth, &borderWidth);
  4118. XtSetArg (args[1], XmNfontList, &fontList);
  4119. XtGetValues (hw->help_dialog.srch.actionBtn, args, 2);
  4120. #define BETBUTSPACE 5 /* pixels */
  4121. sumWidth = BETBUTSPACE; /* left side space */
  4122. posList[0] = (float) sumWidth;
  4123. for (i=0; i<NUMSTRS; i++)
  4124. {
  4125. XmString labelString;
  4126. Dimension width;
  4127. _DtHelpProcessLock();
  4128. s_GlobSrchDlgBtnStrs[i] = (char *) _DTGETMESSAGE(GSSET,
  4129. s_GlobSrchDlgBtnCatNum[i],s_GlobSrchDlgBtnStrs[i]);
  4130. labelString = XmStringCreateLocalized(s_GlobSrchDlgBtnStrs[i]);
  4131. _DtHelpProcessUnlock();
  4132. #define MARGINS 4 /* pixel margins: 2=L, 2=R */
  4133. width = XmStringWidth(fontList,labelString) + borderWidth + MARGINS;
  4134. if (i<=2) maxWidth = max(width,maxWidth);
  4135. if (i==2) width = maxWidth; /* 1st three labels go in 1st button */
  4136. if (i>=2) /* after scanning just labels, do buttons */
  4137. {
  4138. sumWidth += width;
  4139. posList[i*2+1] = (float) sumWidth;
  4140. sumWidth += BETBUTSPACE;
  4141. posList[i*2+2] = (float) sumWidth;
  4142. }
  4143. XmStringFree(labelString);
  4144. } /* for calcing widths */
  4145. /* scale pixels to percent */
  4146. scale = 100.0 / (float) sumWidth;
  4147. n = 0;
  4148. XtSetArg (args[n], XmNwidth, maxWidth); n++;
  4149. XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  4150. XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[0]*scale)); n++;
  4151. XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  4152. XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[5]*scale)); n++;
  4153. XtSetValues (hw->help_dialog.srch.actionBtn, args, n);
  4154. n = 0;
  4155. XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  4156. XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[6]*scale)); n++;
  4157. XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  4158. XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[7]*scale)); n++;
  4159. XtSetValues (hw->help_dialog.srch.closeBtn, args, n);
  4160. n = 0;
  4161. XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  4162. XtSetArg (args[n], XmNleftPosition, (Dimension) (posList[8]*scale)); n++;
  4163. XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  4164. XtSetArg (args[n], XmNrightPosition,(Dimension) (posList[9]*scale)); n++;
  4165. XtSetValues (hw->help_dialog.srch.helpBtn, args, n);
  4166. } /* */
  4167. { /* set the proper offset between the bottom of the results list
  4168. and the bottom of the form to maintain a constant sized
  4169. button bar. */
  4170. int offset = 0;
  4171. /* first calc offset of list to form bottom based on earlier sizes */
  4172. #define KNOWN_OFFSETS_BELOW_LIST 20 /* actually only 15, but 15 fails */
  4173. n = 0;
  4174. XtSetArg(args[n], XmNborderWidth, &widgetBorderHeight); n++;
  4175. XtSetArg(args[n], XmNheight, &widgetHeight); n++;
  4176. XtGetValues(hw->help_dialog.srch.actionBtn, args, n);
  4177. offset = widgetHeight + 2 * widgetBorderHeight;
  4178. XtGetValues(separator, args, n);
  4179. offset += widgetHeight + 2 * widgetBorderHeight;
  4180. XtGetValues(XtParent(hw->help_dialog.srch.resultList), args, 1);
  4181. offset += widgetBorderHeight;
  4182. offset += KNOWN_OFFSETS_BELOW_LIST;
  4183. /* then set the offset */
  4184. n = 0;
  4185. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  4186. XtSetArg (args[n], XmNbottomOffset, offset); n++;
  4187. XtSetValues (XtParent (hw->help_dialog.srch.resultList), args, n);
  4188. }
  4189. /** force tabs to go to each widget and in right order **/
  4190. XtSetArg (args[0], XmNnavigationType, XmSTICKY_TAB_GROUP);
  4191. XtSetValues (hw->help_dialog.srch.curVolRadBtn,args,1);
  4192. XtSetValues (hw->help_dialog.srch.allVolRadBtn,args,1);
  4193. XtSetValues (hw->help_dialog.srch.selVolRadBtn,args,1);
  4194. XtSetValues (hw->help_dialog.srch.selectBtn,args,1);
  4195. XtSetValues (hw->help_dialog.srch.fullIndexRadBtn,args,1);
  4196. XtSetValues (hw->help_dialog.srch.containsRadBtn,args,1);
  4197. XtSetValues (hw->help_dialog.srch.wordField,args,1);
  4198. XtSetValues (hw->help_dialog.srch.resultList,args,1);
  4199. XtSetValues (hw->help_dialog.srch.actionBtn,args,1);
  4200. XtSetValues (hw->help_dialog.srch.closeBtn,args,1);
  4201. XtSetValues (hw->help_dialog.srch.helpBtn,args,1);
  4202. /** put focus on the text field **/
  4203. XtSetArg (args[0], XmNinitialFocus, hw->help_dialog.srch.wordField);
  4204. XtSetValues (parentForm,args,1);
  4205. /* Add the proper help callback to the print dialog shell "F1" support */
  4206. pHelpInfo = _DtHelpListAdd(DtHELP_srchIndexShell_STR,
  4207. (Widget) hw, &hw->help_dialog.help,
  4208. &hw->help_dialog.help.pHelpListHead);
  4209. XtAddCallback(parentForm, XmNhelpCallback,
  4210. _DtHelpCB, (XtPointer) pHelpInfo);
  4211. }
  4212. /*****************************************************************************
  4213. * Function: updateDisplay()
  4214. *
  4215. *
  4216. * Parameters: hw: the help widget
  4217. *
  4218. * Return Value: 0
  4219. *
  4220. * Purpose: forces an update on index search dialog widgets
  4221. *
  4222. *****************************************************************************/
  4223. static int updateDisplay(
  4224. DtHelpDialogWidget hw)
  4225. {
  4226. XmUpdateDisplay((Widget)hw->help_dialog.srch.actionBtn);/*DBG*/
  4227. XmUpdateDisplay((Widget)hw->help_dialog.srch.curVolRadBtn);/*DBG*/
  4228. XmUpdateDisplay((Widget)hw->help_dialog.srch.allVolRadBtn);/*DBG*/
  4229. XmUpdateDisplay((Widget)hw->help_dialog.srch.selVolRadBtn);/*DBG*/
  4230. XmUpdateDisplay((Widget)hw->help_dialog.srch.selectBtn);/*DBG*/
  4231. XmUpdateDisplay((Widget)hw->help_dialog.srch.fullIndexRadBtn);/*DBG*/
  4232. XmUpdateDisplay((Widget)hw->help_dialog.srch.containsRadBtn);/*DBG*/
  4233. XmUpdateDisplay((Widget)hw->help_dialog.srch.wordField);/*DBG*/
  4234. XmUpdateDisplay((Widget)hw->help_dialog.srch.statusLabel);/*DBG*/
  4235. XmUpdateDisplay((Widget)hw->help_dialog.srch.resultList);/*DBG*/
  4236. XmUpdateDisplay((Widget)hw->help_dialog.srch.closeBtn);/*DBG*/
  4237. XmUpdateDisplay((Widget)hw->help_dialog.srch.helpBtn);/*DBG*/
  4238. XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));/*DBG*/
  4239. return 0;
  4240. }
  4241. /*****************************************************************************
  4242. * Function: void _DtHelpGlobSrchDisplayDialog()
  4243. *
  4244. *
  4245. * Parameters: parent Specifies the parent widget
  4246. * searchWord word to put into searchWord field
  4247. * remove this when integrated into DtHelp:
  4248. * curVolume volume considered the current volume
  4249. *
  4250. * Return Value:
  4251. *
  4252. * Purpose: Setsup the proper data in the search dialog and
  4253. * displays an instance of the search dialog.
  4254. *
  4255. *****************************************************************************/
  4256. void _DtHelpGlobSrchDisplayDialog(
  4257. Widget w,
  4258. char * searchWord,
  4259. char * curVolume)
  4260. {
  4261. DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
  4262. XmToggleButtonCallbackStruct status; /* the call data */
  4263. Widget sourceBtn; /* widget owning event */
  4264. #if 0
  4265. Dimension height;
  4266. Dimension width;
  4267. int n;
  4268. #endif
  4269. XmString labelString = NULL;
  4270. Arg args[10];
  4271. /* make the dialog itself */
  4272. if (NULL == hw->help_dialog.srch.srchForm)
  4273. {
  4274. CreateGlobSrchDialog((Widget) hw,searchWord);
  4275. /* create the button label */
  4276. CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
  4277. XtSetArg (args[0], XmNlabelString, labelString);
  4278. XtSetValues (hw->help_dialog.srch.curVolRadBtn, args, 1);
  4279. XmStringFree (labelString);
  4280. /*** map widget and update display before doing any searching ***/
  4281. /* Make sure the Search Dialog is managed */
  4282. XtManageChild(hw->help_dialog.srch.srchForm);
  4283. XtMapWidget(hw->help_dialog.srch.srchForm);
  4284. /* set focus to contains word */
  4285. XmProcessTraversal(hw->help_dialog.srch.wordField,XmTRAVERSE_CURRENT);
  4286. /* force several updates to make sure it is fully displayed and
  4287. that height/width are correctly inited */
  4288. XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
  4289. XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
  4290. XmUpdateDisplay(XtParent((Widget)hw->help_dialog.srch.srchForm));
  4291. /*** now update settings, which may also invoke a search ***/
  4292. /* set the cur vol btn sensitivity */
  4293. UpdateCurVolBtnSens(hw,True);
  4294. /* set default show index state */
  4295. /* set full index if current vol has an index, contains word if not */
  4296. if (hw->help_dialog.srch.curVolRadBtnSens) /* set in UpdateCurVolBtnSens*/
  4297. sourceBtn = hw->help_dialog.srch.fullIndexRadBtn;
  4298. else
  4299. sourceBtn = hw->help_dialog.srch.containsRadBtn;
  4300. /* set the show index state */
  4301. status.reason = XmCR_VALUE_CHANGED;
  4302. status.set = True;
  4303. status.event = (XEvent *) 1; /* thwart == NULL test in Update...() */
  4304. UpdateIndexSelectionCB(sourceBtn,(XtPointer)hw,(XtPointer)&status);
  4305. StatusLabelUpdate(hw,FIRST_PROMPT_STATUS,False,0);
  4306. updateDisplay(hw); /* DBG */
  4307. #if 0 /* 11/23/94 */
  4308. /** Set min size for the dialog **/
  4309. n = 0;
  4310. XtSetArg(args[n], XmNheight, &height); ++n;
  4311. XtSetArg(args[n], XmNwidth, &width); ++n;
  4312. XtGetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
  4313. n = 0;
  4314. XtSetArg(args[n], XmNminHeight, height - 200); ++n; /* 200: arbitrary */
  4315. XtSetArg(args[n], XmNminWidth, width); ++n;
  4316. XtSetValues(XtParent((Widget)hw->help_dialog.srch.srchForm), args, n);
  4317. #endif
  4318. }
  4319. else /* properly update dialog to support new word and cur vol */
  4320. {
  4321. /* fixup current volume, if need be */
  4322. _DtHelpGlobSrchUpdateCurVol((Widget)hw);
  4323. /* fixup search word, if need be */
  4324. if (NULL != searchWord)
  4325. {
  4326. String srchWord = XtNewString(searchWord);
  4327. /* srchWord is freed or used in CheckSearchWord() */
  4328. if (CheckSearchWord(hw,srchWord,True) == True)
  4329. { /* words are different */
  4330. /* free all hit-related data and reset flags */
  4331. HitListFreeAllVolHits(hw,True); /*True=free everything*/
  4332. }
  4333. }
  4334. /* if its not managed, manage it */
  4335. if ( XtIsManaged(hw->help_dialog.srch.srchForm) == False )
  4336. {
  4337. /* manage and map the Search Dialog */
  4338. XtManageChild(hw->help_dialog.srch.srchForm);
  4339. XtMapWidget((Widget)hw->help_dialog.srch.srchForm);
  4340. /* see if the selection dialog was already open */
  4341. if ( hw->help_dialog.srch.selectionDlg
  4342. && XtIsManaged(hw->help_dialog.srch.selectionDlg) )
  4343. {
  4344. XtManageChild(hw->help_dialog.srch.selectionDlg);
  4345. XtMapWidget(hw->help_dialog.srch.selectionDlg);
  4346. }
  4347. }
  4348. else /* if it is managed, bring it forward */
  4349. {
  4350. Widget parent = XtParent(hw->help_dialog.srch.srchForm);
  4351. XRaiseWindow ( XtDisplay(parent), XtWindow(parent) );
  4352. }
  4353. /* change focus */
  4354. if (hw->help_dialog.srch.hitsFound == True)
  4355. XmProcessTraversal(hw->help_dialog.srch.resultList,XmTRAVERSE_CURRENT);
  4356. else
  4357. XmProcessTraversal(hw->help_dialog.srch.allVolRadBtn,XmTRAVERSE_CURRENT);
  4358. } /* end if create a new dialog */
  4359. }
  4360. /*****************************************************************************
  4361. * Function: void _DtHelpGlobSrchUpdateCurVol()
  4362. *
  4363. * Parameters: new the help widget
  4364. *
  4365. * Return Value:
  4366. *
  4367. * Purpose: Adjusts the current volume of the dialog
  4368. *
  4369. *****************************************************************************/
  4370. void _DtHelpGlobSrchUpdateCurVol(
  4371. Widget w)
  4372. {
  4373. String path;
  4374. DtHelpDialogWidget hw = (DtHelpDialogWidget) w;
  4375. #if 1
  4376. if ( NULL == hw->help_dialog.srch.srchForm )
  4377. #else
  4378. if ( NULL == hw->help_dialog.srch.srchForm
  4379. || XtIsManaged(hw->help_dialog.srch.srchForm) == False )
  4380. #endif
  4381. return; /* RETURN */
  4382. /* get full pathname for the volume */
  4383. path = NULL;
  4384. if (hw->help_dialog.display.helpVolume)
  4385. path = _DtHelpFileLocate(DtHelpVOLUME_TYPE,
  4386. /* FIX: will helpVolume have matching path? */
  4387. hw->help_dialog.display.helpVolume,
  4388. _DtHelpFileSuffixList,False,R_OK);
  4389. if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
  4390. && hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC
  4391. && NULL != path
  4392. && NULL != hw->help_dialog.srch.curVolPath
  4393. && _DtHelpFileIsSameP(path,hw->help_dialog.srch.curVolPath,
  4394. GetVolumeInfoCB, _DtHELP_FILE_NAME,
  4395. hw->help_dialog.help.pDisplayArea) )
  4396. {
  4397. /* leave current status as is */
  4398. XtFree(path);
  4399. return; /* RETURN */
  4400. }
  4401. /* a different current volume or change of topic */
  4402. {
  4403. XmString labelString;
  4404. Arg args[5];
  4405. /* if still searching previous cur volume, stop any search in progress */
  4406. if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources
  4407. && hw->help_dialog.srch.workProcId)
  4408. {
  4409. /* cancel the search */
  4410. StopSearchCB(NULL,(XtPointer) hw, NULL);
  4411. /* (F,F,F,F): disable search,disable display,no 0 hits,for all vols */
  4412. SetVolStatus(hw->help_dialog.srch.volListHead,False,False,False,False);
  4413. /* zero search data */
  4414. hw->help_dialog.srch.volLeftCnt = 0;
  4415. hw->help_dialog.srch.curSrchVol = NULL;
  4416. /* assumption is, that even though the search was incomplete,
  4417. nothing bad will happen if we don't free the hit data,
  4418. and the search could resume where left off, if necessary. */
  4419. }
  4420. CreateCurVolBtnLabel(hw, NULL, &labelString, NULL);
  4421. XtSetArg(args[0],XmNlabelString,labelString);
  4422. XtSetValues(hw->help_dialog.srch.curVolRadBtn,args,1);
  4423. XmStringFree(labelString);
  4424. /* set the cur vol btn sensitivity */
  4425. UpdateCurVolBtnSens(hw,False);
  4426. /* set state of start button correctly */
  4427. UpdateSearchStartStatusCB(NULL, (XtPointer) hw, NULL);
  4428. /* and search if needed */
  4429. if ( _DtHelpGlobSrchCurVolume == hw->help_dialog.srch.srchSources )
  4430. {
  4431. /* if to search a volume, start the search */
  4432. if (hw->help_dialog.display.helpType == DtHELP_TYPE_TOPIC)
  4433. StartSearchCB(NULL,(XtPointer) hw, NULL);
  4434. else /* if current isn't a volume, clear the display & update status */
  4435. {
  4436. DeleteListContents(&hw->help_dialog.srch);
  4437. StatusLabelUpdate(hw,NO_VOL_STATUS,False,0);
  4438. }
  4439. }
  4440. }
  4441. }
  4442. /*****************************************************************************
  4443. * Function: void _DtHelpGlobSrchInitVars()
  4444. *
  4445. * Parameters: srch search main data structure
  4446. *
  4447. * Return Value:
  4448. *
  4449. * Purpose: Init the contents of the control data structure
  4450. *
  4451. *****************************************************************************/
  4452. void _DtHelpGlobSrchInitVars(
  4453. _DtHelpGlobSearchStuff * srch)
  4454. {
  4455. /* set the font resource */
  4456. if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
  4457. srch->hitPrefixFont = XtNewString(srch->hitPrefixFont);
  4458. /* File Selection Dialog font list */
  4459. srch->volTitlesFontList = NULL;
  4460. /* Set our search dialog widgets to NULL */
  4461. srch->srchForm = NULL;
  4462. srch->actionBtn = NULL;
  4463. srch->curVolRadBtn = NULL;
  4464. srch->allVolRadBtn = NULL;
  4465. srch->selVolRadBtn = NULL;
  4466. srch->selectBtn = NULL;
  4467. srch->fullIndexRadBtn = NULL;
  4468. srch->containsRadBtn = NULL;
  4469. srch->wordField = NULL;
  4470. srch->statusLabel = NULL;
  4471. srch->resultList = NULL;
  4472. srch->gotoBtn = NULL;
  4473. srch->closeBtn = NULL;
  4474. srch->helpBtn = NULL;
  4475. srch->selectionDlg = NULL;
  4476. /* init dialog content variables */
  4477. srch->curVolPath = NULL;
  4478. srch->rawWordStr = NULL;
  4479. srch->normWordStr = NULL;
  4480. srch->localeWordStr = NULL;
  4481. srch->wordFieldFirstChar = 0;
  4482. srch->wordFieldLen = 0;
  4483. srch->statusLineUsage = 0; /* empty */
  4484. /* init srch processing variables */
  4485. srch->iconv3Codeset = NULL; /* iconv(3)-compatible code set of current locale */
  4486. srch->iconv3Context = NULL;
  4487. srch->srchSources = _DtHelpGlobSrchVolumeUndef; /* radio btn usage */
  4488. srch->curSrchVol = NULL; /* volume currently in search */
  4489. srch->hitsFontLoaded= False; /* is font loaded? */
  4490. srch->volScanDone = False; /* is the volume list complete? */
  4491. srch->fullIndex = False;
  4492. srch->hitsFound = False; /* state of search */
  4493. srch->readyToStart = False; /* state of search */
  4494. srch->searchInProgress= False; /* state of search */
  4495. srch->curVolRadBtnSens = False;
  4496. srch->volLeftCnt = 0;
  4497. srch->volListHead = NULL; /* info on search topics found */
  4498. srch->workProcId = 0;
  4499. }
  4500. /*****************************************************************************
  4501. * Function: void _DtHelpGlobSrchCleanAndClose()
  4502. *
  4503. * Parameters: srch search main data structure
  4504. * destroy flag to signal srch dialog should be destroyed
  4505. *
  4506. * Return Value:
  4507. *
  4508. * Purpose: Free the contents of the control data structure
  4509. *
  4510. *****************************************************************************/
  4511. void _DtHelpGlobSrchCleanAndClose(
  4512. _DtHelpGlobSearchStuff * srch,
  4513. Boolean destroy)
  4514. {
  4515. /* close conversion context */
  4516. _DtHelpCeIconvClose(&srch->iconv3Context);
  4517. /* free the font list */
  4518. if(srch->volTitlesFontList)
  4519. {
  4520. XmFontListFree(srch->volTitlesFontList);
  4521. srch->volTitlesFontList = NULL;
  4522. }
  4523. /*
  4524. * Make sure CloseSearchCB does not try using an invalid
  4525. * widget id in its XtUnmanageChild and XtUnmapWidget calls.
  4526. */
  4527. if (destroy)
  4528. srch->srchForm = NULL;
  4529. /* make dialog invisible; update sensitivities */
  4530. CloseSearchCB(NULL,(XtPointer)srch, NULL);
  4531. /* Destroy our index search dialog? */
  4532. if (destroy)
  4533. {
  4534. /* set the font resource */
  4535. if (srch->hitPrefixFont != _DtHelpDefaultSrchHitPrefixFont)
  4536. XtFree(srch->hitPrefixFont);
  4537. /*
  4538. * mark widgets as destroyed.
  4539. * The XtDestroyWidget that called me will have called the destroy
  4540. * callback of the widgets. So I don't have to do anything except
  4541. * make sure I know they are destroyed.
  4542. */
  4543. srch->selectionDlg = NULL;
  4544. srch->srchForm = NULL;
  4545. srch->resultList = NULL;
  4546. /* free other data released to search dialog */
  4547. VolListFree(srch);
  4548. /* free the locale word string, if allocated
  4549. * (i.e. diff from normWordStr) */
  4550. if(srch->localeWordStr!=srch->normWordStr)
  4551. {
  4552. XtFree(srch->localeWordStr);
  4553. srch->localeWordStr=NULL;
  4554. }
  4555. XtFree(srch->normWordStr);
  4556. srch->normWordStr=NULL;
  4557. XtFree(srch->rawWordStr);
  4558. srch->rawWordStr=NULL;
  4559. XtFree(srch->curVolPath);
  4560. srch->curVolPath=NULL;
  4561. XtFree(srch->iconv3Codeset);
  4562. srch->iconv3Codeset = NULL;
  4563. }
  4564. }