1 /************************************************************************/
2 /*									*/
3 /*  A spelling tool.							*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"appFrameConfig.h"
8 
9 #   include	<stdlib.h>
10 #   include	<stdio.h>
11 #   include	<stddef.h>
12 #   include	<string.h>
13 #   include	<appDebugon.h>
14 
15 #   include	"appSpellTool.h"
16 #   include	"appFrame.h"
17 #   include	"appQuestion.h"
18 #   include	"guiToolUtil.h"
19 
20 /************************************************************************/
21 /*									*/
22 /*  Resources for the spell tool.					*/
23 /*									*/
24 /************************************************************************/
25 
26 /* From ../tedPackage/languages.txt */
27 static LocaleName AppSpellToolLocaleNames[]=
28 {
29     { "en_US", "American English",		},
30 
31     { "nl_NL", "Dutch",				},
32     { "en_GB", "British English",		},
33     { "de_DE", "German",			},
34     { "es_ES", "Spanish",			},
35     { "es_AR", "Argentinian Spanish",		},
36     { "pt_PT", "Portuguese",			},
37     { "pt_BR", "Brazilian Portuguese",		},
38     { "fr_FR", "French",			},
39     { "it_IT", "Italian",			},
40     { "cs_CZ", "Czech",				},
41     { "da_DK", "Danish",			},
42     { "sv_SE", "Swedish",			},
43     { "no_NO", "Norwegian",			},
44     { "pl_PL", "Polish",			},
45     { "ru_RU", "Russian",			},
46     { "sk_SK", "Slovak",			},
47     { "sl_SI", "Slovene",			},
48     { "hu_HU", "Hungarian",			},
49     { "mg_MG", "Malagasi",			},
50     { "oc_FR", "Occitan",			},
51     { "eu_FR", "Basque",			},
52     { "bg_BG", "Bulgarian",			},
53     { "hr_HR", "Croatian",			},
54     { "et_EE", "Estonian",			},
55     { "fi_FI", "Finnish",			},
56 };
57 
58 /************************************************************************/
59 /*									*/
60 /*  Adapt buttons to different situations..				*/
61 /*									*/
62 /************************************************************************/
63 
appSpellToolSomethingFound(SpellTool * ast,int yes_no)64 static void appSpellToolSomethingFound(	SpellTool *	ast,
65 					int		yes_no )
66     {
67     guiEnableWidget( ast->astLearnButton, yes_no );
68     guiEnableWidget( ast->astIgnoreButton, yes_no );
69 
70     return;
71     }
72 
appSpellToolGotAlternative(SpellTool * ast,int gotAlternative)73 static void appSpellToolGotAlternative(	SpellTool *	ast,
74 					int		gotAlternative )
75     {
76     ast->astGotAlternative= gotAlternative;
77 
78     guiEnableWidget( ast->astForgetButton, ast->astGotAlternative );
79     guiEnableWidget( ast->astCorrectButton,
80 			    ast->astGotAlternative && ! ast->astReadOnly );
81     guiEnableWidget( ast->astGuessButton, ast->astGotAlternative );
82 
83     return;
84     }
85 
86 /************************************************************************/
87 /*									*/
88 /*  Complain								*/
89 /*									*/
90 /************************************************************************/
91 
appSpellToolComplain(int error,const char * subject,void * voidast)92 static void appSpellToolComplain(	int			error,
93 					const char *		subject,
94 					void *			voidast )
95     {
96     SpellTool *			ast= (SpellTool *)voidast;
97     const char *		message= "?";
98     const SpellToolResources *	astr= ast->astResources;
99     APP_WIDGET			topWidget= ast->astInspector->aiTopWidget;
100 
101     if  ( error > 0 && error < SCerr_COUNT )
102 	{ message= astr->astrErrors[error]; }
103 
104     if  ( subject )
105 	{
106 	appQuestionRunErrorDialog( ast->astApplication,
107 				topWidget, (APP_WIDGET)0, message );
108 	}
109     else{
110 	appQuestionRunSubjectErrorDialog( ast->astApplication,
111 				topWidget, (APP_WIDGET)0, subject, message );
112 	}
113 
114     return;
115     }
116 
117 /************************************************************************/
118 /*									*/
119 /*  Guess what was intended for word.					*/
120 /*									*/
121 /************************************************************************/
122 
appSpellMakeGuesses(void * voidast,const char * word)123 static void appSpellMakeGuesses(	void *		voidast,
124 					const char *	word )
125     {
126     SpellTool *			ast= (SpellTool *)voidast;
127     SpellChecker *		sc;
128     SpellDictionary *		sd;
129 
130     int				count;
131     int				i;
132     static IndGuessList		igl;
133 
134     if  ( ast->astCurrentDictionary < 0 )
135 	{ LDEB(ast->astCurrentDictionary); return;	}
136     if  ( ! ( sc= ast->astSpellChecker ) )
137 	{ XDEB(ast->astSpellChecker); return;	}
138     if  ( ! sc->scGuessWord )
139 	{ XDEB(sc->scGuessWord); return;		}
140 
141     sd= sc->scDictionaries+ ast->astCurrentDictionary;
142 
143     count= (*sc->scGuessWord)( &igl, sd,
144 				appSpellToolComplain, (void *)ast, sc, word );
145     if  ( count < 0 )
146 	{ LDEB(count); return;	}
147 
148     appGuiEmptyListWidget( ast->astGuessList );
149     appStringToTextWidget( ast->astWordText, (const char *)word );
150 
151     for ( i= 0; i < count; i++ )
152 	{
153 	appGuiAddValueToListWidget( ast->astGuessList, -1,
154 					(char *)igl.iglGuesses[i].igsWord );
155 	}
156 
157     appSpellToolGotAlternative( ast, 0 );
158     }
159 
appSpellToolSetReadOnly(SpellTool * ast,int readOnly)160 void appSpellToolSetReadOnly(	SpellTool *		ast,
161 				int			readOnly )
162     {
163     ast->astReadOnly= readOnly;
164 
165     guiEnableWidget( ast->astCorrectButton,
166 				ast->astGotAlternative && ! ast->astReadOnly );
167 
168     /* Not needed, but not doing this confuses: */
169     guiEnableWidget( ast->astGuessList, ! ast->astReadOnly );
170     guiEnableText( ast->astWordText, ! ast->astReadOnly );
171 
172     return;
173     }
174 
175 /************************************************************************/
176 /*									*/
177 /*  Look for the next unknown word.					*/
178 /*									*/
179 /************************************************************************/
180 
appSpellToolFindNext(SpellTool * ast)181 static void appSpellToolFindNext(	SpellTool *	ast )
182     {
183     SpellChecker *		sc;
184     SpellDictionary *		sd;
185     MemoryBuffer		mbGuess;
186 
187     utilInitMemoryBuffer( &mbGuess );
188 
189     if  ( ! ( sc= ast->astSpellChecker ) )
190 	{ XDEB(ast->astSpellChecker); return;	}
191 
192     if  ( ast->astCurrentDictionary < 0				||
193 	  ast->astCurrentDictionary >= sc->scDictionaryCount	)
194 	{ LLDEB(ast->astCurrentDictionary,sc->scDictionaryCount); return; }
195 
196     sd= sc->scDictionaries+ ast->astCurrentDictionary;
197 
198     appStringToTextWidget( ast->astWordText, "" );
199     appGuiEmptyListWidget( ast->astGuessList );
200 
201     if  ( (*sc->scOpenDict)( sd, appSpellToolComplain, (void *)ast, sc ) )
202 	{ return;	}
203 
204     if  ( ! (*sc->scFindNext)( ast->astApplication, &mbGuess, sc, sd ) )
205 	{
206 	appSpellToolSomethingFound( ast, 1 );
207 	appSpellMakeGuesses( ast, utilMemoryBufferGetString( &mbGuess ) );
208 	}
209     else{ appSpellToolSomethingFound( ast, 0 );	}
210 
211     appSpellToolGotAlternative( ast, 0 );
212 
213     utilCleanMemoryBuffer( &mbGuess );
214     }
215 
216 /************************************************************************/
217 /*									*/
218 /*  'Learn/Forget/Ignore' button has been pushed.			*/
219 /*									*/
220 /************************************************************************/
221 
APP_BUTTON_CALLBACK_H(appSpellToolLearnPushed,w,voidast)222 static APP_BUTTON_CALLBACK_H( appSpellToolLearnPushed, w, voidast )
223     {
224     SpellTool *		ast= (SpellTool *)voidast;
225     SpellChecker *		sc;
226     SpellDictionary *		sd;
227     char *			word;
228 
229     if  ( ast->astCurrentDictionary < 0 )
230 	{ LDEB(ast->astCurrentDictionary); return;	}
231     if  ( ! ( sc= ast->astSpellChecker ) )
232 	{ XDEB(ast->astSpellChecker); return;	}
233     if  ( ! sc->scLearnWord )
234 	{ XDEB(sc->scLearnWord); return;		}
235 
236     sd= sc->scDictionaries+ ast->astCurrentDictionary;
237 
238     word= appGetStringFromTextWidget( ast->astWordText );
239 
240     (*sc->scLearnWord)( sd, appSpellToolComplain, (void *)ast, sc, word );
241 
242     appFreeStringFromTextWidget( word );
243 
244     appSpellToolFindNext( ast );
245 
246     return;
247     }
248 
APP_BUTTON_CALLBACK_H(appSpellToolForgetPushed,w,voidast)249 static APP_BUTTON_CALLBACK_H( appSpellToolForgetPushed, w, voidast )
250     {
251     SpellTool *		ast= (SpellTool *)voidast;
252     SpellChecker *		sc;
253     SpellDictionary *		sd;
254     char *			word;
255 
256     if  ( ast->astCurrentDictionary < 0 )
257 	{ LDEB(ast->astCurrentDictionary); return;	}
258     if  ( ! ( sc= ast->astSpellChecker ) )
259 	{ XDEB(ast->astSpellChecker); return;	}
260     if  ( ! sc->scForgetWord )
261 	{ XDEB(sc->scForgetWord); return;		}
262 
263     sd= sc->scDictionaries+ ast->astCurrentDictionary;
264 
265     word= appGetStringFromTextWidget( ast->astWordText );
266 
267     (*sc->scForgetWord)( sd, appSpellToolComplain, (void *)ast, sc, word );
268 
269     appFreeStringFromTextWidget( word );
270 
271     guiEnableWidget( ast->astForgetButton, 0 );
272     guiEnableWidget( ast->astLearnButton, 1 );
273 
274     return;
275     }
276 
APP_BUTTON_CALLBACK_H(appSpellToolIgnorePushed,w,voidast)277 static APP_BUTTON_CALLBACK_H( appSpellToolIgnorePushed, w, voidast )
278     {
279     SpellTool *		ast= (SpellTool *)voidast;
280     SpellChecker *		sc;
281     SpellDictionary *		sd;
282     char *			word;
283 
284     if  ( ast->astCurrentDictionary < 0 )
285 	{ LDEB(ast->astCurrentDictionary); return;	}
286     if  ( ! ( sc= ast->astSpellChecker ) )
287 	{ XDEB(ast->astSpellChecker); return;	}
288     if  ( ! sc->scIgnoreWord )
289 	{ XDEB(sc->scIgnoreWord); return;		}
290 
291     sd= sc->scDictionaries+ ast->astCurrentDictionary;
292 
293     word= appGetStringFromTextWidget( ast->astWordText );
294 
295     (*sc->scIgnoreWord)( sd, appSpellToolComplain, (void *)ast, sc, word );
296 
297     appFreeStringFromTextWidget( word );
298 
299     appSpellToolFindNext( ast );
300 
301     return;
302     }
303 
304 /************************************************************************/
305 /*									*/
306 /*  'Find Next' button has been pushed.					*/
307 /*									*/
308 /************************************************************************/
309 
APP_BUTTON_CALLBACK_H(appSpellToolFindNextPushed,w,voidast)310 static APP_BUTTON_CALLBACK_H( appSpellToolFindNextPushed, w, voidast )
311     {
312     SpellTool *		ast= (SpellTool *)voidast;
313 
314     appSpellToolFindNext( ast );
315 
316     return;
317     }
318 
319 /************************************************************************/
320 /*									*/
321 /*  The user typed something in the Coreection, Turn on the the		*/
322 /*  'Correct' button.							*/
323 /*									*/
324 /************************************************************************/
325 
APP_TXTYPING_CALLBACK_H(appSpellCorrectionTyped,w,voidast)326 static APP_TXTYPING_CALLBACK_H( appSpellCorrectionTyped, w, voidast )
327     {
328     SpellTool *	ast= (SpellTool *)voidast;
329 
330     appSpellToolGotAlternative( ast, 1 );
331 
332     return;
333     }
334 
335 /************************************************************************/
336 /*									*/
337 /*  'Correct' button has been pushed.					*/
338 /*  Or a double click on the listbox with guesses.			*/
339 /*									*/
340 /************************************************************************/
341 
APP_BUTTON_CALLBACK_H(appSpellToolCorrect,w,voidast)342 static APP_BUTTON_CALLBACK_H( appSpellToolCorrect, w, voidast )
343     {
344     SpellTool *	ast= (SpellTool *)voidast;
345     SpellChecker *	sc;
346     char *		guess;
347 
348     if  ( ast->astReadOnly )
349 	{ return;	}
350     if  ( ! ( sc= ast->astSpellChecker ) )
351 	{ XDEB(ast->astSpellChecker); return;	}
352     if  ( ! sc->scCorrect || ast->astReadOnly )
353 	{ XLDEB(sc->scCorrect,ast->astReadOnly); return;	}
354 
355     guess= appGetStringFromTextWidget( ast->astWordText );
356 
357     (*sc->scCorrect)( ast->astApplication, guess );
358 
359     appFreeStringFromTextWidget( guess );
360 
361     appSpellToolFindNext( ast );
362 
363     return;
364     }
365 
366 /************************************************************************/
367 /*									*/
368 /*  The 'Guess' button has been pushed.					*/
369 /*									*/
370 /************************************************************************/
371 
APP_BUTTON_CALLBACK_H(appSpellGuessButtonPushed,w,voidast)372 static APP_BUTTON_CALLBACK_H( appSpellGuessButtonPushed, w, voidast )
373     {
374     SpellTool *	ast= (SpellTool *)voidast;
375     char *		word;
376 
377     word= appGetStringFromTextWidget( ast->astWordText );
378 
379     appSpellMakeGuesses( voidast, word );
380 
381     appFreeStringFromTextWidget( word );
382 
383     return;
384     }
385 
386 /************************************************************************/
387 /*  A guess in the list has been selected.				*/
388 /************************************************************************/
389 
APP_LIST_CALLBACK_H(appSpellGuessChosen,w,voidast,voidlcs)390 static APP_LIST_CALLBACK_H( appSpellGuessChosen, w, voidast, voidlcs )
391     {
392     SpellTool *		ast= (SpellTool *)voidast;
393 
394     char *			text;
395 
396     text= appGuiGetStringFromListCallback( w, voidlcs );
397     if  ( text )
398 	{
399 	appStringToTextWidget( ast->astWordText, text );
400 	appFreeStringFromListCallback( text );
401 	}
402 
403     appSpellToolGotAlternative( ast, 1 );
404 
405     return;
406     }
407 
408 /************************************************************************/
409 /*									*/
410 /*  A dictionary has been selected.					*/
411 /*									*/
412 /************************************************************************/
413 
appSpellDictionaryChosen(int dict,void * voidast)414 static void appSpellDictionaryChosen(	int		dict,
415 					void *		voidast )
416     {
417     SpellTool *		ast= (SpellTool *)voidast;
418     SpellChecker *	sc;
419 
420     if  ( ! ( sc= ast->astSpellChecker ) )
421 	{ XDEB(ast->astSpellChecker); return;	}
422 
423     if  ( dict < 0 || dict >= sc->scDictionaryCount )
424 	{ LLDEB(dict,sc->scDictionaryCount); return;	}
425 
426     ast->astCurrentDictionary= dict;
427 
428     return;
429     }
430 
431 /************************************************************************/
432 /*									*/
433 /*  Make the dictionary part of the spelling tool.			*/
434 /*									*/
435 /************************************************************************/
436 
appSpellMakeDictionaryFrame(APP_WIDGET parent,const SpellToolResources * astr,SpellTool * ast)437 static APP_WIDGET appSpellMakeDictionaryFrame(
438 					APP_WIDGET			parent,
439 					const SpellToolResources *	astr,
440 					SpellTool *			ast )
441     {
442     APP_WIDGET		frame;
443     APP_WIDGET		paned;
444 
445     APP_WIDGET		buttonRow;
446 
447     appMakeColumnFrameInColumn( &frame, &paned,
448 					    parent, astr->astrDictionary );
449 
450     appMakeOptionmenuInColumn( &(ast->astDictionaryOptionmenu), paned,
451 				    appSpellDictionaryChosen, (void *)ast );
452 
453     guiToolMake2BottonRow( &buttonRow, paned,
454 		&(ast->astLearnButton), &(ast->astForgetButton),
455 		astr->astrLearn, astr->astrForget,
456 		appSpellToolLearnPushed, appSpellToolForgetPushed,
457 		(void *)ast );
458 
459     return frame;
460     }
461 
462 /************************************************************************/
463 /*									*/
464 /*  Fill the list of dictionaries.					*/
465 /*									*/
466 /************************************************************************/
467 
appSpellFillDictionaryMenu(SpellTool * ast,const SpellToolResources * astr)468 static void appSpellFillDictionaryMenu(	SpellTool *			ast,
469 					const SpellToolResources *	astr )
470     {
471     SpellChecker *	sc;
472     SpellDictionary *	sd;
473 
474     int			dict;
475     int			defaultDict= -1;
476 
477     if  ( ! ( sc= ast->astSpellChecker ) )
478 	{ XDEB(ast->astSpellChecker); return;	}
479 
480     appEmptyOptionmenu( &(ast->astDictionaryOptionmenu) );
481 
482     sd= sc->scDictionaries;
483     for ( dict= 0; dict < sc->scDictionaryCount; sd++, dict++ )
484 	{
485 	appAddItemToOptionmenu(
486 		    &(ast->astDictionaryOptionmenu), sd->sdLocaleLabel );
487 
488 	if  ( ast->astApplication					&&
489 	      ast->astApplication->eaLocaleName				&&
490 	      ! strcmp( sd->sdLocale, ast->astApplication->eaLocaleName ) )
491 	    { defaultDict= dict;	}
492 	}
493 
494     if  ( sc->scDictionaryCount == 0 )
495 	{
496 	(void) appAddItemToOptionmenu(
497 		    &(ast->astDictionaryOptionmenu), astr->astrNoDicts );
498 	}
499 
500     if  ( defaultDict < 0 )
501 	{ defaultDict= 0;	}
502 
503     appSetOptionmenu( &(ast->astDictionaryOptionmenu), defaultDict );
504     ast->astCurrentDictionary= defaultDict;
505 
506     appOptionmenuRefreshWidth( &(ast->astDictionaryOptionmenu) );
507     }
508 
509 /************************************************************************/
510 /*									*/
511 /*  Make the listbox with guesses.					*/
512 /*									*/
513 /************************************************************************/
514 
appSpellGuessList(APP_WIDGET parent,const SpellToolResources * astr,SpellTool * ast)515 static APP_WIDGET appSpellGuessList(	APP_WIDGET			parent,
516 					const SpellToolResources *	astr,
517 					SpellTool *			ast )
518     {
519     APP_WIDGET		label;
520     APP_WIDGET		list;
521 
522     const int		visibleItems= 6;
523 
524     appMakeLabelInColumn( &label, parent, astr->astrGuesses );
525 
526     appGuiMakeListInColumn( &list, parent, visibleItems,
527 		    appSpellGuessChosen, appSpellToolCorrect, (void *)ast );
528 
529     return list;
530     }
531 
532 /************************************************************************/
533 /*									*/
534 /*  Make the button part of the spelling Tool.				*/
535 /*									*/
536 /************************************************************************/
537 
appSpellMakeButtonRows(APP_WIDGET spellForm,const SpellToolResources * astr,SpellTool * ast)538 static void appSpellMakeButtonRows(
539 				APP_WIDGET			spellForm,
540 				const SpellToolResources * 	astr,
541 				SpellTool *			ast )
542     {
543     APP_WIDGET		buttonRow;
544 
545     guiToolMake2BottonRow( &buttonRow, spellForm,
546 		&(ast->astIgnoreButton), &(ast->astFindNextButton),
547 		astr->astrIgnore, astr->astrFindNext,
548 		appSpellToolIgnorePushed, appSpellToolFindNextPushed,
549 		(void *)ast );
550 
551     guiToolMake2BottonRow( &buttonRow, spellForm,
552 		&(ast->astGuessButton), &(ast->astCorrectButton),
553 		astr->astrGuess, astr->astrCorrect,
554 		appSpellGuessButtonPushed, appSpellToolCorrect,
555 		(void *)ast );
556 
557     return;
558     }
559 
560 /************************************************************************/
561 /*									*/
562 /*  Resolve locale names.						*/
563 /*									*/
564 /************************************************************************/
565 
appSpellGetLocaleNames(EditApplication * ea,SpellChecker * sc)566 static int appSpellGetLocaleNames(		EditApplication *	ea,
567 						SpellChecker *		sc )
568     {
569     static int				gotResources;
570 
571     static LocaleName *			localeNames= (LocaleName *)0;
572     static int				localeNameCount;
573     static AppConfigurableResource *	localeRes= (AppConfigurableResource *)0;
574 
575     int					i;
576 
577     if  ( ! gotResources )
578 	{
579 	localeNames= malloc( sc->scDictionaryCount* sizeof(LocaleName) );
580 	if  ( ! localeNames )
581 	    { LXDEB(sc->scDictionaryCount,localeNames); return -1; }
582 	localeRes= malloc( sc->scDictionaryCount*
583 					    sizeof(AppConfigurableResource) );
584 	if  ( ! localeRes )
585 	    { LXDEB(sc->scDictionaryCount,localeRes); return -1; }
586 
587 	for ( i= 0; i < sc->scDictionaryCount; i++ )
588 	    {
589 	    int			j;
590 	    char *		name;
591 	    const char *	def;
592 
593 	    localeNames[i].lnLocale= strdup( sc->scDictionaries[i].sdLocale );
594 	    if  ( ! localeNames[i].lnLocale )
595 		{ XDEB(localeNames[i].lnLocale); return -1;	}
596 
597 	    name= malloc( 5+ strlen(sc->scDictionaries[i].sdLocale)+ 1 );
598 	    if  ( ! name )
599 		{ XDEB(name); return -1;	}
600 
601 	    sprintf( name, "NAME_%s", sc->scDictionaries[i].sdLocale );
602 	    def=  sc->scDictionaries[i].sdLocale;
603 
604 	    for ( j= 0;
605 		  j < sizeof(AppSpellToolLocaleNames)/sizeof(LocaleName);
606 		  j++ )
607 		{
608 		if  ( ! strcmp( AppSpellToolLocaleNames[j].lnLocale,
609 					    sc->scDictionaries[i].sdLocale ) )
610 		    {
611 		    def= AppSpellToolLocaleNames[j].lnLocaleName;
612 		    break;
613 		    }
614 		}
615 
616 	    APP_SET_RESOURCE( localeRes+ i, name,
617 		    i* sizeof(LocaleName)+ offsetof(LocaleName,lnLocaleName),
618 		    def );
619 	    }
620 
621 	appGuiGetResourceValues( &gotResources, ea, (void *)localeNames,
622 					    localeRes, sc->scDictionaryCount );
623 	localeNameCount= sc->scDictionaryCount;
624 	gotResources= 1;
625 	}
626 
627     for ( i= 0; i < sc->scDictionaryCount; i++ )
628 	{
629 	int		j;
630 
631 	for ( j= 0; j < localeNameCount; j++ )
632 	    {
633 	    int		n= ( i+ j ) % localeNameCount;
634 
635 	    if  ( ! strcmp( localeNames[n].lnLocale,
636 					sc->scDictionaries[i].sdLocale ) )
637 		{
638 		indSpellDictionarySetLocaleLabel( &(sc->scDictionaries[i]),
639 						localeNames[n].lnLocaleName );
640 		break;
641 		}
642 	    }
643 	}
644 
645     return 0;
646     }
647 
648 /************************************************************************/
649 
appInitSpellTool(SpellTool * ast)650 void appInitSpellTool(	SpellTool *	ast )
651     {
652     ast->astApplication= (EditApplication *)0;
653     ast->astInspector= (AppInspector *)0;
654 
655     ast->astResources= (SpellToolResources *)0;
656 
657     appInitOptionmenu( &(ast->astDictionaryOptionmenu) );
658 
659     ast->astLearnButton= (APP_WIDGET)0;
660     ast->astForgetButton= (APP_WIDGET)0;
661     ast->astGuessButton= (APP_WIDGET)0;
662     ast->astIgnoreButton= (APP_WIDGET)0;
663     ast->astFindNextButton= (APP_WIDGET)0;
664 
665     ast->astCorrectButton= (APP_WIDGET)0;
666     ast->astGuessList= (APP_WIDGET)0;
667     ast->astWordText= (APP_WIDGET)0;
668 
669     ast->astSpellChecker= (SpellChecker *)0;
670     ast->astCurrentDictionary= -1;
671 
672     ast->astReadOnly= 0;
673     ast->astGotAlternative= 0;
674     }
675 
appCleanSpellTool(SpellTool * ast)676 void appCleanSpellTool(	SpellTool *	ast )
677     {
678     /* ast->astSpellChecker is not owned bt the tool */
679     return;
680     }
681 
682 /************************************************************************/
683 /*									*/
684 /*  make a spell tool.							*/
685 /*									*/
686 /************************************************************************/
687 
appFillSpellTool(SpellChecker * sc,SpellTool * ast,const SpellToolResources * astr,AppInspector * ai,int subjectPage,InspectorSubject * is,APP_WIDGET pageWidget,const InspectorSubjectResources * isr)688 void appFillSpellTool(	SpellChecker *			sc,
689 			SpellTool *			ast,
690 			const SpellToolResources *	astr,
691 			AppInspector *			ai,
692 			int				subjectPage,
693 			InspectorSubject *		is,
694 			APP_WIDGET			pageWidget,
695 			const InspectorSubjectResources * isr )
696     {
697     ast->astResources= astr;
698 
699     ast->astSpellChecker= sc;
700     ast->astCurrentDictionary= -1;
701     if  ( utilMemoryBufferSetString( &(sc->scPrivateDirectory),
702 					    astr->astrPrivateDictionaries ) )
703 	{ LDEB(1);	}
704     if  ( utilMemoryBufferSetString( &(sc->scSystemDirectory),
705 					    astr->astrSystemDictionaries ) )
706 	{ LDEB(1);	}
707 
708     appInitOptionmenu( &(ast->astDictionaryOptionmenu) );
709 
710     (*sc->scSetup)( sc, appSpellToolComplain, ast );
711 
712     ast->astDictionaryFrame=
713 		    appSpellMakeDictionaryFrame( pageWidget, astr, ast );
714     ast->astGuessList= appSpellGuessList( pageWidget, astr, ast );
715 
716     appMakeTextInColumn( &(ast->astWordText), pageWidget, 0, 1 );
717 
718     appGuiSetTypingCallbackForText( ast->astWordText,
719 				    appSpellCorrectionTyped, (void *)ast );
720 
721     appSpellMakeButtonRows( pageWidget, astr, ast );
722 
723     appSpellToolSomethingFound( ast, 0 );
724     appSpellToolGotAlternative( ast, 0 );
725 
726     return;
727     }
728 
appSpellToolFillChoosers(SpellTool * ast,const SpellToolResources * astr)729 void appSpellToolFillChoosers(	SpellTool *			ast,
730 				const SpellToolResources *	astr )
731     {
732     if  ( appSpellGetLocaleNames( ast->astApplication, ast->astSpellChecker ) )
733 	{ LDEB(1);	}
734 
735     appSpellFillDictionaryMenu( ast, astr );
736 
737     return;
738     }
739 
appFinishSpellTool(SpellTool * ast,const SpellToolResources * astr)740 void appFinishSpellTool(		SpellTool *			ast,
741 					const SpellToolResources *	astr )
742     {
743     SpellChecker *		sc;
744     int				hasDict= 1;
745 
746     appOptionmenuRefreshWidth( &(ast->astDictionaryOptionmenu) );
747 
748     if  ( ! ( sc= ast->astSpellChecker ) )
749 	{ hasDict= 0;	}
750     else{
751 	if  ( ast->astCurrentDictionary < 0				||
752 	      ast->astCurrentDictionary >= sc->scDictionaryCount	)
753 	    { hasDict= 0;	}
754 	}
755 
756     guiEnableWidget( ast->astFindNextButton, hasDict );
757     appSpellToolGotAlternative( ast, 0 );
758     }
759 
760 static AppConfigurableResource APP_SpellToolResourceTable[]=
761     {
762     /************************/
763     /*  Spell Tool.		*/
764     /************************/
765     APP_RESOURCE( "spellToolDictTitle",
766 		offsetof(SpellToolResources,astrDictionary),
767 		"Dictionary" ),
768     APP_RESOURCE( "spellToolLearn",
769 		offsetof(SpellToolResources,astrLearn),
770 		"Learn" ),
771     APP_RESOURCE( "spellToolForget",
772 		offsetof(SpellToolResources,astrForget),
773 		"Forget" ),
774     APP_RESOURCE( "spellToolGuesses",
775 		offsetof(SpellToolResources,astrGuesses),
776 		"Guesses" ),
777     APP_RESOURCE( "spellToolIgnore",
778 		offsetof(SpellToolResources,astrIgnore),
779 		"Ignore" ),
780     APP_RESOURCE( "spellToolFindNext",
781 		offsetof(SpellToolResources,astrFindNext),
782 		"Find Next" ),
783     APP_RESOURCE( "spellToolGuess",
784 		offsetof(SpellToolResources,astrGuess),
785 		"Guess" ),
786     APP_RESOURCE( "spellToolCorrect",
787 		offsetof(SpellToolResources,astrCorrect),
788 		"Correct" ),
789     APP_RESOURCE( "spellToolNoDicts",
790 		offsetof(SpellToolResources,astrNoDicts),
791 		"None" ),
792 
793 #   ifdef __VMS
794     APP_RESOURCE( "spellToolPrivateDicts",
795 		offsetof(SpellToolResources,astrPrivateDictionaries),
796 		"_Dictionaries" ),
797 #   else
798     APP_RESOURCE( "spellToolPrivateDicts",
799 		offsetof(SpellToolResources,astrPrivateDictionaries),
800 		".Dictionaries" ),
801 #   endif
802     APP_RESOURCE( "spellToolSystemDicts",
803 		offsetof(SpellToolResources,astrSystemDictionaries),
804 		INDDIR ),
805 
806     APP_RESOURCE( "spellToolDirNoAccess",
807 	    offsetof(SpellToolResources,astrErrors[SCerrDIR_NO_ACCESS]),
808 	    "Could not access directory for dictionaries." ),
809     APP_RESOURCE( "spellToolDirNoSuchDir",
810 	    offsetof(SpellToolResources,astrErrors[SCerrDIR_DOES_NOT_EXIST]),
811 	    "This directory could not be found." ),
812     APP_RESOURCE( "spellToolDirNoDicts",
813 	    offsetof(SpellToolResources,astrErrors[SCerrDIR_HAS_NO_DICTS]),
814 	    "No dictionaries were found in this directory." ),
815     APP_RESOURCE( "spellToolSysDictNoAccess",
816 	    offsetof(SpellToolResources,astrErrors[SCerrDICT_NO_ACCESS]),
817 	    "Could not read system dictionary." ),
818     APP_RESOURCE( "spellToolPrivDictDirNotMade",
819 	    offsetof(SpellToolResources,astrErrors[SCerrPRIVATE_DIR_NOT_MADE]),
820 	    "Could not make private directory." ),
821     APP_RESOURCE( "spellToolPrivDictNoAccess",
822 	    offsetof(SpellToolResources,astrErrors[SCerrPRIVATE_DICT_NO_ACCESS]),
823 	    "Could not read private dictionary." ),
824     APP_RESOURCE( "spellToolPrivDictWrongFormat",
825 	    offsetof(SpellToolResources,astrErrors[SCerrPRIVATE_DICT_WRONG_FORMAT]),
826 	    "Private dictionary has an illegal format." ),
827     };
828 
829 static AppConfigurableResource APP_SpellToolSubjectResourceTable[]=
830     {
831     APP_RESOURCE( "docToolMenuSpellText",
832 		offsetof(InspectorSubjectResources,isrSubjectName),
833 		"Spelling" ),
834     };
835 
appSpellToolGetResourceTable(EditApplication * ea,SpellToolResources * astr,InspectorSubjectResources * isr)836 void appSpellToolGetResourceTable(	EditApplication *		ea,
837 					SpellToolResources *		astr,
838 					InspectorSubjectResources *	isr )
839     {
840     static int	gotToolResources= 0;
841     static int	gotSubjectResources= 0;
842 
843     if  ( ! gotToolResources )
844 	{
845 	appGuiGetResourceValues( &gotToolResources, ea, (void *)astr,
846 					APP_SpellToolResourceTable,
847 					sizeof(APP_SpellToolResourceTable)/
848 					sizeof(AppConfigurableResource) );
849 	}
850 
851     if  ( ! gotSubjectResources )
852 	{
853 	appGuiGetResourceValues( &gotSubjectResources, ea, (void *)isr,
854 				APP_SpellToolSubjectResourceTable,
855 				sizeof(APP_SpellToolSubjectResourceTable)/
856 				sizeof(AppConfigurableResource) );
857 	}
858 
859     return;
860     }
861